static int Main(string[] args) { if (args.Length <= 0) { Console.WriteLine("Please supply an hmd properties file"); return(-1); } if (args.Length > 1) { Console.WriteLine("Too many arguments...please only supply an hmd properties file"); return(-1); } String hmdPropertiesFile = args[0]; HmdProperties hmdProperties = HmdFileParser.ParsePropertiesFile( hmdPropertiesFile, Path.GetDirectoryName(hmdPropertiesFile)); hmdProperties.ResolveChildParentReferences(); CodeGenerator codeGenerator = new CodeGenerator(CSharpLanguageGenerator.Instance, Console.Out, "DefaultHmdNamespace", "DefaultRootClassName", "HmdType"); codeGenerator.Generate(hmdProperties); return(0); }
public static void Parse(HmdBlockID root, Stream stream, String importPath, HmdProperties hmdProperties) { using (StreamReader fileStream = new StreamReader(stream)) { Parse(root, fileStream, importPath, hmdProperties); } }
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); } } }
public void Validate(HmdBlockID root, HmdProperties hmdProperties) { debugOutput = HmdDebug.DebugOutput; if (root == null) { throw new ArgumentNullException("root"); } if (hmdProperties == null) { throw new ArgumentNullException("hmdProperties"); } hmdProperties.ResolveChildParentReferences(); debugOutput.WriteLine("[Validating HMD file...]"); hmdProperties.PrintEnums(debugOutput); currentBlock = null; blockStack = new Stack <HmdBlockValidator>(); ValidateBlockID(root, hmdProperties.root, hmdProperties); debugOutput.WriteLine("[Done validating HMD file]"); }
public void ResolveAdditionalChildrenLinks(HmdProperties hmdProperties) { TextWriter debugOutput = HmdDebug.DebugOutput; if (debugOutput == null) { debugOutput = TextWriter.Null; } if (additionalChildrenList != null) { for (int i = 0; i < additionalChildrenList.Length; i++) { HmdIDProperties childProperties = additionalChildrenList[i].TryToGetReference(); if (childProperties == null) { childProperties = hmdProperties.TryToGetChildInScope(this, additionalChildrenList[i]); if (childProperties == null) { throw new InvalidOperationException(String.Format("Parent \"{0}\" is not defined in the property dictionary", additionalChildrenList[i].IDOriginalCase)); } debugOutput.WriteLine("For ID \"{0}\", resolved Parent->Child reference to \"{1}\"", idOriginalCase, childProperties.idOriginalCase); additionalChildrenList[i] = childProperties; // cache the reference } childProperties.AddAdditionalParentFromItsAdditionalChildrenList(this); } } }
public static HmdProperties ParsePropertiesFile(TextReader reader, String importPath) { HmdProperties hmdProperties = new HmdProperties(); ParsePropertiesFile(hmdProperties.root, hmdProperties, new HmdTokenizer(reader, 0), importPath, true); return(hmdProperties); }
public HmdTypeverifydevicesarenotpresent(HmdBlockID blockID, HmdProperties hmdProperties) { for (int i = 0; i < blockID.ChildCount; i++) { HmdID childID = blockID.GetChild(i); if (childID.isBlock) { HmdBlockID childBlockID = (HmdBlockID)childID; // parse field UsbDevice if (childBlockID.idLowerCase.Equals("usbdevice", StringComparison.CurrentCultureIgnoreCase)) { // set List to not null this.UsbDevice.Add(new HmdTypeusbdevice(childBlockID, hmdProperties)); } else { throw new FormatException(String.Format("Unrecognized child block id \"{0}\"", childID.idOriginalCase)); } } else { HmdValueID childValueID = (HmdValueID)childID; throw new FormatException(String.Format("Unrecognized child value id \"{0}\"", childID.idOriginalCase)); } } }
public static void TestPropertyParserFormatException(String propertyString, HmdProperties hmdProperties) { try { CallParserWithDefaults(propertyString, hmdProperties); Assert.Fail(String.Format("Expected parsing \"{0}\" to cause a FormatException, but it didn't", propertyString)); } catch (FormatException formatException) { } }
public DefaultRootClassName(HmdBlockID blockID, HmdProperties hmdProperties) { for (int i = 0; i < blockID.ChildCount; i++) { HmdID childID = blockID.GetChild(i); if (childID.isBlock) { HmdBlockID childBlockID = (HmdBlockID)childID; // parse field VerifyDevicesArePresent if (childBlockID.idLowerCase.Equals("verifydevicesarepresent", StringComparison.CurrentCultureIgnoreCase)) { // set List to not null this.VerifyDevicesArePresent.Add(new HmdTypeverifydevicesarepresent(childBlockID, hmdProperties)); } // parse field VerifyDevicesAreNotPresent else if (childBlockID.idLowerCase.Equals("verifydevicesarenotpresent", StringComparison.CurrentCultureIgnoreCase)) { // set List to not null this.VerifyDevicesAreNotPresent.Add(new HmdTypeverifydevicesarenotpresent(childBlockID, hmdProperties)); } else { throw new FormatException(String.Format("Unrecognized child block id \"{0}\"", childID.idOriginalCase)); } } else { HmdValueID childValueID = (HmdValueID)childID; // parse field Message if (childValueID.idLowerCase.Equals("message", StringComparison.CurrentCultureIgnoreCase)) { this.Message.Add(childValueID.value); } // parse field UsbSwitch else if (childValueID.idLowerCase.Equals("usbswitch", StringComparison.CurrentCultureIgnoreCase)) { this.UsbSwitch.Add((usbswitch)Enum.Parse(typeof(usbswitch), childValueID.value, true)); } // parse field Sleep else if (childValueID.idLowerCase.Equals("sleep", StringComparison.CurrentCultureIgnoreCase)) { this.Sleep.Add(UInt32.Parse(childValueID.value)); } else { throw new FormatException(String.Format("Unrecognized child value id \"{0}\"", childID.idOriginalCase)); } } } }
void ILanguageGenerator.PrintFileHeader(TextWriter output, HmdProperties hmdProperties) { output.WriteLine("/*"); output.WriteLine(" * This file was autogenerated by HmdClassGen.exe"); output.WriteLine(" *"); output.WriteLine(" * PropertyDictionary:"); hmdProperties.Print(output); output.WriteLine(" *"); output.WriteLine(" */"); output.WriteLine("using System;"); output.WriteLine("using System.Collections.Generic;"); output.WriteLine("using HumanModifiableData;"); }
public void TestConcreteExample() { // // Parse Properties File // TextReader propertiesReader = new System.IO.StringReader("%enum:ExecuteEnum Local Remote Ignore Unsupported;Script{%props:1;Source:enum(File Remote);File:0-1;ListenPort:0-1 int4;}RebootCommand {%props:1;Execute:1 enum(Ignore Unsupported Emulator);RemoteHost:0-1;RemotePort:0-1 int4;}UsbSwitchCommand { %props:1; Execute:1 enum ExecuteEnum; Platform:0-1 enum(Windows Linux); RemoteHost:0-1; RemotePort:0-1 int4;}TestCommands { %props:1; Execute:1 enum ExecuteEnum; RemoteHost:0-1; RemotePort:0-1 int4;}"); HmdProperties properties = HmdFileParser.ParsePropertiesFile(propertiesReader, null); properties.ResolveChildParentReferences(); properties.Print(Console.Out); HmdEnum hmdEnum; hmdEnum = properties.TryGetEnum("ExecuteEnum"); Assert.IsNotNull(hmdEnum); Assert.IsTrue(hmdEnum.IsValidEnumValue("local")); Assert.IsTrue(hmdEnum.IsValidEnumValue("remote")); Assert.IsTrue(hmdEnum.IsValidEnumValue("IGNORE")); Assert.IsTrue(hmdEnum.IsValidEnumValue("unsupported")); hmdEnum = properties.TryGetEnum("script.source"); Assert.IsNotNull(hmdEnum); Assert.IsTrue(hmdEnum.IsValidEnumValue("FILE")); Assert.IsTrue(hmdEnum.IsValidEnumValue("remote")); HmdBlockID fileRoot = new HmdBlockID("THE_ROOT!", null); HmdBlockID script = new HmdBlockID("script", fileRoot); Assert.IsNotNull(properties.GetProperties(script)); HmdValueID scriptSource = new HmdValueID("source", "file", script); Assert.IsNotNull(properties.GetProperties(scriptSource)); // // Parse Hmd File // TextReader hmdReader = new System.IO.StringReader("Script {Source:Remote;}RebootCommand {Execute:Unsupported;}UsbSwitchCommand {Execute:Unsupported;}TestCommands {Execute:Local;}"); HmdBlockID rootID = new HmdBlockID(String.Empty, null); HmdFileParser.Parse(rootID, hmdReader, "", null); //HmdValidator.ValidateStatic(rootID, properties); }
public static HmdEnum ResolveEnumReference(String enumName, HmdProperties hmdProperties) { List <HmdEnum> enumList = hmdProperties.EnumList; if (enumList != null) { for (int i = 0; i < enumList.Count; i++) { if (enumList[i].name.Equals(enumName, StringComparison.CurrentCultureIgnoreCase)) { return(enumList[i]); } } } throw new InvalidOperationException(String.Format("The enum \"{0}\", has not been defined", enumName)); }
public void ValidateChildren(HmdProperties hmdProperties) { // // Validate Children Counts (make sure there's not too many) // if (childrenCountList != null) { for (int i = 0; i < childrenCountList.Count; i++) { childrenCountList[i].Validate(); } } // // Make sure there are none missing // foreach (HmdIDProperties childIDProperties in blockIDProperties) { if (childIDProperties.CountProperty.MinCount > 0) { Boolean childAppears = false; for (int i = 0; i < childrenCountList.Count; i++) { if (childIDProperties.idLowerCase.Equals(childrenCountList[i].idProperties.idLowerCase, StringComparison.CurrentCultureIgnoreCase)) { childAppears = true; break; } } if (!childAppears) { throw new FormatException(String.Format("Block \"{0}\" is missing the \"{1}\" ID", blockIDProperties.idOriginalCase, childIDProperties.idOriginalCase)); } } } }
public void Generate(HmdProperties hmdProperties) { int tabs = 0; languageGenerator.PrintFileHeader(output, hmdProperties); output.WriteLine(); output.WriteLine(tabs, "namespace {0}", @namespace); output.WriteLine(tabs++, "{"); // // Print Enum Values // List <HmdEnum> hmdEnumList = hmdProperties.EnumList; if (hmdEnumList != null) { foreach (HmdEnum hmdEnum in hmdEnumList) { output.Write(tabs, "public enum {0} {{", typeNameTable.GetTypeName(hmdEnum)); int i; for (i = 0; i < hmdEnum.ValueCount - 1; i++) { output.Write(hmdEnum.GetValue(i)); output.Write(", "); } output.Write(hmdEnum.GetValue(i)); output.WriteLine("};"); } } // // Define Classes // foreach (HmdBlockIDProperties blockProperties in hmdProperties.blockIDTable.definitionDictionary.Values) { GenerateParserClasses(output, blockProperties, hmdProperties, hmdTypePrefix, false); } GenerateParserClasses(output, hmdProperties.root, hmdProperties, hmdTypePrefix, true); output.WriteLine(--tabs, "}"); }
public void ResolveParentOverrideLinks(HmdProperties hmdProperties) { if (parentOverrideList != null) { TextWriter debugOutput = HmdDebug.DebugOutput; if (debugOutput == null) { debugOutput = TextWriter.Null; } for (int i = 0; i < parentOverrideList.Length; i++) { // // Get the parent reference // HmdBlockIDProperties parentBlock = parentOverrideList[i].TryToGetReferenceAsBlock(); if (parentBlock == null) { parentBlock = hmdProperties.GetParentPropertiesInScope(this, parentOverrideList[i]); if (parentBlock == null) { throw new InvalidOperationException(String.Format("Parent \"{0}\" is not defined in the property dictionary", parentOverrideList[i].IDOriginalCase)); } debugOutput.WriteLine("For ID \"{0}\", resolved Parent reference to \"{1}\"", idOriginalCase, parentBlock.idOriginalCase); parentOverrideList[i] = parentBlock; // cache the reference } // // Make sure the parent has this child linked // parentBlock.AddIndirectChildFromFromItsOverrideList(this); // // Add this link as a key to the HmdPropertiesTable // hmdProperties.AddPropertiesFromExtraLinks(parentBlock, this); } } }
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 Boolean IsValidValue(String value, HmdProperties hmdProperties) { switch (hmdType) { case HmdType.String: return(true); case HmdType.Boolean: return(value.Equals("true", StringComparison.CurrentCultureIgnoreCase) || value.Equals("false", StringComparison.CurrentCultureIgnoreCase)); case HmdType.Int: return(value.IsValidInteger(false, 4)); case HmdType.Int1: return(value.IsValidInteger(false, 1)); case HmdType.Int2: return(value.IsValidInteger(false, 2)); case HmdType.Int3: return(value.IsValidInteger(false, 3)); case HmdType.Int4: return(value.IsValidInteger(false, 4)); case HmdType.Int5: return(value.IsValidInteger(false, 5)); case HmdType.Int6: return(value.IsValidInteger(false, 6)); case HmdType.Int7: return(value.IsValidInteger(false, 7)); case HmdType.Int8: return(value.IsValidInteger(false, 8)); case HmdType.Int9: return(value.IsValidInteger(false, 9)); case HmdType.Int10: return(value.IsValidInteger(false, 10)); case HmdType.Int11: return(value.IsValidInteger(false, 11)); case HmdType.Int12: return(value.IsValidInteger(false, 12)); case HmdType.Int13: return(value.IsValidInteger(false, 13)); case HmdType.Int14: return(value.IsValidInteger(false, 14)); case HmdType.Int15: return(value.IsValidInteger(false, 15)); case HmdType.Int16: return(value.IsValidInteger(false, 16)); case HmdType.UInt: return(value.IsValidInteger(true, 4)); case HmdType.UInt1: return(value.IsValidInteger(true, 1)); case HmdType.UInt2: return(value.IsValidInteger(true, 2)); case HmdType.UInt3: return(value.IsValidInteger(true, 3)); case HmdType.UInt4: return(value.IsValidInteger(true, 4)); case HmdType.UInt5: return(value.IsValidInteger(true, 5)); case HmdType.UInt6: return(value.IsValidInteger(true, 6)); case HmdType.UInt7: return(value.IsValidInteger(true, 7)); case HmdType.UInt8: return(value.IsValidInteger(true, 8)); case HmdType.UInt9: return(value.IsValidInteger(true, 9)); case HmdType.UInt10: return(value.IsValidInteger(true, 10)); case HmdType.UInt11: return(value.IsValidInteger(true, 11)); case HmdType.UInt12: return(value.IsValidInteger(true, 12)); case HmdType.UInt13: return(value.IsValidInteger(true, 13)); case HmdType.UInt14: return(value.IsValidInteger(true, 14)); case HmdType.UInt15: return(value.IsValidInteger(true, 15)); case HmdType.UInt16: return(value.IsValidInteger(true, 16)); case HmdType.Decimal: throw new NotImplementedException(); case HmdType.Enumeration: HmdEnum hmdEnum = enumReference.TryGetReference; if (hmdEnum == null) { hmdEnum = hmdProperties.TryGetEnum(enumReference.Name); if (hmdEnum == null) { throw new InvalidOperationException(String.Format("Can't resolve enum reference '{0}'", enumReference.Name)); } this.enumReference = hmdEnum; } return(hmdEnum.IsValidEnumValue(value.Trim())); case HmdType.Empty: throw new InvalidOperationException("Cannot validate the type of a null type"); default: throw new InvalidOperationException(String.Format("HmdType {0} ({1}) is unrecognized", hmdType, (Int32)hmdType)); } }
// // Maybe change to pass in the string offset and length? // public static HmdValueIDProperties ParseValueProperties(String idString, String props, HmdBlockIDProperties definitionParent, HmdProperties hmdProperties) { if (idString == null) { throw new ArgumentNullException("idString"); } Boolean defaultCountPropertyOverriden = false; Boolean defaultHmdTypeOverriden = false; ICountProperty countProperty = hmdProperties.defaultCountProperty; HmdType hmdType = hmdProperties.defaultHmdType; HmdEnumReference enumReference = null; HmdParentReference[] parentOverrideList = null; Int32 offset = 0, saveOffset; // // TODO: To save on memory, maybe I'll add some type of hash lookup so I don't have to instantiate multiple HmdType classes? // while (true) { while (true) { if (offset >= props.Length) { return(new HmdValueIDProperties(idString, countProperty, hmdType, enumReference, definitionParent, parentOverrideList)); } if (!Char.IsWhiteSpace(props[offset])) { break; } offset++; } if (props[offset] >= '0' && props[offset] <= '9') { saveOffset = offset; // keep going while you see 0-9, '-' or '*' do { offset++; if (offset >= props.Length) { break; } } while ((props[offset] >= '0' && props[offset] <= '9') || props[offset] == '-' || props[offset] == '*'); // // Check that the 'count' property has not been specified Twice // if (defaultCountPropertyOverriden) { throw new FormatException("You've specified the 'count' property twice!"); } defaultCountPropertyOverriden = true; countProperty = CountProperty.Parse(props.Substring(saveOffset, offset - saveOffset)); } else if (props[offset] == 's') { if (offset + 6 > props.Length) // 6 = "string".Length { throw new FormatException(String.Format("Found character '{0}', expected to become \"{1}\", but there are some characters missing", HmdTypeClass.String[0], HmdTypeClass.String)); } if (props[offset + 1] != 't' || props[offset + 2] != 'r' || props[offset + 3] != 'i' || props[offset + 4] != 'n' || props[offset + 5] != 'g') { throw new FormatException(String.Format("Expected 'string', but got '{0}'", props.Substring(offset, 6))); } offset += 6; // // Check that the 'type' property has not been specified Twice // if (defaultHmdTypeOverriden) { throw new FormatException("You've specified the 'type' property twice!"); } defaultHmdTypeOverriden = true; hmdType = HmdType.String; } else if (props[offset] == HmdTypeClass.Boolean[0]) { if (offset + HmdTypeClass.Boolean.Length > props.Length) { throw new FormatException( String.Format("Found character '{0}', expected to become \"{1}\", but there are some characters missing", HmdTypeClass.Boolean[0], HmdTypeClass.Boolean)); } offset++; for (int i = 1; i < HmdTypeClass.Boolean.Length; i++) { if (props[offset] != HmdTypeClass.Boolean[i]) { throw new FormatException(String.Format("Expected \"{0}\", but got \"{1}\"", HmdTypeClass.Boolean, props.Substring(offset - i, HmdTypeClass.Boolean.Length))); } offset++; } // // Check that the 'type' property has not been specified Twice // if (defaultHmdTypeOverriden) { throw new FormatException("You've specified the 'type' property twice!"); } defaultHmdTypeOverriden = true; hmdType = HmdType.Boolean; } else if (props[offset] == 'i' || props[offset] == 'u') { Byte byteSize; Boolean isUnsigned = false; if (props[offset] == 'u') { isUnsigned = true; offset++; if (props[offset] != 'i') { throw new FormatException( String.Format("Found character 'u', expected to become \"uint\", but the next character was '{0}'", props[offset])); } } if (offset + 3 > props.Length) { throw new FormatException( String.Format("Found character '{0}', expected to become \"{1}\", but there are some characters missing", isUnsigned ? 'u' : 'i', isUnsigned ? "uint" : "int")); } if (props[offset + 1] != 'n' || props[offset + 2] != 't') { throw new FormatException(String.Format("Expected \"{0}\", but got \"{1}\"", isUnsigned ? "uint" : "int", isUnsigned ? props.Substring(offset - 1, 4) : props.Substring(offset, 3))); } offset += 3; if (offset < props.Length && props[offset] >= '0' && props[offset] <= '9') { saveOffset = offset; do { offset++; } while (offset < props.Length && props[offset] >= '0' && props[offset] <= '9'); byteSize = Byte.Parse(props.Substring(saveOffset, offset - saveOffset)); } else { byteSize = 0; } // // Check that the 'type' property has not been specified Twice // if (defaultHmdTypeOverriden) { throw new FormatException("You've specified the 'type' property twice!"); } defaultHmdTypeOverriden = true; hmdType = HmdTypeClass.GetIntegerType(isUnsigned, byteSize); } else if (props[offset] == 'e') { offset++; if (offset >= props.Length) { throw new FormatException("Found character 'e', expected to become \"enum\" or \"empty\" but the string abrubtly ended"); } if (props[offset] == HmdTypeClass.Empty[1]) { if (offset + HmdTypeClass.Empty.Length - 1 > props.Length) { throw new FormatException("Found \"em\", expected to become \"empty\", but there are some characters missing"); } offset++; for (int i = 2; i < HmdTypeClass.Empty.Length; i++) { if (props[offset] != HmdTypeClass.Empty[i]) { throw new FormatException(String.Format("Expected \"{0}\", but got \"{1}\"", HmdTypeClass.Empty, props.Substring(offset - i, HmdTypeClass.Empty.Length))); } offset++; } // // Check that the 'type' property has not been specified Twice // if (defaultHmdTypeOverriden) { throw new FormatException("You've specified the 'type' property twice!"); } defaultHmdTypeOverriden = true; hmdType = HmdType.Empty; } else if (props[offset] == HmdTypeClass.Enumeration[1]) { if (offset + HmdTypeClass.Enumeration.Length + 1 > props.Length) { throw new FormatException( String.Format("Found \"en\", expected to become \"{0}\", but there are some characters missing", HmdTypeClass.Enumeration)); } offset++; for (int i = 2; i < HmdTypeClass.Enumeration.Length; i++) { if (props[offset] != HmdTypeClass.Enumeration[i]) { throw new FormatException(String.Format("Expected \"{0}\", but got \"{1}\"", HmdTypeClass.Enumeration, props.Substring(offset - i, HmdTypeClass.Enumeration.Length))); } offset++; } // skip whitespace while (true) { if (offset >= props.Length) { throw new FormatException("Expected '(' or 'a-zA-Z', but got EOF"); } if (!Char.IsWhiteSpace(props[offset])) { break; } offset++; } if (props[offset] == '(') { saveOffset = offset + 1; // skip to the next whitespace or ';' while (true) { offset++; if (offset >= props.Length) { throw new FormatException("Expected ')' but reached end of string"); } if (props[offset] == ')') { break; } } String enumReferenceName = (definitionParent == null || definitionParent.definitionContext == null) ? idString.ToLower() : HmdIDProperties.CombineIDContext(definitionParent.idWithContext, idString.ToLower()); HmdEnum newInlineEnum = new HmdEnum(enumReferenceName, props.Substring(saveOffset, offset - saveOffset)); enumReference = newInlineEnum; if (hmdProperties != null) { hmdProperties.AddEnum(newInlineEnum); } offset++; if (defaultHmdTypeOverriden) { throw new FormatException("You've specified the 'type' property twice!"); } defaultHmdTypeOverriden = true; hmdType = HmdType.Enumeration; } else if ((props[offset] >= 'a' && props[offset] <= 'z') || (props[offset] >= 'A' && props[offset] <= 'Z')) { saveOffset = offset; // skip to the next whitespace or ';' while (true) { offset++; if (offset >= props.Length) { break; } if (Char.IsWhiteSpace(props[offset])) { break; } } if (offset - saveOffset <= 0) { throw new FormatException("Unable to parse enum type, the \"enum\" keyword must be either \"enum <type>\" (with only one space before <type>) or \"enum(<value> <value> ...)\""); } enumReference = new HmdEnumReferenceByString(props.Substring(saveOffset, offset - saveOffset)); if (defaultHmdTypeOverriden) { throw new FormatException("You've specified the 'type' property twice!"); } defaultHmdTypeOverriden = true; hmdType = HmdType.Enumeration; } else { throw new FormatException(String.Format("Expected '(' or 'a-zA-Z' after \"enum\", but got '{0}'", props[offset])); } } else { throw new FormatException(String.Format( "Found character 'e', expected to become \"enum\" or \"empty\" but the second character is '{0}'", props[offset])); } } else if (props[offset] == '(') { if (parentOverrideList != null) { throw new FormatException("You've specified the 'parents' property twice!"); } parentOverrideList = ParseParentList(props, ref offset); } else { throw new FormatException( String.Format("Could not recognize first character of property '{0}', of the props string \"{1}\"", props[offset], props)); } } }
private void ValidateBlockID(HmdBlockID blockID, HmdBlockIDProperties blockIDProperties, HmdProperties hmdProperties) { // // Check that the current parent is valid // if (currentBlock == null) { debugOutput.Write(blockStack.Count, "Checking that \"{0}\" is the root...", blockID.idOriginalCase); if (!blockIDProperties.IsRoot) { throw new FormatException(String.Format("Block ID \"{0}\" was expected to be the root, but it wasn't?", blockIDProperties.idOriginalCase)); } debugOutput.WriteLine("Pass."); } else { debugOutput.Write(blockStack.Count, "Checking that \"{0}\" has \"{1}\" as a valid parent...", blockID.idOriginalCase, currentBlock.blockIDProperties.idOriginalCase); if (!blockIDProperties.IsValidParent(currentBlock.blockIDProperties)) { throw new FormatException(String.Format("Block ID \"{0}\" appeared in Block \"{1}\", but this is not allowed with the current properties", blockIDProperties.idOriginalCase, currentBlock.blockIDProperties.idOriginalCase)); } debugOutput.WriteLine("Pass."); // Add ID to current block validator currentBlock.NewChild(blockIDProperties); } // // Verify the Children of the Block ID // debugOutput.WriteLine(blockStack.Count, "{"); blockStack.Push(currentBlock); currentBlock = new HmdBlockValidator(blockIDProperties); blockID.Iterate(hmdProperties, ValidateValueID, ValidateBlockID); // Validate Children debugOutput.Write(blockStack.Count, "Checking counts of all children for \"{0}\"...", blockID.idOriginalCase); currentBlock.ValidateChildren(hmdProperties); debugOutput.WriteLine("Pass."); currentBlock = blockStack.Pop(); debugOutput.WriteLine(blockStack.Count, "}} (end of \"{0}\")", blockID.idOriginalCase); }
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); }
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 static void ValidateStatic(HmdBlockID root, HmdProperties hmdProperties) { new HmdValidator().Validate(root, hmdProperties); }
public static void Parse(HmdBlockID root, String filename, HmdProperties hmdProperties) { Parse(root, filename, Path.GetDirectoryName(filename), hmdProperties); }
private static HmdValueIDProperties CallParserWithDefaults(String propertyString, HmdProperties hmdProperties) { return(HmdParser.ParseValueProperties(String.Empty, propertyString, hmdProperties.root, hmdProperties)); }
public static void Parse(HmdBlockID root, String filename, String importPath, HmdProperties hmdProperties) { using (FileStream fileStream = new FileStream(filename, FileMode.Open)) { Parse(root, fileStream, importPath, hmdProperties); } }
public static void Parse(HmdBlockID root, TextReader reader, String importPath, HmdProperties hmdProperties) { Parse(root, new HmdTokenizer(reader, 1), importPath, hmdProperties); }
public HmdTypeusbdevice(HmdBlockID blockID, HmdProperties hmdProperties) { for (int i = 0; i < blockID.ChildCount; i++) { HmdID childID = blockID.GetChild(i); if (childID.isBlock) { HmdBlockID childBlockID = (HmdBlockID)childID; throw new FormatException(String.Format("Unrecognized child block id \"{0}\"", childID.idOriginalCase)); } else { HmdValueID childValueID = (HmdValueID)childID; // parse field LegacyName if (childValueID.idLowerCase.Equals("legacyname", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.LegacyName != null) { throw new FormatException("Found multiple value id's \"LegacyName\""); } this.LegacyName = (usbdevicelegacyname)Enum.Parse(typeof(usbdevicelegacyname), childValueID.value, true); } // parse field Protocol else if (childValueID.idLowerCase.Equals("protocol", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.Protocol != null) { throw new FormatException("Found multiple value id's \"Protocol\""); } this.Protocol = Byte.Parse(childValueID.value); } // parse field SubClass else if (childValueID.idLowerCase.Equals("subclass", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.SubClass != null) { throw new FormatException("Found multiple value id's \"SubClass\""); } this.SubClass = Byte.Parse(childValueID.value); } // parse field Class else if (childValueID.idLowerCase.Equals("class", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.Class != null) { throw new FormatException("Found multiple value id's \"Class\""); } this.Class = Byte.Parse(childValueID.value); } // parse field Interface else if (childValueID.idLowerCase.Equals("interface", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.Interface != null) { throw new FormatException("Found multiple value id's \"Interface\""); } this.Interface = Byte.Parse(childValueID.value); } // parse field SerialNumber else if (childValueID.idLowerCase.Equals("serialnumber", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.SerialNumber != null) { throw new FormatException("Found multiple value id's \"SerialNumber\""); } this.SerialNumber = childValueID.value; } // parse field Product else if (childValueID.idLowerCase.Equals("product", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.Product != null) { throw new FormatException("Found multiple value id's \"Product\""); } this.Product = childValueID.value; } // parse field Manufacturer else if (childValueID.idLowerCase.Equals("manufacturer", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.Manufacturer != null) { throw new FormatException("Found multiple value id's \"Manufacturer\""); } this.Manufacturer = childValueID.value; } // parse field ProductID else if (childValueID.idLowerCase.Equals("productid", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.ProductID != null) { throw new FormatException("Found multiple value id's \"ProductID\""); } this.ProductID = UInt16.Parse(childValueID.value); } // parse field VendorID else if (childValueID.idLowerCase.Equals("vendorid", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.VendorID != null) { throw new FormatException("Found multiple value id's \"VendorID\""); } this.VendorID = UInt16.Parse(childValueID.value); } // parse field Speed else if (childValueID.idLowerCase.Equals("speed", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.Speed != null) { throw new FormatException("Found multiple value id's \"Speed\""); } this.Speed = (usbdevicespeed)Enum.Parse(typeof(usbdevicespeed), childValueID.value, true); } // parse field PortName else if (childValueID.idLowerCase.Equals("portname", StringComparison.CurrentCultureIgnoreCase)) { // check that field is not set already if (this.PortName != null) { throw new FormatException("Found multiple value id's \"PortName\""); } this.PortName = childValueID.value; } else { throw new FormatException(String.Format("Unrecognized child value id \"{0}\"", childID.idOriginalCase)); } } } }
public static void Parse(HmdBlockID root, HmdTokenizer tokenizer, String importPath, HmdProperties hmdProperties) { if (root == null) { throw new ArgumentNullException("root"); } TextWriter debugOutput = HmdDebug.DebugOutput; if (debugOutput == null) { debugOutput = TextWriter.Null; } if (importPath == null) { importPath = String.Empty; } HmdBlockID parentID = root; Stack <HmdBlockID> parentIDStack = new Stack <HmdBlockID>(); while (true) { HmdGlobalToken token = tokenizer.NextGlobalToken(); // // Check for EOF // if (token.type == HmdGlobalTokenType.EOF) { debugOutput.WriteLine("EOF"); break; } if (token.type == HmdGlobalTokenType.ID) { String idString = token.text; // // Normal Parse // Boolean isBlockID; Boolean isEmptyID = tokenizer.NextIDType(out isBlockID); if (isBlockID) { debugOutput.WriteLine("Block ID : {0}", idString); parentIDStack.Push(parentID); HmdBlockID temp = parentID; parentID = new HmdBlockID(idString, temp); } else { debugOutput.WriteLine("Value ID : {0}", idString); if (isEmptyID) { parentID.AddChild(new HmdValueID(idString, null, parentID)); } else { String nextValue = tokenizer.NextValue(); debugOutput.WriteLine("Value : {0}", nextValue); parentID.AddChild(new HmdValueID(idString, nextValue, parentID)); } } } else if (token.type == HmdGlobalTokenType.Directive) { String directiveID = token.text; // // Handling Directives // Boolean isBlockID; Boolean isEmptyID = tokenizer.NextIDType(out isBlockID); if (isEmptyID) { throw new NotImplementedException(); } else if (!isBlockID) { if (directiveID.Equals("import", StringComparison.CurrentCulture) || directiveID.Equals("pimport", StringComparison.CurrentCulture)) { Boolean isPimport = directiveID[0] == 'p'; String nextValue = tokenizer.NextValue(); debugOutput.WriteLine("{0} : {1}", isPimport ? "%PImport" : "%Import ", nextValue); if (isPimport && hmdProperties == null) { debugOutput.WriteLine("%PImport : Ignoring props, so skipping this %pimport"); } else { String importFileAndPathName = Path.Combine(importPath, nextValue); using (FileStream importStream = new FileStream(importFileAndPathName, FileMode.Open)) { debugOutput.WriteLine("File Start: {0}", importFileAndPathName); if (isPimport) { ParsePropertiesFile(hmdProperties.root, hmdProperties, new HmdTokenizer(new StreamReader(importStream), 1), importPath, true); } else { Parse(parentID, new HmdTokenizer(new StreamReader(importStream), 1), importPath, hmdProperties); } debugOutput.WriteLine("File End : {0}", importFileAndPathName); } } } else if (directiveID.Equals("enum", StringComparison.CurrentCulture)) { throw new FormatException("%enum value directive must be in a %props block directive"); } else if (directiveID.Equals("props", StringComparison.CurrentCulture)) { throw new FormatException("%props value directive must be in a %props block directive"); } else { throw new Exception(String.Format("Parser (line {0}): Unrecognized value directive \"{1}\"", token.line, directiveID)); } } else { if (directiveID.Equals("props", StringComparison.CurrentCulture)) { debugOutput.WriteLine("%Props Blk:"); if (hmdProperties == null) { debugOutput.WriteLine("Skipping %props block..."); IgnoreCurrentBlock(debugOutput, tokenizer); } else { ParsePropertiesFile(hmdProperties.root, hmdProperties, tokenizer, importPath, false); } } else if (directiveID.Equals("group", StringComparison.CurrentCulture)) { throw new FormatException("%group value directive must be in a %props block directive"); } else { throw new Exception(String.Format("Parser (line {0}): Unrecognized block directive \"{1}\"", token.line, directiveID)); } } } else if (token.type == HmdGlobalTokenType.CloseBrace) { if (parentIDStack.Count <= 0) { throw new FormatException(String.Format("Parser (line {0}): Unmatched close brace {1}", token.line, token)); } debugOutput.WriteLine("Block End : {0}", parentID.idOriginalCase); HmdBlockID temp = parentID; parentID = parentIDStack.Pop(); parentID.AddChild(temp); } else { throw new FormatException(String.Format("Parser (line {0}): Unexpected token {1}", token.line, token)); } } if (parentIDStack.Count > 0) { throw new FormatException(String.Format("Parser (EOF): Block \"{0}\" was not ended with '}'", parentIDStack.Peek().idOriginalCase)); } }