Beispiel #1
0
        internal override GrammarExpressionTuple GenerateGrammar(GrammarType grammarType, int grammarNumber,
                                                                 ref int index, ref int additionalGrammarNumber, Action <GrammarPostReport> onIterate, params GrammarExpressionWithOriginal[] dependencies)
        {
            CheckDependencies(dependencies);

            Grammar leftExpGrammar  = dependencies[0].GrammarExpression.Grammar;
            Grammar rightExpGrammar = dependencies[1].GrammarExpression.Grammar;

            NonTerminalSymbol target = new NonTerminalSymbol(new Label(new SingleLabel(Grammar._DefaultNonTerminalSymbol, index++)));

            Rule rule = new Rule(
                EnumerateHelper.Sequence(
                    new Chain(EnumerateHelper.Sequence(leftExpGrammar.Target)),
                    new Chain(EnumerateHelper.Sequence(rightExpGrammar.Target))
                    ), target);

            IEnumerable <Rule> newRules = leftExpGrammar.Rules.Concat(rightExpGrammar.Rules).Concat(rule);

            GrammarExpressionTuple grammarExpressionTuple = new GrammarExpressionTuple(this, new Grammar(newRules, target), grammarNumber);

            if (onIterate != null)
            {
                onIterate(new GrammarPostReport(grammarExpressionTuple, dependencies));
            }

            return(grammarExpressionTuple);
        }
 public Rule(NonTerminalSymbol leftSide, Symbol rightSide)
 {
     LeftSide  = leftSide;
     RightSide = new List <Symbol> {
         rightSide
     };
 }
Beispiel #3
0
        internal override GrammarExpressionTuple GenerateGrammar(GrammarType grammarType, int grammarNumber,
                                                                 ref int index, ref int additionalGrammarNumber, Action <GrammarPostReport> onIterate, params GrammarExpressionWithOriginal[] dependencies)
        {
            CheckDependencies(dependencies);

            NonTerminalSymbol target = new NonTerminalSymbol(new Label(new SingleLabel(Grammar._DefaultNonTerminalSymbol, index++)));

            GrammarExpressionTuple grammarExpressionTuple =
                new GrammarExpressionTuple(
                    this,
                    new Grammar(
                        EnumerateHelper.Sequence(
                            new Rule(EnumerateHelper.Sequence(new Chain(Enumerable.Empty <Grammars.Symbol>())), target)
                            ),
                        target
                        ),
                    grammarNumber
                    );

            if (onIterate != null)
            {
                onIterate(new GrammarPostReport(grammarExpressionTuple, dependencies));
            }

            return(grammarExpressionTuple);
        }
Beispiel #4
0
        private Grammar MakeGrammarLeft()
        {
            IDictionary <char, TerminalSymbol>     charTerminalMap     = Alphabet.ToDictionary(c => c, c => new TerminalSymbol(c));
            IDictionary <Label, NonTerminalSymbol> stateNonTerminalMap = States.ToDictionary(s => s, s => new NonTerminalSymbol(s));

            NonTerminalSymbol target = Grammar.GetNewNonTerminal(stateNonTerminalMap.Values);

            ISet <Rule> rules = new HashSet <Rule>();

            foreach (Transition transition in Transitions)
            {
                Chain chain = new Chain(
                    EnumerateHelper.Sequence <Symbol>(
                        stateNonTerminalMap[transition.CurrentState], charTerminalMap[transition.Symbol]
                        )
                    );

                rules.Add(new Rule(chain.AsSequence(), stateNonTerminalMap[transition.NextState]));
            }

            rules.Add(new Rule(Chain.Empty.AsSequence(), stateNonTerminalMap[InitialState]));

            IEnumerable <Chain> chains = FinalStates.Select(fs => new Chain(stateNonTerminalMap[fs].AsSequence()));

            rules.Add(new Rule(chains, target));

            return(new Grammar(rules, target));
        }
Beispiel #5
0
        // generates the method header and body
        private string GenerateParseMethod(NonTerminalSymbol s)
        {
            string        Indent2 = IndentTabs(2);
            string        Indent3 = IndentTabs(3);
            StringBuilder sb      = new StringBuilder();

            sb.AppendLine(Indent2 + "private void Parse" + s.Name + "(ParseNode parent)" + Helper.AddComment("NonTerminalSymbol: " + s.Name));
            sb.AppendLine(Indent2 + "{");
            sb.AppendLine(Indent3 + "Token tok;");
            sb.AppendLine(Indent3 + "ParseNode n;");
            sb.AppendLine(Indent3 + "bool found;");
            sb.AppendLine(Indent3 + "ParseNode node = parent.CreateNode(scanner.GetToken(TokenType." + s.Name + "), \"" + s.Name + "\");");
            sb.AppendLine(Indent3 + "parent.Nodes.Add(node);");
            sb.AppendLine("");

            if (s.Rules.Count == 1)
            {
                sb.AppendLine(GenerateProductionRuleCode(s.Rules, 0, 3));
            }
            else
            {
                throw new Exception("Internal error");
            }

            sb.AppendLine(Indent3 + "parent.Token.UpdateRange(node.Token);");
            sb.AppendLine(Indent2 + "}" + Helper.AddComment("NonTerminalSymbol: " + s.Name));
            sb.AppendLine();
            return(sb.ToString());
        }
Beispiel #6
0
 private static IEnumerable <Chain> RightChainEnumerator(Chain chain, NonTerminalSymbol target)
 {
     return(EnumerateHelper.Sequence(
                new Chain(
                    chain.Concat(EnumerateHelper.Sequence(target))
                    ),
                chain
                ));
 }
Beispiel #7
0
 public ParseTreeVisitor(ParseTreeVisitor otherVisitor)
 {
     Forest      = otherVisitor.Forest;
     i           = otherVisitor.i;
     j           = otherVisitor.j;
     currentNode = otherVisitor.currentNode;
     parentNode  = otherVisitor.parentNode;
     currentType = otherVisitor.currentType;
 }
Beispiel #8
0
 public ParseTreeVisitor Left()
 {
     if (currentNode == null)
     {
         return(null);
     }
     parentNode  = currentNode;
     j           = parentNode.k;
     currentNode = Forest.P[i, j, (int)parentNode.B].list;
     currentType = parentNode.B;
     return(this);
 }
Beispiel #9
0
        protected void recurse(int i, int j, NonTerminalSymbol nt, int d, Action <NonTerminalSymbol, ParseTreeNodeMatch, int, bool> act)
        {
            ParseTreeNode      thisnode = Forest.P[i, j, (int)nt];
            ParseTreeNodeMatch m        = thisnode.list;

            act(nt, m, i, m == null);
            if (m != null)
            {
                recurse(i, m.k, m.B, d + 1, act);
                recurse(i + m.k + 1, j - m.k - 1, m.C, d + 1, act);
            }
        }
Beispiel #10
0
 public ParseTreeVisitor Right()
 {
     if (currentNode == null)
     {
         return(null);
     }
     parentNode  = currentNode;
     i           = i + parentNode.k + 1;
     j           = j - parentNode.k - 1;
     currentNode = Forest.P[i, j, (int)parentNode.C].list;
     currentType = parentNode.C;
     return(this);
 }
Beispiel #11
0
 public ParseTreeVisitor(ParseForest treeCollection, NonTerminalSymbol whichTree)
 {
     if (whichTree == 0)
     {
         throw new Exception("Can't pass 0 to ParseTreeVisitor constructor");
     }
     Forest      = treeCollection;
     i           = 0;
     j           = Forest.n - 1;
     currentNode = Forest.P[i, j, (int)whichTree].list;
     parentNode  = null;
     currentType = whichTree;
 }
Beispiel #12
0
        public List <NonTerminalSymbol> SentenceTypes()
        {
            var retval = new List <NonTerminalSymbol>();

            for (NonTerminalSymbol x = 0; x < NonTerminalSymbol.Length; x++)
            {
                if (P[0, n - 1, (int)x].match)
                {
                    retval.Add(x);
                }
            }
            return(retval);
        }
Beispiel #13
0
        // ExtensionMethods /////////////////////////

        public static string PrintPyramid(this ParseForest tree, bool force = false)
        {
            string retval = Environment.NewLine;

            ParseTreeNode[, ,] P = tree.P;
            int n = tree.n, r = tree.r;

            for (int k = n - 1; k >= 0; k--)
            {
                foreach (int i in 1.to(n - k))
                {
                    retval += "\t";
                    //string retval = "";
                    foreach (int nonterminals in 1.to(r))
                    {
                        NonTerminalSymbol nt = (NonTerminalSymbol)nonterminals;
                        if (P[i, k, nonterminals].match && nt != NonTerminalSymbol.comma)
                        {
                            retval += (retval == "" ? "" : ",") + (nt == NonTerminalSymbol.colon ? ":" : nt.ToString());
                        }
                    }
                    retval += (retval.Length > 10 ? "*" : retval);
                }
                retval += Environment.NewLine;
            }
            foreach (int i in 1.to(n))
            {
                retval += ("\t" + tree.a[i]);
            }
            retval += Environment.NewLine;

            // is valid?
            if (tree.Count == 0)
            {
                retval += Environment.NewLine;
            }
            else if (tree.Count == 1)
            {
                retval += "IS a member of language as a " + tree.SentenceType.ToString();
            }
            else
            {
                retval += "is a member of language but ambiguous, with" + tree.Count + " interpretations";
            }
            return(retval);
        }
Beispiel #14
0
        public static List <Rule> ParseRules(List <string> rulesStrings, List <Symbol> possibleSymbols)
        {
            var rules = new List <Rule>();

            foreach (var ruleString in rulesStrings)
            {
                var ruleStringSplit = ruleString.Split(new[] { "->" }, StringSplitOptions.RemoveEmptyEntries);

                var leftSideSymbol   = new NonTerminalSymbol(ruleStringSplit[0]);
                var rightSideSymbols = SymbolParser.ParseSymbols(ruleStringSplit[1], possibleSymbols);

                var rule = new Rule(leftSideSymbol, rightSideSymbols);
                rules.Add(rule);
            }

            return(rules);
        }
Beispiel #15
0
        public static void PrintPyramid(ParseForest tree)
        {
//			if (!force) return;
            ParseTreeNode[, ,] P = tree.P;
            int n = tree.n, r = tree.r;

            for (int k = n - 1; k >= 0; k--)
            {
                foreach (int i in 1.to(n - k))
                {
                    "\t".LogAnd();
                    string retval = "";
                    foreach (int nonterminals in 1.to(r))
                    {
                        NonTerminalSymbol nt = (NonTerminalSymbol)nonterminals;
                        if (P[i, k, nonterminals].match && nt != NonTerminalSymbol.comma)
                        {
                            retval += (retval == "" ? "" : ",") + (nt == NonTerminalSymbol.colon ? ":" : nt.ToString());
                        }
                    }
                    (retval.Length > 10 ? "*" : retval).LogAnd();
                }
                "".Log();
            }
            foreach (int i in 1.to(n))
            {
                ("\t" + tree.a[i]).LogAnd();
            }
            "".Log();

            // is valid?
            if (tree.Count == 0)
            {
                "".Log();                //"is NOT a member of language".Log();
            }
            else if (tree.Count == 1)
            {
                "IS a member of language as a ".Log(tree.SentenceType.ToString());
            }
            else
            {
                "is a member of language but ambiguous, with".Log(tree.Count + " interpretations");
            }
        }
Beispiel #16
0
        // generates the method header and body
        private string GenerateParseMethod(NonTerminalSymbol s)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("        Private Sub Parse" + s.Name + "(ByVal parent As ParseNode)" + Helper.AddComment("'", "NonTerminalSymbol: " + s.Name));
            sb.AppendLine("            Dim tok As Token");
            sb.AppendLine("            Dim n As ParseNode");
            sb.AppendLine("            Dim node As ParseNode = parent.CreateNode(m_scanner.GetToken(TokenType." + s.Name + "), \"" + s.Name + "\")");
            sb.AppendLine("            parent.Nodes.Add(node)");
            sb.AppendLine("");

            foreach (Rule rule in s.Rules)
            {
                sb.AppendLine(GenerateProductionRuleCode(s.Rules[0], 3));
            }

            sb.AppendLine("            parent.Token.UpdateRange(node.Token)");
            sb.AppendLine("        End Sub" + Helper.AddComment("'", "NonTerminalSymbol: " + s.Name));
            sb.AppendLine();
            return sb.ToString();
        }
Beispiel #17
0
        // generates the method header and body
        private string GenerateParseMethod(NonTerminalSymbol s)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("        private void Parse" + s.Name + "(ParseNode parent)" + Helper.AddComment("NonTerminalSymbol: " + s.Name));
            sb.AppendLine("        {");
            sb.AppendLine("            Token tok;");
            sb.AppendLine("            ParseNode n;");
            sb.AppendLine("            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType." + s.Name + "), \"" + s.Name + "\");");
            sb.AppendLine("            parent.Nodes.Add(node);");
            sb.AppendLine("");

            foreach (Rule rule in s.Rules)
            {
                sb.AppendLine(GenerateProductionRuleCode(s.Rules[0], 3));
            }

            sb.AppendLine("            parent.Token.UpdateRange(node.Token);");
            sb.AppendLine("        }" + Helper.AddComment("NonTerminalSymbol: " + s.Name));
            sb.AppendLine();
            return sb.ToString();
        }
Beispiel #18
0
        // generates the method header and body
        private string GenerateParseMethod(NonTerminalSymbol s)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("        Private Sub Parse" + s.Name + "(ByVal parent As ParseNode)" + Helper.AddComment("'", "NonTerminalSymbol: " + s.Name));
            sb.AppendLine("            Dim tok As Token");
            sb.AppendLine("            Dim n As ParseNode");
            sb.AppendLine("            Dim node As ParseNode = parent.CreateNode(m_scanner.GetToken(TokenType." + s.Name + "), \"" + s.Name + "\")");
            sb.AppendLine("            parent.Nodes.Add(node)");
            sb.AppendLine("");

            foreach (Rule rule in s.Rules)
            {
                sb.AppendLine(GenerateProductionRuleCode(s.Rules[0], 3));
            }

            sb.AppendLine("            parent.Token.UpdateRange(node.Token)");
            sb.AppendLine("        End Sub" + Helper.AddComment("'", "NonTerminalSymbol: " + s.Name));
            sb.AppendLine();
            return(sb.ToString());
        }
Beispiel #19
0
        /// <summary>
        /// replaces $ variables with a c# statement
        /// the routine also implements some checks to see if $variables are matching with production symbols
        /// errors are added to the Error object.
        /// </summary>
        /// <param name="nts">non terminal and its production rule</param>
        /// <returns>a formated codeblock</returns>
        private string FormatCodeBlock(NonTerminalSymbol nts)
        {
            string codeblock = nts.CodeBlock;

            if (nts == null)
            {
                return("");
            }

            Regex var = new Regex(@"\$(?<var>[a-zA-Z_0-9]+)(\[(?<index>[^]]+)\])?", RegexOptions.Compiled);

            Symbols symbols = nts.DetermineProductionSymbols();


            Match match = var.Match(codeblock);

            while (match.Success)
            {
                Symbol s = symbols.Find(match.Groups["var"].Value);
                if (s == null)
                {
                    //TOD: handle error situation
                    //Errors.Add("Variable $" + match.Groups["var"].Value + " cannot be matched.");
                    break;                     // error situation
                }
                string indexer = "0";
                if (match.Groups["index"].Value.Length > 0)
                {
                    indexer = match.Groups["index"].Value;
                }

                string replacement = "this.GetValue(tree, TokenType." + s.Name + ", " + indexer + ")";

                codeblock = codeblock.Substring(0, match.Captures[0].Index) + replacement + codeblock.Substring(match.Captures[0].Index + match.Captures[0].Length);
                match     = var.Match(codeblock);
            }

            codeblock = "            " + codeblock.Replace("\n", "\r\n        ");
            return(codeblock);
        }
Beispiel #20
0
        // generates the method header and body
        private string GenerateParseMethod(NonTerminalSymbol s)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("        private void Parse" + s.Name + "(ParseNode parent)" + Helper.AddComment("NonTerminalSymbol: " + s.Name));
            sb.AppendLine("        {");
            sb.AppendLine("            Token tok;");
            sb.AppendLine("            ParseNode n;");
            sb.AppendLine("            ParseNode node = parent.CreateNode(scanner.GetToken(TokenType." + s.Name + "), \"" + s.Name + "\");");
            sb.AppendLine("            parent.getNodes().add(node);");
            sb.AppendLine("");

            foreach (Rule rule in s.Rules)
            {
                sb.AppendLine(GenerateProductionRuleCode(s.Rules[0], 3));
            }

            sb.AppendLine("            parent.Token.UpdateRange(node.Token);");
            sb.AppendLine("        }" + Helper.AddComment("NonTerminalSymbol: " + s.Name));
            sb.AppendLine();
            return(sb.ToString());
        }
Beispiel #21
0
        protected void Recurse(int i, int j, NonTerminalSymbol nt, int d, visitor act)
        {
            ParseTreeNode thisnode = P[i, j, (int)nt];

            if (!thisnode.match)
            {
                return;
            }
            ParseTreeNodeMatch m = thisnode.list;

            if (m != null)
            {
                for (; m != null; m = m.next)
                {
                    act(this, d, false, nt, m.B, m.C, i, j);
                    Recurse(i, m.k, m.B, d + 1, act);
                    Recurse(i + m.k + 1, j - m.k - 1, m.C, d + 1, act);
                }
            }
            else
            {
                act(this, d, true, nt, 0, 0, i, j);
            }
        }
Beispiel #22
0
        internal override GrammarExpressionTuple GenerateGrammar(GrammarType grammarType, int grammarNumber,
                                                                 ref int index, ref int additionalGrammarNumber, Action <GrammarPostReport> onIterate, params GrammarExpressionWithOriginal[] dependencies)
        {
            CheckDependencies(dependencies);

            Func <Chain, NonTerminalSymbol, IEnumerable <Chain> > chainEnumerator;
            Grammar expGrammar = dependencies[0].GrammarExpression.Grammar;

            switch (grammarType)
            {
            case GrammarType.Left:
                chainEnumerator = LeftChainEnumerator;
                break;

            case GrammarType.Right:
                chainEnumerator = RightChainEnumerator;
                break;

            default:
                throw new InvalidOperationException(UnknownGrammarMessage(grammarType));
            }


            IReadOnlySet <Rule> terminalSymbolsOnlyRules;
            IReadOnlySet <Rule> otherRules;

            expGrammar.SplitRules(out terminalSymbolsOnlyRules, out otherRules);

            ISet <Rule> newRules = new HashSet <Rule>(otherRules);

            foreach (Rule rule in terminalSymbolsOnlyRules)
            {
                ISet <Chain> newChains = new HashSet <Chain>(
                    rule.Chains.SelectMany(chain => chainEnumerator(chain, expGrammar.Target))
                    );

                newRules.Add(new Rule(newChains, rule.Target));
            }

            NonTerminalSymbol symbol = new NonTerminalSymbol(new Label(new SingleLabel(Grammar._DefaultNonTerminalSymbol, index++)));

            IEnumerable <Chain> chains = EnumerateHelper.Sequence(new Chain(EnumerateHelper.Sequence(expGrammar.Target)));

            if (!IsPositive)
            {
                chains = chains.Concat(new Chain(Enumerable.Empty <Grammars.Symbol>()));
            }

            newRules.Add(new Rule(chains, symbol));

            GrammarExpressionTuple grammarExpressionTuple =
                new GrammarExpressionTuple(
                    this,
                    new Grammar(newRules, symbol),
                    grammarNumber
                    );

            if (onIterate != null)
            {
                onIterate(new GrammarPostReport(grammarExpressionTuple, dependencies));
            }

            return(grammarExpressionTuple);
        }
 public Symbol(NonTerminalSymbol nonTerminalSymbol)
 {
     IsTerminal = false;
     NonTerminalSymbol = nonTerminalSymbol;
 }
 public RulesListItemModel(NonTerminalSymbol rule)
 {
     Rule   = rule.ToString();
     First  = Join(rule.First);
     Follow = Join(rule.Follow);
 }
Beispiel #25
0
 public ParseTreeNode(bool m, int k, NonTerminalSymbol B, NonTerminalSymbol C, ParseTreeNodeMatch prev)
 {
     match = m; list = new ParseTreeNodeMatch(k, B, C, prev);
 }
Beispiel #26
0
 public ParseTreeNodeMatch(int partition, NonTerminalSymbol b, NonTerminalSymbol c, ParseTreeNodeMatch item)
 {
     k = partition; B = b; C = c; next = item;
 }
Beispiel #27
0
        /// <summary>
        /// replaces $ variables with a c# statement
        /// the routine also implements some checks to see if $variables are matching with production symbols
        /// errors are added to the Error object.
        /// </summary>
        /// <param name="nts">non terminal and its production rule</param>
        /// <returns>a formated codeblock</returns>
        private string FormatCodeBlock(NonTerminalSymbol nts)
        {
            string codeblock = nts.CodeBlock;
            if (nts == null) return "";

            Regex var = new Regex(@"\$(?<var>[a-zA-Z_0-9]+)(\[(?<index>[^]]+)\])?", RegexOptions.Compiled);

            Symbols symbols = nts.DetermineProductionSymbols();

            Match match = var.Match(codeblock);
            while (match.Success)
            {
                Symbol s = symbols.Find(match.Groups["var"].Value);
                if (s == null)
                {
                    //TOD: handle error situation
                    //Errors.Add("Variable $" + match.Groups["var"].Value + " cannot be matched.");
                    break; // error situation
                }
                string indexer = "0";
                if (match.Groups["index"].Value.Length > 0)
                {
                    indexer = match.Groups["index"].Value;
                }

                string replacement = "this.GetValue(tree, TokenType." + s.Name + ", " + indexer + ")";

                codeblock = codeblock.Substring(0, match.Captures[0].Index) + replacement + codeblock.Substring(match.Captures[0].Index + match.Captures[0].Length);
                match = var.Match(codeblock);
            }

            codeblock = "            " + codeblock.Replace("\n", "\r\n        ");
            return codeblock;
        }
 public StateRule(NonTerminalSymbol leftSide, List <Symbol> rightSide, int dotIndex) : base(leftSide, rightSide)
 {
     DotIndex = dotIndex;
 }
 public Rule(NonTerminalSymbol leftSide, List <Symbol> rightSide)
 {
     LeftSide  = leftSide;
     RightSide = rightSide;
 }
Beispiel #30
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;
        }
Beispiel #31
0
        /// <summary>
        /// validates whether $ variables are corresponding to valid symbols
        /// errors are added to the tree Error object.
        /// </summary>
        /// <param name="nts">non terminal and its production rule</param>
        /// <returns>a formated codeblock</returns>
        private void ValidateCodeBlock(ParseTree tree, NonTerminalSymbol nts, ParseNode node)
        {
            if (nts == null) return;
            string codeblock = nts.CodeBlock;

            Regex var = new Regex(@"\$(?<var>[a-zA-Z_0-9]+)(\[(?<index>[^]]+)\])?", RegexOptions.Compiled);

            Symbols symbols = nts.DetermineProductionSymbols();

            MatchCollection matches = var.Matches(codeblock);
            foreach (Match match in matches)
            {
                Symbol s = symbols.Find(match.Groups["var"].Value);
                if (s == null)
                {
                    tree.Errors.Add(new ParseError("Variable $" + match.Groups["var"].Value + " cannot be matched.", 0x1016, node.Token.File, node.Token.StartPos + match.Groups["var"].Index, node.Token.StartPos + match.Groups["var"].Index, match.Groups["var"].Length));
                    break; // error situation
                }
            }
        }
Beispiel #32
0
 public UnitRule(NonTerminalSymbol leftside, string rightside)
 {
     headterm = leftside; TerminalSymbol = rightside;
 }
Beispiel #33
0
 public UnitRule(NonTerminalSymbol leftside, Func <string, bool> findtype)
 {
     headterm = leftside; TypeRule = findtype;
 }
Beispiel #34
0
 public RewriteRule(NonTerminalSymbol leftside, NonTerminalSymbol rightSide1, NonTerminalSymbol rightSide2)
 {
     headterm = leftside; term2 = rightSide1; term3 = rightSide2;
 }