private XElement ParseTypedefTree(ITree tree, Block scope) { if (foundDomains.ContainsKey(tree)) { return foundDomains[tree]; } if (tree.ChildCount == 0) { return null; } ITree tt = tree.GetChild(0); XElement domain = null; if (tt.Type == BlaiseParser.TYPE_ARRAY) { ITree realDomain = tt.GetChild(tt.ChildCount - 2); // last child return ParseTypedefTree(tt, scope); // array of this type } else if (tt.Type == BlaiseParser.TYPE_CATEGORY) { XElement catScheme = Ddi.Element(Ddi.CategoryScheme); XElement codeScheme = Ddi.Element(Ddi.CodeScheme); this.categorySchemes.Add(catScheme); this.codeSchemes.Add(codeScheme); domain = Ddi.Element(Ddi.CodeDomain, false); domain.Add(Ddi.GetReference(Ddi.CodeSchemeReference, codeScheme)); // for each child category List<string> categoryNames = new List<string>(); // for making up a scheme name int codeNumber = 1; for (int i = 0; i < tt.ChildCount; ++i) { int langCount = 0; ITree cat = tt.GetChild(i); XElement category = Ddi.Element(Ddi.Category); XElement code = Ddi.Element(Ddi.LogicalCode, false); code.Add(Ddi.GetReference(Ddi.CategoryReference, category)); catScheme.Add(category); codeScheme.Add(code); string catName= string.Empty; // initialize the category if (cat.ChildCount > 0) { catName = cat.GetChild(0).Text; category.Add(new XElement(Ddi.CategoryName, Ddi.XmlLang(MainLanguage), catName)); category.Add(new XElement(Ddi.Label, Ddi.XmlLang(MainLanguage), catName)); } for (int c = 1; c < cat.ChildCount; ++c) { ITree test = cat.GetChild(c); // set the current code if present if (test.Type == BlaiseParser.TYPE_CATEGORY_CODE) { if (test.ChildCount == 1) { try { codeNumber = Int32.Parse(test.GetChild(0).Text); } catch (Exception) { //TODO } } } //labels for each language else if (test.Type == BlaiseParser.LID_STRING) { LanguageString ls = new LanguageString(test); if (string.IsNullOrEmpty(ls.Language) && langCount < options.DefinedLanguagesOrder.Count) { ls.Language = options.DefinedLanguagesOrder[langCount]; langCount++; } BlaiseLanguageMapping mapping = options.GetMapping(ls.Language); if (mapping != null) { category.Add(new XElement(Ddi.Label, Ddi.XmlLang(mapping.Culture), ls.Value)); } else { category.Add(new XElement(Ddi.Label, Ddi.XmlLang(MainLanguage), ls.Value)); } } } code.Add(new XElement(Ddi.Value, codeNumber.ToString())); codeNumber++; /* if (cat.ChildCount == 1) { code.Value = cat.GetChild(0).Text; category.ItemName.Current = cat.GetChild(0).Text; category.Label.Current = cat.GetChild(0).Text; } else if (cat.ChildCount >= 2) { // TODO for now ignore the (code) coding code.Value = cat.GetChild(0).Text; for (int j = 1; j < cat.ChildCount; ++j) { if (cat.GetChild(j).Text.StartsWith("\"")) { category.Label.Current = cat.GetChild(j).Text.Trim(new char[] { '"' }); break; } } } */ if (categoryNames.Count < 3) { categoryNames.Add(catName); } } string madeUpName = string.Join(string.Empty, categoryNames.ToArray()); catScheme.AddFirst(new XElement(Ddi.CategorySchemeName, madeUpName + "Categories")); codeScheme.AddFirst(new XElement(Ddi.CodeSchemeName, madeUpName + " Codes")); } else if (tt.Type == BlaiseParser.TYPE_INTEGER) { domain = Ddi.Element(Ddi.NumericDomain, false); domain.Add(new XAttribute("type", "Integer")); } else if (tt.Type == BlaiseParser.TYPE_OPEN) { domain = Ddi.Element(Ddi.TextDomain, false); } else if (tt.Type == BlaiseParser.TYPE_REAL) { domain = Ddi.Element(Ddi.NumericDomain, false); domain.Add(new XAttribute("type", "Float")); } else if (tt.Type == BlaiseParser.TYPE_SETOF) { string temp = tree.ToStringTree(); } else if (tt.Type == BlaiseParser.TYPE_STRING) { domain = Ddi.Element(Ddi.TextDomain, false); } else if (tt.Type == BlaiseParser.TYPE_TIMETYPE) { domain = Ddi.Element(Ddi.DateTimeDomain, false); } else if (tt.Type == BlaiseParser.REALRANGE) { domain = Ddi.Element(Ddi.NumericDomain, false); domain.Add(new XAttribute("type", "Real")); var child0 = tt.GetChild(0); string low = null; if (child0 != null) { if (child0.GetChild(0) != null) { low = child0.GetChild(0).Text; } if (child0.GetChild(1) != null) { low += "." + child0.GetChild(1).Text; } } var child1 = tt.GetChild(1); string high = null; if (child1 != null) { if (child1.GetChild(0) != null) { high = child1.GetChild(0).Text; } if (child1.GetChild(1) != null) { high += "." + child1.GetChild(1).Text; } } try { bool hasRange = false; XElement range = Ddi.Element(Ddi.NumberRange, false); if (!string.IsNullOrEmpty(low)) { range.Add(new XElement(Ddi.Low, low)); hasRange = true; } if (!string.IsNullOrEmpty(high)) { range.Add(new XElement(Ddi.High, high)); hasRange = true; } if (hasRange) { domain.Add(range); } if (child0 != null) { domain.Add(new XAttribute("decimalPositions", child0.GetChild(1).Text.Length)); } } catch (Exception) { // TODO warn invalid blaise file } } else if (tt.Type == BlaiseParser.INTRANGE) { domain = Ddi.Element(Ddi.NumericDomain, false); domain.Add(new XAttribute("type", "Integer")); //TODO parse reals as reals string low = tt.GetChild(0).Text; string high = tt.GetChild(1).Text; try { XElement range = Ddi.Element(Ddi.NumberRange, false); range.Add(new XElement(Ddi.Low, low)); range.Add(new XElement(Ddi.High, high)); domain.Add(range); domain.Add(new XAttribute("decimalPositions", 0)); } catch (Exception) { // TODO warn invalid blaise file } } else if (tt.Type == BlaiseParser.TYPE_USERDEF) { // find the type and ask again if (tt.ChildCount != 0) { string usertype = tt.GetChild(0).Text; if (scope.HasBlaiseType(usertype)) { ITree usertree = scope.GetBlaiseType(usertype); return ParseTypedefTree(usertree, scope); } } } if (domain == null) { domain = Ddi.Element(Ddi.TextDomain, false); } foundDomains.Add(tree, domain); return domain; }
private Block WalkSubModel(ITree datamodel, Block scope) { if (datamodel.ChildCount < 1) { return null; // TODO maybe warn } Block block = new Block(); block.Label = datamodel.GetChild(0); blocks[block.Title] = block; if (scope != null) // not the top datamodel { block.Parent = scope; scope.AddBlock(block.Title, block); } ITree submodel = datamodel; // TODO // extract all type information for this submodel for (int i = 0; i < submodel.ChildCount; ++i) { ITree subtype = submodel.GetChild(i); if (subtype.Type == BlaiseParser.SUB_TYPE) { // add all types to this block for (int j = 0; j < subtype.ChildCount; ++j) { ITree typeItem = subtype.GetChild(j); if (typeItem.Type == BlaiseParser.TYPE_ITEM) { if (typeItem.ChildCount == 2 && typeItem.GetChild(1).Type == BlaiseParser.TYPEDEF) { string typeName = typeItem.GetChild(0).Text; block.AddType(typeName, typeItem.GetChild(1)); } } } } } // extract all field information for this submodel for (int i = 0; i < submodel.ChildCount; ++i) { ITree fields = submodel.GetChild(i); if (fields.Type == BlaiseParser.FIELDS || fields.Type == BlaiseParser.AUXFIELDS || fields.Type == BlaiseParser.SUB_LOCALS) { // add all fields to this block for (int j = 0; j < fields.ChildCount; ++j) { ITree field = fields.GetChild(j); if (field.Type == BlaiseParser.FIELD) // not necessary unless parser changes { if (field.ChildCount < 2) { continue; } ITree idList = field.GetChild(0); List<Field> toadd = new List<Field>(idList.ChildCount); for (int k = 0; k < idList.ChildCount; ++k) { Field f = new Field(); f.Title = idList.GetChild(k).Text; toadd.Add(f); } ITree typedef = null; Collection<LanguageString> fieldTexts = new Collection<LanguageString>(); Collection<LanguageString> fieldDescriptions = new Collection<LanguageString>(); string tag = null; // Do these seperate so we can keep the language ordering int langCount = 0; for (int k = 0; k < field.ChildCount; ++k) { ITree fi = field.GetChild(k); if (fi.Type == BlaiseParser.FIELD_TEXT) { ITree lidString = fi.GetChild(0); LanguageString ls = new LanguageString(lidString); if (string.IsNullOrEmpty(ls.Language) && langCount < options.DefinedLanguagesOrder.Count) { ls.Language = options.DefinedLanguagesOrder[langCount]; langCount++; } fieldTexts.Add(ls); } } langCount = 0; for (int k = 0; k < field.ChildCount; ++k) { ITree fi = field.GetChild(k); if (fi.Type == BlaiseParser.FIELD_DESC) { ITree lidString = fi.GetChild(0); LanguageString ls = new LanguageString(lidString); if (string.IsNullOrEmpty(ls.Language) && langCount < options.DefinedLanguagesOrder.Count) { ls.Language = options.DefinedLanguagesOrder[langCount]; langCount++; } fieldDescriptions.Add(ls); } // tack this on here, there is only one of them if (fi.Type == BlaiseParser.TYPEDEF) { typedef = fi; } else if (fi.Type == BlaiseParser.FIELD_TAG) { if (fi.ChildCount == 1) { ITree tagList = fi.GetChild(0); for (int ti = 0; ti < tagList.ChildCount; ti++) { if (ti == 0) { tag = tagList.GetChild(ti).Text; } else { tag += "," + tagList.GetChild(ti).Text; } } } } } foreach (Field f in toadd) { f.Question = fieldTexts; f.Description = fieldDescriptions; f.Typedef = typedef; f.Parent = block; f.Tag = tag; block.AddField(f.Title, f); } } } } } // extract all child block information for this submodel for (int i = 0; i < submodel.ChildCount; ++i) { ITree child = submodel.GetChild(i); if (child.Type == BlaiseParser.BLOCK || child.Type == BlaiseParser.TABLE || child.Type == BlaiseParser.PROCEDURE) { WalkSubModel(child, block); } } // extract rules for this submodel for (int i = 0; i < submodel.ChildCount; ++i) { ITree child = submodel.GetChild(i); if (child.Type == BlaiseParser.RULES) { block.Rules = child; } } return block; }
private void AssignQuestionStrings(XElement question, LanguageString blaiseString, Block scope) { BlaiseLanguageMapping mapping = options.GetMapping(blaiseString.Language); string encodedText = GetQuestionText(blaiseString.Value, scope); if (mapping != null) { if (mapping.MetadataElement == MetadataFieldType.Default) { question.Add(new XElement(Ddi.QuestionText, Ddi.XmlLang(mapping.Culture), new XElement(Ddi.LiteralText, new XElement(Ddi.Text, encodedText)))); } else if (mapping.MetadataElement == MetadataFieldType.Description) { question.Add(new XElement(Ddi.Description, Ddi.XmlLang(mapping.Culture), encodedText)); } else if (mapping.MetadataElement == MetadataFieldType.QuestionText) { question.Add(new XElement(Ddi.QuestionText, Ddi.XmlLang(mapping.Culture), new XElement(Ddi.LiteralText, new XElement(Ddi.Text, encodedText)))); } else if (mapping.MetadataElement == MetadataFieldType.Intent) { question.Add(new XElement(Ddi.QuestionIntent, Ddi.XmlLang(mapping.Culture), encodedText)); } else if (mapping.MetadataElement == MetadataFieldType.Label) { question.Add(new XElement(Ddi.Label, Ddi.XmlLang(mapping.Culture), encodedText)); } else if (mapping.MetadataElement == MetadataFieldType.Instructions) { // TODO } } else { question.Add(new XElement(Ddi.QuestionText, Ddi.XmlLang(MainLanguage), new XElement(Ddi.LiteralText, new XElement(Ddi.Text, encodedText)))); } }