private void AddActionEntry(Item item, Func <ActionParsingTableEntry, bool> action, string actionDescription, ItemSet set, TerminalExpressionDefinition expressionDefinition) { ParsingTableSegment segment = GetOrCreateSegment(set); ActionParsingTableEntry existingEntry = (ActionParsingTableEntry)segment.Entries.FirstOrDefault(x => x is ActionParsingTableEntry apte && apte.ActionDescription == actionDescription && apte.ExpressionDefinition.IsEqualTo(expressionDefinition)); if (existingEntry == null) { segment.Entries.Add(new ActionParsingTableEntry { ItemSet = set, ExpressionDefinition = expressionDefinition, Items = new List <Item> { item }, ActionDescription = actionDescription, Action = action }); } else { existingEntry.Items.Add(item); } }
private void DoParse() { while (true) { ActionParsingTableEntry entry = GetEntry(); if (!entry.Action(entry)) { break; } } }
private bool Shift(ActionParsingTableEntry entry) { ItemSet arg1 = entry.ItemSet; ExpressionDefinition arg3 = entry.ExpressionDefinition; List <ItemSet> transitions = arg1.Transitions.Where(x => x.Key.IsEqualTo(arg3)).Select(x => x.Value).ToList(); if (transitions.Count > 1) { throw new Exception(); } ItemSet transition = transitions.First(); if (DebugModeEnabled) { Console.WriteLine("SHIFT " + Current.ToString() + ", to" + transition.Id); } Stack.Add(transition); ParsingNode parsingNode = new ParsingNode() { Expression = new TerminalExpression { TokenType = ((TerminalExpressionDefinition)arg3).TokenType, Key = ((TerminalExpressionDefinition)arg3).Key }, Parser = this, SubProduction = arg3.SubProduction }; parsingNode.Attributes.Add(ParserConstants.Token, Current); ParsingNodes.Add(parsingNode); Current = LexicalAnalyzer.GetNextToken(); return(true); }
private bool Accept(ActionParsingTableEntry entry) { return(false); }
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); }