private ActionParsingTableEntry GetEntry() { List <ActionParsingTableEntry> entries = ParsingTable.GetSegment(Stack.Last()).Entries .Where(x => x is ActionParsingTableEntry a && a.ExpressionDefinition.TokenType == Current.Type).Cast <ActionParsingTableEntry>().ToList(); if (entries.Count == 1) { return(entries.First()); } else if (entries.Count > 1) { // reduce/reduce of shift/reduce conflict List <ActionParsingTableEntry> entriesForLookahead = entries.Where(x => x.Items.Any(y => y.Lookahead.Any(z => z.TokenType == Current.Type))).ToList();; if (entriesForLookahead.Count == 1) { return(entriesForLookahead.First()); } if (entries.Count == 1) { return(entries.First()); } else if (entries.Count > 1) { return(ResolveShiftReduceConflicts(entries)); } else { Error(); } } else { Error(); } return(null); }
private bool Reduce(ActionParsingTableEntry entry) { SubProduction subProduction = null; if (entry.Items.Count > 1) { Item match = entry.Items.First(x => x.Lookahead.Any(x => x.TokenType == Current.Type)); subProduction = match.SubProduction; } else { subProduction = entry.Items.First().SubProduction; } NonTerminalExpressionDefinition target = new NonTerminalExpressionDefinition { Identifier = subProduction.Production.Identifier }; ParsingNode parsingNode = new ParsingNode() { Expression = new NonTerminalExpression { Identifier = subProduction.Production.Identifier, }, Parser = this, SubProduction = subProduction }; for (int y = subProduction.Count - 1; y >= 0; y--) { for (int i = ParsingNodes.Count - 1; i >= 0; i--) { if (ParsingNodes[i].Parent != null) { continue; } if (ParsingNodes[i].Expression is NonTerminalExpression ne && subProduction[y] is NonTerminalExpressionDefinition ned) { if (ne.Identifier == ned.Identifier) { ParsingNodes[i].Expression.Key = ned.Key; ParsingNodes[i].Parent = parsingNode; break; } } if (ParsingNodes[i].Expression is TerminalExpression te && subProduction[y] is TerminalExpressionDefinition ted) { if (te.TokenType == ted.TokenType) { ParsingNodes[i].Parent = parsingNode; break; } } } } ParsingNodes.Add(parsingNode); List <ExpressionDefinition> expressionDefinitionsToRemove = subProduction.Where(x => !(x is SemanticActionDefinition) && !(x is TerminalExpressionDefinition ted && ted.TokenType == TokenType.EmptyString)).ToList(); for (int i = 0; i < expressionDefinitionsToRemove.Count(); i++) { Stack.RemoveAt(Stack.Count - 1); } ItemSet tos = Stack.Last(); List <ParsingTableEntry> entries = ParsingTable.GetSegment(tos).Entries .Where(x => x is GotoParsingTableEntry g && g.ItemSet == tos && g.ExpressionDefinition.IsEqualTo(target)).ToList(); if (entries.Count > 1) { throw new Exception(); } GotoParsingTableEntry gotoEntry = (GotoParsingTableEntry)entries.First(); if (DebugModeEnabled) { Console.WriteLine("REDUCE DEST " + gotoEntry.Destination.Id + ", TARGET " + target.ToString()); } Stack.Add(gotoEntry.Destination); return(true); }