public void ValidateNextGlobalToken(String input, HmdGlobalTokenType type, UInt32 lines, String expectedText)
        {
            HmdTokenizer tokenizer = new HmdTokenizer(new StringReader(input), 0);

            HmdGlobalToken token = tokenizer.NextGlobalToken();

            Assert.AreEqual(lines, token.line);
            Assert.IsTrue(expectedText.Equals(token.text, StringComparison.CurrentCultureIgnoreCase));
        }
Exemple #2
0
        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));
            }
        }
Exemple #3
0
        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));
                }
            }
        }
Exemple #4
0
        private static void IgnoreCurrentBlock(TextWriter debugOutput, HmdTokenizer tokenizer)
        {
            HmdGlobalToken token;
            Int32          ignoreStackDepth = 0;

            while (true)
            {
                token = tokenizer.NextGlobalToken();

                // Check for EOF
                if (token.type == HmdGlobalTokenType.EOF)
                {
                    throw new FormatException(String.Format("Parser (line {0}): Got EOF in the middle of a %props block",
                                                            token.line));
                }
                if (token.type == HmdGlobalTokenType.ID)
                {
                    String  idString = token.text;
                    Boolean isBlockID;
                    Boolean isEmptyID = tokenizer.NextIDType(out isBlockID);

                    if (isEmptyID)
                    {
                        debugOutput.WriteLine("Value ID  : {0} (IGNORED)", idString);
                    }
                    else if (isBlockID)
                    {
                        debugOutput.WriteLine("Block ID  : {0}", idString);
                        ignoreStackDepth++;
                    }
                    else
                    {
                        debugOutput.WriteLine("Value ID  : {0} (IGNORED)", idString);

                        String nextValue = tokenizer.NextValue();
                        debugOutput.WriteLine("Value     : {0} (IGNORED)", nextValue);
                    }
                }
                else if (token.type == HmdGlobalTokenType.Directive)
                {
                    String  directiveIDString = token.text;
                    Boolean isBlockID;
                    Boolean isEmptyID = tokenizer.NextIDType(out isBlockID);

                    if (isEmptyID)
                    {
                        debugOutput.WriteLine("Value ID  : {0} (IGNORED)", directiveIDString);
                    }
                    else if (isBlockID)
                    {
                        debugOutput.WriteLine("Block ID  : {0}", directiveIDString);
                        ignoreStackDepth++;
                    }
                    else
                    {
                        debugOutput.WriteLine("Value ID  : {0} (IGNORED)", directiveIDString);

                        String nextValue = tokenizer.NextValue();
                        debugOutput.WriteLine("Value     : {0} (IGNORED)", nextValue);
                    }
                }
                else if (token.type == HmdGlobalTokenType.CloseBrace)
                {
                    if (ignoreStackDepth <= 0)
                    {
                        break;
                    }
                    ignoreStackDepth--;
                }
                else
                {
                    throw new FormatException(String.Format("Parser (line {0}): Unexpected token {1}", token.line, token));
                }
            }
        }