Ejemplo n.º 1
0
        private static void Try(string input)
        {
            AntlrFileStream        str      = new AntlrFileStream(input);
            BisonLexer             lexer    = new BisonLexer(str);
            CommonTokenStream      tokens   = new CommonTokenStream(lexer);
            BisonParser            parser   = new BisonParser(tokens);
            ErrorListener <IToken> listener = new ErrorListener <IToken>(parser, lexer, tokens);

            parser.AddErrorListener(listener);
            BisonParser.InputContext tree = parser.input();
            if (listener.had_error)
            {
                System.Console.WriteLine("error in parse.");
            }
            else
            {
                System.Console.WriteLine("parse completed.");
                GrammarListener visitor = new GrammarListener();
                ParseTreeWalker.Default.Walk(visitor, tree);
                foreach (Tuple <string, List <List <string> > > r in visitor.rules)
                {
                    string lhs = r.Item1;
                    System.Console.WriteLine(lhs);
                    List <List <string> > rhs = r.Item2;
                    bool first = true;
                    foreach (List <string> s in rhs)
                    {
                        System.Console.Write(first ? "  :" : "  |");
                        first = false;
                        foreach (string c in s)
                        {
                            System.Console.Write(" " + c);
                        }

                        System.Console.WriteLine();
                    }
                    System.Console.WriteLine("  ;");
                }
            }
            System.Console.WriteLine(tokens.OutputTokens());
            System.Console.WriteLine(tree.OutputTree(tokens));
        }
Ejemplo n.º 2
0
        public void Try(string ffn, string input, ref Dictionary <string, string> results)
        {
            bool                        convert_undefined_to_terminals = true;
            string                      now       = DateTime.Now.ToString();
            StringBuilder               errors    = new StringBuilder();
            StringBuilder               sb        = new StringBuilder();
            AntlrInputStream            str       = new AntlrInputStream(input);
            BisonLexer                  lexer     = new BisonLexer(str);
            CommonTokenStream           tokens    = new CommonTokenStream(lexer);
            BisonParser                 parser    = new BisonParser(tokens);
            ErrorListenerBison <IToken> elistener = new ErrorListenerBison <IToken>(parser, lexer, tokens, errors);

            parser.AddErrorListener(elistener);
            BisonParser.InputContext tree = parser.input();
            string error_file_name        = ffn.Replace(".g4", ".txt");

            if (elistener.had_error)
            {
                results.Add(ffn.Replace(".y", ".txt"), errors.ToString());
                return;
            }
            else
            {
                errors.AppendLine("File " + ffn + " parsed successfully.");
                errors.AppendLine("Date: " + now);
            }

            // Get list of tokens. Convert this to a list of capitalized names.
            Dictionary <string, string> terminals                = new Dictionary <string, string>();
            Dictionary <string, string> nonterminals             = new Dictionary <string, string>();
            List <Tuple <string, List <List <string> > > > rules = new List <Tuple <string, List <List <string> > > >();

            // Collect terminals.
            using (AntlrTreeEditing.AntlrDOM.AntlrDynamicContext dynamicContext =
                       new AntlrTreeEditing.AntlrDOM.ConvertToDOM().Try(tree, parser))
            {
                org.eclipse.wst.xml.xpath2.processor.Engine engine =
                    new org.eclipse.wst.xml.xpath2.processor.Engine();
                var nodes = engine.parseExpression(
                    @"//token_decls//token_decl/id[position() = 1]",
                    new StaticContextBuilder()).evaluate(
                    dynamicContext, new object[] { dynamicContext.Document })
                            .Select(x => (x.NativeValue as AntlrTreeEditing.AntlrDOM.AntlrElement).AntlrIParseTree);
                Antlr4.Runtime.Tree.IParseTree parent;
                foreach (var token in nodes)
                {
                    string tok     = token.GetText();
                    string cap_tok = tok.Length == 1 ? char.ToUpper(tok[0]).ToString() :
                                     (char.ToUpper(tok[0]) + tok.Substring(1));
                    terminals.Add(tok, cap_tok);
                }
            }

            // Collect rules.
            using (AntlrTreeEditing.AntlrDOM.AntlrDynamicContext dynamicContext =
                       new AntlrTreeEditing.AntlrDOM.ConvertToDOM().Try(tree, parser))
            {
                org.eclipse.wst.xml.xpath2.processor.Engine engine =
                    new org.eclipse.wst.xml.xpath2.processor.Engine();
                var nodes = engine.parseExpression(
                    @"//rules",
                    new StaticContextBuilder()).evaluate(
                    dynamicContext, new object[] { dynamicContext.Document })
                            .Select(x => (x.NativeValue as AntlrTreeEditing.AntlrDOM.AntlrElement));
                foreach (var rule in nodes)
                {
                    var    r       = rule.AntlrIParseTree;
                    var    lhs     = r.GetChild(0).GetText();
                    string cap_tok = lhs.Length == 1 ? char.ToLower(lhs[0]).ToString() :
                                     (char.ToLower(lhs[0]) + lhs.Substring(1));
                    nonterminals[lhs] = cap_tok;
                    var rhs   = new List <List <string> >();
                    var rhses = engine.parseExpression(
                        @".//rhses_1/rhs",
                        new StaticContextBuilder()).evaluate(
                        dynamicContext, new object[] { rule })
                                .Select(x => (x.NativeValue as AntlrTreeEditing.AntlrDOM.AntlrElement));
                    foreach (var r1 in rhses)
                    {
                        rhs.Add(new List <string>());
                        var sym = engine.parseExpression(
                            @".//symbol",
                            new StaticContextBuilder()).evaluate(
                            dynamicContext, new object[] { r1 })
                                  .Select(x => (x.NativeValue as AntlrTreeEditing.AntlrDOM.AntlrElement).AntlrIParseTree);
                        foreach (var s in sym)
                        {
                            List <string> l = rhs.Last();
                            l.Insert(0, s.GetText());
                        }
                    }
                    rules.Add(new Tuple <string, List <List <string> > >(lhs, rhs));
                }
            }

            // First, collect information about the grammar.
            //          BisonGrammarListener listener = new BisonGrammarListener();
            //          ParseTreeWalker.Default.Walk(listener, tree);


            if (convert_undefined_to_terminals)
            {
                foreach (Tuple <string, List <List <string> > > r in rules)
                {
                    List <List <string> > rhs = r.Item2;
                    foreach (List <string> s in rhs)
                    {
                        foreach (string c in s)
                        {
                            if (rules.Where(rr => rr.Item1 == c).Any())
                            {
                                continue;
                            }

                            if (terminals.ContainsKey(c))
                            {
                                continue;
                            }

                            if (c[0] == '\'')
                            {
                                continue;
                            }

                            if (c == "error")
                            {
                                continue;
                            }
                            // RHS symbol is not a non-terminal and not a %token terminal.
                            // Enter it as a terminal.
                            string tok     = c;
                            string cap_tok = tok.Length == 1 ? char.ToUpper(tok[0]).ToString() :
                                             (char.ToUpper(tok[0]) + tok.Substring(1));
                            terminals.Add(tok, cap_tok);
                            // Note that in the error list.
                            errors.AppendLine("Symbol " + c + " not declared, assuming it is a terminal.");
                        }
                    }
                }
            }

            // Convert any nonterminals which are keywords in Antlr...
            foreach (Tuple <string, List <List <string> > > r in rules)
            {
                if (!terminals.ContainsKey(r.Item1) &&
                    (r.Item1 == "options" ||
                     r.Item1 == "grammar" ||
                     r.Item1 == "tokenVocab" ||
                     r.Item1 == "lexer" ||
                     r.Item1 == "parser" ||
                     r.Item1 == "rule"
                    ))
                {
                    if (!nonterminals.ContainsKey(r.Item1))
                    {
                        nonterminals.Add(r.Item1, r.Item1 + "_nonterminal");
                    }
                }
                else
                {
                    if (!nonterminals.ContainsKey(r.Item1))
                    {
                        nonterminals.Add(r.Item1, r.Item1);
                    }
                }
            }

            // Get the name of the grammar.
            string name = System.IO.Path.GetFileNameWithoutExtension(ffn);

            sb.AppendLine("// Combined Antlr4 grammar generated by Antlrvsix.");
            sb.AppendLine("// Input grammar: " + ffn);
            sb.AppendLine("// Date: " + now);
            sb.AppendLine();
            sb.AppendLine("grammar " + name + ";");

            // Output the rules.
            foreach (Tuple <string, List <List <string> > > r in rules)
            {
                string lhs = r.Item1;
                lhs = nonterminals[lhs];
                nonterminals.TryGetValue(lhs, out string nlhs);
                if (nlhs != null && nlhs != "")
                {
                    lhs = nlhs;
                }
                sb.Append(lhs);
                List <List <string> > rhs = r.Item2;
                bool first = true;
                foreach (List <string> s in rhs)
                {
                    sb.Append(first ? "  :" : "  |");
                    first = false;
                    foreach (string c in s)
                    {
                        var re = c;
                        if (terminals.ContainsKey(re))
                        {
                            re = terminals[re];
                        }
                        else if (nonterminals.ContainsKey(re))
                        {
                            re = nonterminals[re];
                        }
                        sb.Append(" " + re);
                    }

                    sb.AppendLine();
                }
                sb.AppendLine("  ;");
            }

            // Check for use of error symbol. The semantics is for the parser to look for
            // the ERROR token.
            bool found = false;

            foreach (Tuple <string, List <List <string> > > r in rules)
            {
                List <List <string> > rhs = r.Item2;
                foreach (List <string> s in rhs)
                {
                    foreach (string c in s)
                    {
                        if (c == "error")
                        {
                            found = true;
                            goto bigexit;
                        }
                    }
                }
            }
bigexit:
            if (found)
            {
                sb.AppendLine("error : ERROR ;");
            }
            results.Add(ffn.Replace(".y", ".g4"), sb.ToString());
            results.Add(ffn.Replace(".y", ".txt"), errors.ToString());
        }