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); } }
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()); }
// 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); }
private void PrintTerminalRule(GrammarRule entry) { var rhs = char.ToLower(entry.Symbol.ToString()[0]) + entry.Symbol.ToString().Substring(1); _derivationsStream.WriteLine($"{entry.Symbol} -> {rhs}"); }
public RuleMatch(Lexem lexem, GrammarRule rule) { Lexem = lexem; Rule = rule; }