public static void Iterate(this HmdBlockID blockID, HmdProperties hmdProperties, AtValueIDWithProperties atValueIDWithProperties, AtBlockIDWithProperties atBlockIDWithProperties) { for (int i = 0; i < blockID.ChildCount; i++) { HmdID childID = blockID.GetChild(i); if (childID.isBlock) { HmdBlockID childBlockID = childID.CastAsBlockID; HmdBlockIDProperties childBlockIDProperties = hmdProperties.GetProperties(childBlockID); if (childBlockIDProperties == null) { throw new InvalidOperationException(String.Format("Found a block id \"{0}\", but it was not defined in the property dictionary", childID.idOriginalCase)); } atBlockIDWithProperties(childBlockID, childBlockIDProperties, hmdProperties); } else { HmdValueID childValueID = childID.CastAsValueID; HmdValueIDProperties childValueIDProperties = hmdProperties.GetProperties(childValueID); if (childValueIDProperties == null) { throw new InvalidOperationException(String.Format("Found a value id \"{0}\", but it was not defined in the property dictionary", childID.idOriginalCase)); } atValueIDWithProperties(childValueID, childValueIDProperties, hmdProperties); } } }
private void ValidateValueID(HmdValueID valueID, HmdValueIDProperties valueIDProperties, HmdProperties hmdProperties) { // // Check that the current parent is valid // debugOutput.Write(blockStack.Count, "Checking that \"{0}\" has \"{1}\" as a valid parent...", valueID.idOriginalCase, currentBlock.blockIDProperties.idOriginalCase); if (!valueIDProperties.IsValidParent(currentBlock.blockIDProperties)) { throw new FormatException(String.Format("Value ID \"{0}\" appeared in Block \"{1}\", but this is not allowed with the current properties", valueID.idOriginalCase, currentBlock.blockIDProperties.idOriginalCase)); } debugOutput.WriteLine("Pass."); if (valueID.value != null) { debugOutput.Write(blockStack.Count, "Checking the Value Type for \"{0}\"...", valueID.idOriginalCase); if (!valueIDProperties.IsValidValue(valueID.value, hmdProperties)) { throw new FormatException(String.Format("Value ID \"{0}\" of type {1}, had an invalid value of \"{2}\"", valueID.idOriginalCase, valueIDProperties.hmdType.ToHmdTypeString(), valueID.value)); } debugOutput.WriteLine("Pass."); } // Add ID to current block validator currentBlock.NewChild(valueIDProperties); }
private static void VerifyValueProperties(String idString, HmdValueIDProperties valueIDProperties, ICountProperty expectedCountProperty, HmdType hmdType, String enumReferenceName, params String[] parentOverrideArray) { // Verify idString Assert.AreEqual(idString, valueIDProperties.idLowerCase); // Verify CountProperty is correct Assert.IsTrue(expectedCountProperty.Equals(valueIDProperties.CountProperty)); // Verify Parents are correct if (parentOverrideArray != null) { Assert.AreEqual(parentOverrideArray.Length, valueIDProperties.ParentOverrideCount); for (int i = 0; i < parentOverrideArray.Length; i++) { Assert.IsTrue(valueIDProperties.IsInParentOverrideList(parentOverrideArray[i])); } } // Verify HmdType is correct Assert.AreEqual(hmdType, valueIDProperties.hmdType); if (enumReferenceName == null) { Assert.IsNull(valueIDProperties.EnumReference); } else { Assert.AreEqual(enumReferenceName, valueIDProperties.EnumReference.Name); } }
public static void TestPropertyParserInlineEnum(String propertyString, params String[] values) { HmdValueIDProperties valueIDProperties = CallParserWithDefaults(propertyString, TestPropertyDictionary); VerifyValueProperties(String.Empty, valueIDProperties, UnrestrictedCount.Instance, HmdType.Enumeration, ""); // // Verify enum values // HmdEnumReference hmdEnumReference = valueIDProperties.EnumReference; HmdEnum hmdEnum = hmdEnumReference.TryGetReference; Assert.IsNotNull(hmdEnum); for (int i = 0; i < values.Length; i++) { Assert.IsTrue(hmdEnum.IsValidEnumValue(values[i])); } }
private static void ParsePropertiesFile(HmdBlockIDProperties propertyBlockRoot, HmdProperties hmdProperties, HmdTokenizer tokenizer, String importPath, Boolean isPImportFile) { TextWriter debugOutput = HmdDebug.DebugOutput; if (debugOutput == null) { debugOutput = TextWriter.Null; } if (propertyBlockRoot == null) { throw new ArgumentNullException("propertyBlockRoot"); } // // TODO: What about pimport files? Should they require a %props block? If not, then can they put it anyways? I'll need to add another argument to this argument list // that will say whether or not it is a PImport so it can gracefully end on EOF instead of '}' (close brace) // // // TODO: MAKE SURE YOU DISALLOW SPECIFYING %PROPS VALUE ID in a BLOCK TWICE!!! // // HmdBlockIDProperties currentParent = propertyBlockRoot; Stack <HmdBlockIDProperties> parentStack = new Stack <HmdBlockIDProperties>(); while (true) { HmdGlobalToken token = tokenizer.NextGlobalToken(); // // Check for EOF // if (token.type == HmdGlobalTokenType.EOF) { if (isPImportFile && parentStack.Count <= 0) { return; } else { throw new FormatException("Reached EOF inside a %props block directive"); } } if (token.type == HmdGlobalTokenType.ID) { String idString = token.text; Boolean isBlockID; Boolean isEmptyID = tokenizer.NextIDType(out isBlockID); if (isEmptyID) { // this just means the value ID has all the defaults debugOutput.WriteLine("EmptyProp ID: {0}", idString); HmdValueIDProperties valueIDProperties = new HmdValueIDProperties(idString, hmdProperties.defaultCountProperty, hmdProperties.defaultHmdType, null, currentParent, null); if (!valueIDProperties.DirectParentIsOverriden) { currentParent.AddDirectChildWithNoParentOverrideList(valueIDProperties); } hmdProperties.AddPropertiesFromDefinition(valueIDProperties); } else if (!isBlockID) { debugOutput.WriteLine("ValProp ID: {0}", idString); String nextValue = tokenizer.NextValue(); debugOutput.WriteLine("ValProp : {0}", nextValue); HmdValueIDProperties valueIDProperties = HmdParser.ParseValueProperties(idString, nextValue, currentParent, hmdProperties); if (!valueIDProperties.DirectParentIsOverriden) { currentParent.AddDirectChildWithNoParentOverrideList(valueIDProperties); } hmdProperties.AddPropertiesFromDefinition(valueIDProperties); } else { debugOutput.WriteLine("BlkProp ID: {0}", idString); HmdBlockIDProperties blockIDProperties = new HmdBlockIDProperties(idString, hmdProperties.defaultCountProperty, currentParent); // wait to add this child to the current parent so we know whether or not it's default parent is overriden hmdProperties.AddPropertiesFromDefinition(blockIDProperties); parentStack.Push(currentParent); currentParent = blockIDProperties; } } else if (token.type == HmdGlobalTokenType.Directive) { String directiveID = token.text; Boolean isBlockID; Boolean isEmptyID = tokenizer.NextIDType(out isBlockID); if (isEmptyID) { throw new NotImplementedException(); } else if (!isBlockID) { // // TODO: Props Blocks should not allow %import directives, they should only allow %pimport directives // if (token.text.Equals("import", StringComparison.CurrentCulture)) { throw new FormatException("%import directive not allowed inside a %prop block"); } else if (token.text.Equals("pimport", StringComparison.CurrentCulture)) { String nextValue = tokenizer.NextValue(); debugOutput.WriteLine("%PImport : {0}", nextValue); String importFileAndPathName = Path.Combine(importPath, nextValue); using (FileStream importStream = new FileStream(importFileAndPathName, FileMode.Open)) { debugOutput.WriteLine("File Start: {0}", importFileAndPathName); ParsePropertiesFile(currentParent, hmdProperties, new HmdTokenizer(new StreamReader(importStream), 1), importPath, false); debugOutput.WriteLine("File End : {0}", importFileAndPathName); } } else if (token.text.Equals("enum", StringComparison.CurrentCulture)) { String nextValue = tokenizer.NextValue(); debugOutput.WriteLine("%Enum : {0}", nextValue); hmdProperties.AddEnum(new HmdEnum(nextValue)); } else if (token.text.Equals("props", StringComparison.CurrentCulture)) { if (parentStack.Count <= 0) { throw new FormatException("You can't specify a %props value on the root"); } String nextValue = tokenizer.NextValue(); debugOutput.WriteLine("%Props : {0}", nextValue); HmdParser.ParseAndOverrideBlockProperties(currentParent, nextValue); } else { throw new Exception(String.Format("Parser (line {0}): Unrecognized value directive \"{1}\"", token.line, token.text)); } } else { if (token.text.Equals("props", StringComparison.CurrentCulture)) { throw new FormatException("Right now this is just weird, why do you have a %props block inside a props block (Maybe I'll let this slide later)?"); debugOutput.WriteLine("Block ID : %props Directive"); if (hmdProperties == null) { debugOutput.WriteLine("Not Parsing %props Directive Block ID..."); throw new NotImplementedException("Haven't implemented the feature to parse without doing the props block"); } else { ParsePropertiesFile(hmdProperties.root, hmdProperties, tokenizer, importPath, false); } } else if (token.text.Equals("group", StringComparison.CurrentCulture)) { throw new NotImplementedException(); } else { throw new Exception(String.Format("Parser (line {0}): Unrecognized block directive \"{1}\"", token.line, token.text)); } } } else if (token.type == HmdGlobalTokenType.CloseBrace) { if (parentStack.Count <= 0) { debugOutput.WriteLine("%Props End:"); return; } debugOutput.WriteLine("Block End : {0}", currentParent.idOriginalCase); HmdBlockIDProperties temp = currentParent; currentParent = parentStack.Pop(); if (!temp.DirectParentIsOverriden) { currentParent.AddDirectChildWithNoParentOverrideList(temp); } } else { throw new FormatException(String.Format("Parser (line {0}): Unexpected token {1}", token.line, token)); } } }
public static void TestPropertyParser(String propertyString, params String[] expectedParents) { HmdValueIDProperties valueIDProperties = CallParserWithDefaults(propertyString, TestPropertyDictionary); VerifyValueProperties(String.Empty, valueIDProperties, UnrestrictedCount.Instance, HmdType.String, null, expectedParents); }
public static void TestPropertyParserEnumReference(String propertyString, String enumReferenceTypeString) { HmdValueIDProperties valueIDProperties = CallParserWithDefaults(propertyString, TestPropertyDictionary); VerifyValueProperties(String.Empty, valueIDProperties, UnrestrictedCount.Instance, HmdType.Enumeration, enumReferenceTypeString); }
public static void TestPropertyParser(String propertyString, HmdType hmdType) { HmdValueIDProperties valueIDProperties = CallParserWithDefaults(propertyString, TestPropertyDictionary); VerifyValueProperties(String.Empty, valueIDProperties, UnrestrictedCount.Instance, hmdType, null); }
public static void TestPropertyParser(String propertyString, ICountProperty expectedCountProperty) { HmdValueIDProperties valueIDProperties = CallParserWithDefaults(propertyString, TestPropertyDictionary); VerifyValueProperties(String.Empty, valueIDProperties, expectedCountProperty, HmdType.String, null); }
public void GenerateParserClasses(TextWriter output, HmdBlockIDProperties block, HmdProperties hmdProperties, String hmdTypePrefix, Boolean isRoot) { String className = isRoot ? rootClassName : (hmdTypePrefix + typeNameTable.GetTypeName(block)); // // Generate the class for the current block // int tabs = 1; output.WriteLine(tabs, "public class {0}", className); output.WriteLine(tabs++, "{"); // // Print Fields // foreach (HmdIDProperties childIDProperties in block) { if (childIDProperties.isBlock) { HmdBlockIDProperties childBlockProperties = childIDProperties.CastAsBlockIDProperties; String type = hmdTypePrefix + typeNameTable.GetTypeName(childBlockProperties); if (childBlockProperties.CountProperty.Multiple) { type = languageGenerator.ListType(type); } output.WriteLine(tabs, "public {0} {1};", type, childBlockProperties.idOriginalCase); } else { HmdValueIDProperties childValueProperties = childIDProperties.CastAsValueIDProperties; if (childValueProperties.hmdType != HmdType.Empty) { String type; if (childValueProperties.hmdType == HmdType.Enumeration) { HmdEnum hmdEnum = childValueProperties.EnumReference.TryGetReference; if (hmdEnum == null) { hmdEnum = hmdProperties.TryGetEnum(childValueProperties.EnumReference.Name); if (hmdEnum == null) { throw new FormatException(String.Format("Can't resolve enum reference '{0}'", childValueProperties.EnumReference.Name)); } childValueProperties.ResolveEnumReference(hmdEnum); } type = typeNameTable.GetTypeName(hmdEnum); } else { type = languageGenerator.HmdTypeToLanguageType(childValueProperties.hmdType); } if (childValueProperties.CountProperty.Multiple) { type = languageGenerator.ListType(type); } output.WriteLine(tabs, "public {0} {1};", type, childValueProperties.idOriginalCase); } } } // // Print Constructor // output.WriteLine(tabs, "public {0}(HmdBlockID blockID, HmdProperties hmdProperties)", className); output.WriteLine(tabs++, "{"); output.WriteLine(tabs, "for(int i = 0; i < blockID.ChildCount; i++)"); output.WriteLine(tabs++, "{"); output.WriteLine(tabs, "HmdID childID = blockID.GetChild(i);"); output.WriteLine(tabs, "if(childID.isBlock)"); output.WriteLine(tabs++, "{"); output.WriteLine(tabs, "HmdBlockID childBlockID = (HmdBlockID)childID;"); Int32 blockChildCount = 0; foreach (HmdIDProperties childIDProperties in block) { if (childIDProperties.isBlock) { HmdBlockIDProperties childBlockProperties = childIDProperties.CastAsBlockIDProperties; blockChildCount++; output.WriteLine(tabs, "// parse field {0}", childIDProperties.idOriginalCase); output.WriteLine(tabs, "{0}if(childBlockID.idLowerCase.Equals(\"{1}\",StringComparison.CurrentCultureIgnoreCase))", blockChildCount > 1 ? "else " : String.Empty, childIDProperties.idLowerCase); output.WriteLine(tabs++, "{"); if (childIDProperties.CountProperty.Multiple) { output.WriteLine(tabs, "// set List to not null"); output.WriteLine(tabs, "this.{0}.Add(new {1}{2}(childBlockID, hmdProperties));", childIDProperties.idOriginalCase, hmdTypePrefix, typeNameTable.GetTypeName(childBlockProperties)); } else { output.WriteLine(tabs, "// check that field is not set already"); output.WriteLine(tabs, "if(this.{0} != null)", childIDProperties.idOriginalCase); output.WriteLine(tabs++, "{"); output.WriteLine(tabs, "throw new FormatException(\"Found multiple block id's \\\"{0}\\\"\");", childIDProperties.idOriginalCase); output.WriteLine(--tabs, "}"); output.WriteLine(tabs, "this.{0} = new {1}{2}(childBlockID, hmdProperties);", childIDProperties.idOriginalCase, hmdTypePrefix, typeNameTable.GetTypeName(childBlockProperties)); } output.WriteLine(--tabs, "}"); } } if (blockChildCount > 0) { output.WriteLine(tabs, "else"); output.WriteLine(tabs++, "{"); } output.WriteLine(tabs, "throw new FormatException(String.Format(\"Unrecognized child block id \\\"{0}\\\"\",childID.idOriginalCase));"); if (blockChildCount > 0) { output.WriteLine(--tabs, "}"); } output.WriteLine(--tabs, "}"); output.WriteLine(tabs, "else"); output.WriteLine(tabs++, "{"); output.WriteLine(tabs, "HmdValueID childValueID = (HmdValueID)childID;"); Int32 valueChildCount = 0; foreach (HmdIDProperties childIDProperties in block) { if (!childIDProperties.isBlock) { HmdValueIDProperties childValueIDProperties = childIDProperties.CastAsValueIDProperties; valueChildCount++; output.WriteLine(tabs, "// parse field {0}", childIDProperties.idOriginalCase); output.WriteLine(tabs, "{0}if(childValueID.idLowerCase.Equals(\"{1}\",StringComparison.CurrentCultureIgnoreCase))", valueChildCount > 1 ? "else " : String.Empty, childIDProperties.idLowerCase); output.WriteLine(tabs++, "{"); String variableName = "childValueID.value"; String parseCode = null; if (childValueIDProperties.hmdType == HmdType.Enumeration) { parseCode = languageGenerator.GenerateStringToEnumParseCode( typeNameTable.GetTypeName(childValueIDProperties.EnumReference.TryGetReference), variableName); } else { parseCode = languageGenerator.GenerateStringToTypeParseCode( childValueIDProperties.hmdType, variableName); } if (childIDProperties.CountProperty.Multiple) { output.WriteLine(tabs, "this.{0}.Add({1});", childIDProperties.idOriginalCase, parseCode); } else { output.WriteLine(tabs, "// check that field is not set already"); output.WriteLine(tabs, "if(this.{0} != null)", childIDProperties.idOriginalCase); output.WriteLine(tabs++, "{"); output.WriteLine(tabs, "throw new FormatException(\"Found multiple value id's \\\"{0}\\\"\");", childIDProperties.idOriginalCase); output.WriteLine(--tabs, "}"); output.WriteLine(tabs, "this.{0} = {1};", childIDProperties.idOriginalCase, parseCode); } output.WriteLine(--tabs, "}"); } } if (valueChildCount > 0) { output.WriteLine(tabs, "else"); output.WriteLine(tabs++, "{"); } output.WriteLine(tabs, "throw new FormatException(String.Format(\"Unrecognized child value id \\\"{0}\\\"\",childID.idOriginalCase));"); if (valueChildCount > 0) { output.WriteLine(--tabs, "}"); } output.WriteLine(--tabs, "}"); output.WriteLine(--tabs, "}"); output.WriteLine(--tabs, "}"); output.WriteLine(--tabs, "}"); }
public void AddPropertiesFromDefinition(HmdValueIDProperties valueIDProperties) { valueIDTable.AddPropertiesFromDefinition(valueIDProperties); }