Esempio n. 1
0
        /// <summary>
        /// constructor, construct parser table
        /// </summary>
        public Parser(Grammar grammar)
        {
            _lrGotos = new List<int[]>();
            _gotoPrecedence = new List<int[]>();
            _lr0Items = new List<LR0Item>();
            _lr1Items = new List<LR1Item>();
            _lr0States = new List<HashSet<int>>();
            _lr0Kernels = new List<HashSet<int>>();
            _lalrStates = new List<HashSet<int>>();
            _terminals = new HashSet<int>();

            _nonterminals = new HashSet<int>();
            _lalrPropogations = new List<IDictionary<int, IList<LALRPropogation>>>();
            _grammar = grammar;
            _productions = new List<Production>();
            _productionDerivation = new List<Derivation>();
            _productionPrecedence = new List<int>();
            var nTokens = _grammar.TokenCategories.Length;
            _firstSets = new HashSet<int>[nTokens];

            PopulateProductions();
            InitSymbols();
            GenerateLR0Items();
            ComputeFirstSets();
            ConvertLR0ItemsToKernels();
            var nLalrStates = InitLALRTables();
            CalculateLookAheads();

            _parseTable = new ParseTable(nLalrStates, nTokens);
            GenerateParseTable();
        }
Esempio n. 2
0
        private static async Task MainAsync(string[] args, CancellationToken token)
        {
            //
            // the following program produces a parse table for the following grammar
            // for infix expressions, and appropriately applies operator precedence of
            // the + - * / operators, otherwise evaluating the leftmost operations first
            //
            // S' -> e
            // e -> i
            // e -> ( e )
            // e -> e * e
            // e -> e / e
            // e -> e + e
            // e -> e - e
            //
            var grammar = new Grammar(
                new[] {"S'", "e", "+", "-", "*", "/", "i", "(", ")"},
                new PrecedenceGroup(Derivation.None,
                                    //S' -> e
                                    new Production(0, (_, x) => x[0], 1),
                                    //e -> i
                                    new Production(1, (_, x) => x.Length == 1 ? x[0] : null, 6),
                                    //e -> ( e )
                                    new Production(1,
                                                   (_, x) => x[1].ContentType == ContentType.Nested ? x[1].Nested : null,
                                                   7, 1, 8)
                    ),
                new PrecedenceGroup(Derivation.LeftMost,
                                    //e -> e * e
                                    new Production(1, RewriteConstBinaryExpr, 1, 4, 1),
                                    //e -> e / e
                                    new Production(1, RewriteConstBinaryExpr, 1, 5, 1)
                    ),
                // productions are left associative and bind less tightly than * or /
                new PrecedenceGroup(Derivation.LeftMost,
                                    //e -> e + e
                                    new Production(1, RewriteConstBinaryExpr, 1, 2, 1),
                                    //e -> e - e
                                    new Production(1, RewriteConstBinaryExpr, 1, 3, 1)
                    )
                );

            // generate the parse table
            var parser = new Parser(grammar);
            var debugger = new Debug(parser, Console.Write, Console.Error.Write);

            debugger.DumpParseTable();
            debugger.Flush();

            var parseTime = System.Diagnostics.Stopwatch.StartNew();
#if DEBUG
            // (24 / 12) + 2 * (3-4)
            var inputSource = new[]
                {
                    new Token(6, 2),
                    new Token(2, "+"),
                    new Token(7, "("),
                    new Token(6, 0),
                    new Token(4, "*"),
                    new Token(6, int.MaxValue),
                    new Token(8, ")")
                };
#else
            var inputSource = TestLarge();
#endif
            Token result;
            using (var tokenIterator = new AsyncLATokenIterator(inputSource.AsAsync()))
            {
                result = await parser.ParseInputAsync(tokenIterator, debugger, allowRewriting: true);
            }
            parseTime.Stop();
            var timeElapsed = string.Format("{0} ms", parseTime.Elapsed.TotalMilliseconds);
            debugger.WriteFinalToken(
                string.Format("Accept ({0}): ", timeElapsed),
                string.Format("Error while parsing ({0}): ", timeElapsed),
                              result);
        }