Example #1
0
        protected override object EvalProduction(ParseTree tree, params object[] paramlist)
        {
            Grammar g = (Grammar)paramlist[0];

            if (Nodes[2].Nodes[0].Token.Type == TokenType.STRING)
            {
                TerminalSymbol term = g.Symbols.Find(Nodes[0].Token.Text) as TerminalSymbol;
                if (term == null)
                {
                    tree.Errors.Add(new ParseError("Symbol '" + Nodes[0].Token.Text + "' is not declared. ", 0x1040, Nodes[0]));
                }
            }
            else
            {
                NonTerminalSymbol nts = g.Symbols.Find(Nodes[0].Token.Text) as NonTerminalSymbol;
                if (nts == null)
                {
                    tree.Errors.Add(new ParseError("Symbol '" + Nodes[0].Token.Text + "' is not declared. ", 0x1041, Nodes[0]));
                }
                Rule r = (Rule)Nodes[2].Eval(tree, g, nts);
                if (nts != null)
                {
                    nts.Rules.Add(r);
                }

                if (Nodes[3].Token.Type == TokenType.CODEBLOCK)
                {
                    string codeblock = Nodes[3].Token.Text;
                    nts.CodeBlock = codeblock;
                    ValidateCodeBlock(tree, nts, Nodes[3]);

                    // beautify the codeblock format
                    codeblock     = codeblock.Substring(1, codeblock.Length - 3).Trim();
                    nts.CodeBlock = codeblock;
                }
            }
            return(g);
        }
Example #2
0
        /// <summary>
        /// EvalStart will first do a semantic check to see if symbols are declared correctly
        /// then it will also check for attributes and parse the directives
        /// after that it will complete the transformation to the grammar tree.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="paramlist"></param>
        /// <returns></returns>
        protected override object EvalStart(ParseTree tree, params object[] paramlist)
        {
            TerminalSymbol terminal   = null;
            bool           StartFound = false;
            Grammar        g          = new Grammar();

            foreach (ParseNode n in Nodes)
            {
                if (n.Token.Type == TokenType.Directive)
                {
                    EvalDirective(tree, new object[] { g, n });
                }
                if (n.Token.Type == TokenType.ExtProduction)
                {
                    if (n.Nodes[n.Nodes.Count - 1].Nodes[2].Nodes[0].Token.Type == TokenType.STRING)
                    {
                        try
                        {
                            terminal = new TerminalSymbol(n.Nodes[n.Nodes.Count - 1].Nodes[0].Token.Text, (string)n.Nodes[n.Nodes.Count - 1].Nodes[2].Nodes[0].Token.Text);
                            for (int i = 0; i < n.Nodes.Count - 1; i++)
                            {
                                if (n.Nodes[i].Token.Type == TokenType.Attribute)
                                {
                                    EvalAttribute(tree, new object[] { g, terminal, n.Nodes[i] });
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            tree.Errors.Add(new ParseError("regular expression for '" + n.Nodes[n.Nodes.Count - 1].Nodes[0].Token.Text + "' results in error: " + ex.Message, 0x1020, n.Nodes[0]));
                            continue;
                        }

                        if (terminal.Name == "Start")
                        {
                            tree.Errors.Add(new ParseError("'Start' symbol cannot be a regular expression.", 0x1021, n.Nodes[0]));
                        }

                        if (g.Symbols.Find(terminal.Name) == null)
                        {
                            g.Symbols.Add(terminal);
                        }
                        else
                        {
                            tree.Errors.Add(new ParseError("Terminal already declared: " + terminal.Name, 0x1022, n.Nodes[0]));
                        }
                    }
                    else
                    {
                        NonTerminalSymbol nts = new NonTerminalSymbol(n.Nodes[n.Nodes.Count - 1].Nodes[0].Token.Text);
                        if (g.Symbols.Find(nts.Name) == null)
                        {
                            g.Symbols.Add(nts);
                        }
                        else
                        {
                            tree.Errors.Add(new ParseError("Non terminal already declared: " + nts.Name, 0x1023, n.Nodes[0]));
                        }

                        for (int i = 0; i < n.Nodes.Count - 1; i++)
                        {
                            if (n.Nodes[i].Token.Type == TokenType.Attribute)
                            {
                                EvalAttribute(tree, new object[] { g, nts, n.Nodes[i] });
                            }
                        }

                        if (nts.Name == "Start")
                        {
                            StartFound = true;
                        }
                    }
                }
            }

            if (!StartFound)
            {
                tree.Errors.Add(new ParseError("The grammar requires 'Start' to be a production rule.", 0x0024));
                return(g);
            }

            foreach (ParseNode n in Nodes)
            {
                if (n.Token.Type == TokenType.ExtProduction)
                {
                    n.Eval(tree, g);
                }
            }

            return(g);
        }
Example #3
0
        /// <summary>
        /// EvalStart will first do a semantic check to see if symbols are declared correctly
        /// then it will also check for attributes and parse the directives
        /// after that it will complete the transformation to the grammar tree.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="paramlist"></param>
        /// <returns></returns>
        protected override object EvalStart(ParseTree tree, params object[] paramlist)
        {
            TerminalSymbol terminal = null;
            bool StartFound = false;
            Grammar g = new Grammar();
            foreach (ParseNode n in Nodes)
            {
                if (n.Token.Type == TokenType.Directive)
                {
                    EvalDirective(tree, new object[] { g, n });
                }
                if (n.Token.Type == TokenType.ExtProduction)
                {

                    if (n.Nodes[n.Nodes.Count - 1].Nodes[2].Nodes[0].Token.Type == TokenType.STRING)
                    {
                        try
                        {
                            terminal = new TerminalSymbol(n.Nodes[n.Nodes.Count - 1].Nodes[0].Token.Text, (string)n.Nodes[n.Nodes.Count - 1].Nodes[2].Nodes[0].Token.Text);
                            for (int i = 0; i < n.Nodes.Count - 1; i++)
                            {
                                if (n.Nodes[i].Token.Type == TokenType.Attribute)
                                    EvalAttribute(tree, new object[] { g, terminal, n.Nodes[i] });
                            }

                        }
                        catch (Exception ex)
                        {
                            tree.Errors.Add(new ParseError("regular expression for '" + n.Nodes[n.Nodes.Count - 1].Nodes[0].Token.Text + "' results in error: " + ex.Message, 0x1020, n.Nodes[0]));
                            continue;
                        }

                        if (terminal.Name == "Start")
                            tree.Errors.Add(new ParseError("'Start' symbol cannot be a regular expression.", 0x1021, n.Nodes[0]));

                        if (g.Symbols.Find(terminal.Name) == null)
                            g.Symbols.Add(terminal);
                        else
                            tree.Errors.Add(new ParseError("Terminal already declared: " + terminal.Name, 0x1022, n.Nodes[0]));

                    }
                    else
                    {
                        NonTerminalSymbol nts = new NonTerminalSymbol(n.Nodes[n.Nodes.Count - 1].Nodes[0].Token.Text);
                        if (g.Symbols.Find(nts.Name) == null)
                            g.Symbols.Add(nts);
                        else
                            tree.Errors.Add(new ParseError("Non terminal already declared: " + nts.Name, 0x1023, n.Nodes[0]));

                        for (int i = 0; i < n.Nodes.Count - 1; i++)
                        {
                            if (n.Nodes[i].Token.Type == TokenType.Attribute)
                                EvalAttribute(tree, new object[] { g, nts, n.Nodes[i] });
                        }

                        if (nts.Name == "Start")
                            StartFound = true;
                    }
                }
            }

            if (!StartFound)
            {
                tree.Errors.Add(new ParseError("The grammar requires 'Start' to be a production rule.", 0x0024));
                return g;
            }

            foreach (ParseNode n in Nodes)
            {
                if (n.Token.Type == TokenType.ExtProduction)
                {
                    n.Eval(tree, g);
                }
            }

            return g;
        }