예제 #1
0
        private bool SkipErrors(GrammarRule entry)
        {
            if (entry.IsTerminalRule)
            {
                return(true);
            }

            if (entry.FirstSet.Contains(_lookahead.TokenType) || (entry.IsNullable && entry.FollowSet.Contains(_lookahead.TokenType)))
            {
                return(true);
            }
            else
            {
                // Write error
                _syntaxErrorStream.WriteLine($"Syntax error: [{_lookahead.StartLine}:{_lookahead.StartColumn}]");
                Console.WriteLine($"Error: Syntax error: [{_lookahead.StartLine}:{_lookahead.StartColumn}]");
                var firstAndFollow = entry.FirstSet.Concat(entry.FollowSet ?? new List <TokenType>()).ToList();
                while (!firstAndFollow.Contains(_lookahead.TokenType))
                {
                    if (!ShiftForwardLookaheadToken())
                    {
                        return(false);
                    }
                    if (entry.IsNullable && entry.FollowSet.Contains(_lookahead.TokenType))
                    {
                        return(false);
                    }
                }
                return(true);
            }
        }
예제 #2
0
        private void PrintSatisfiableRHS(GrammarRule entry, List <IRule> satisfiableRHS)
        {
            var           LHS = entry.Symbol;
            var           RHS = satisfiableRHS.OfType <GrammarRule>().Select(x => x.Symbol);
            StringBuilder b   = new StringBuilder();

            b.Append($"{LHS} -> ");
            foreach (var symbol in RHS)
            {
                b.Append($"{symbol} ");
            }

            _derivationsStream.WriteLine(b.ToString());
        }
예제 #3
0
        // Explanation based on slide 11 of slides SyntaxII
        public bool Parse(NonTerminal nonTerminal)
        {
            GrammarRule entry = _grammar[nonTerminal];

            if (!SkipErrors(entry))
            {
                return(false);
            }

            if (entry.IsTerminalRule)
            {
                PrintTerminalRule(entry);
                var result = Match(entry.FirstSet.First());
                return(result);
            }

            if (!entry.FirstSet.Contains(_lookahead.TokenType))
            {
                var result = entry.IsNullable && entry.FollowSet.Contains(_lookahead.TokenType);
                //ErrorExpectedTokens(entry.FirstSet, currentLookahead.StartLine, currentLookahead.StartColumn);
                return(result);
            }

            List <IRule> satisfiableRHS = null;

            foreach (var rhs in entry.RHSSet)
            {
                var grammarRules = rhs.Where(x => x is GrammarRule); // Filter out semantic rules
                var firstRule    = grammarRules.First() as GrammarRule;
                if (firstRule.FirstSet.Contains(_lookahead.TokenType) || (firstRule.IsNullable && firstRule.FollowSet.Contains(_lookahead.TokenType)))
                {
                    satisfiableRHS = rhs;
                    PrintSatisfiableRHS(entry, satisfiableRHS);
                    break;
                }
            }

            if (satisfiableRHS == null)
            {
                // ERROR
                Console.WriteLine("ASSERT: no satisfiable RHS");
                Environment.Exit(-2);
            }

            // Going through the RHS
            foreach (var symbol in satisfiableRHS)
            {
                var grammarRule  = symbol as GrammarRule;
                var semanticRule = symbol as ISemanticRule;

                if (grammarRule != null) // Is a Grammar rule
                {
                    bool result = Parse(grammarRule.Symbol);
                    if (!result)
                    {
                        // Report error
                        _hasRHSErrors = true;
                    }
                }
                else if (semanticRule != null) // Is a Semantic Rule
                {
                    // Do semantic rule stuff
                    _astBuilder.HandleSemanticRule(semanticRule, _lookahead, _previousLookahead, _previousPreviousLookahead);
                }
                else
                {
                    _syntaxErrorStream.WriteLine("Unhandled production type");
                    Console.WriteLine("ERROR: Unhandled production type");
                    Environment.Exit(-1);
                }
            }

            return(true);
        }
예제 #4
0
        private void PrintTerminalRule(GrammarRule entry)
        {
            var rhs = char.ToLower(entry.Symbol.ToString()[0]) + entry.Symbol.ToString().Substring(1);

            _derivationsStream.WriteLine($"{entry.Symbol} -> {rhs}");
        }
예제 #5
0
 public RuleMatch(Lexem lexem, GrammarRule rule)
 {
     Lexem = lexem;
     Rule  = rule;
 }