private void Reduce(StackGraph graph) { var newHeads = new List <Node>(); var curHeadList = graph.Heads; while (curHeadList.Count > 0) { var headsWithShifts = curHeadList .Where(h => Table[h.State].ShiftActionsMap.Count > 0) .ToList(); newHeads.AddRange(headsWithShifts); var reducedHeads = curHeadList .Where(h => Table[h.State].ReduceRulesIds.Count > 0) .SelectMany(h => Table[h.State].ReduceRulesIds .Select(r => new { Head = h, Rule = Table.Grammar.Rules[r] })) .SelectMany(t => FindAllPathsBack(t.Head, t.Rule.SourceTokens.Count + 1) .Select(p => new { Head = t.Head, Rule = t.Rule, Path = p })) .Select(t => CreateReduceNode(t.Path, t.Rule)) .Where(rn => rn != null) .ToList(); curHeadList = reducedHeads; } newHeads = CombineNodes(newHeads).ToList(); graph.Heads = newHeads; }
private void Shift(StackGraph graph, GrammarRuleToken token) { List <Node> resultNodes = new List <Node>(graph.Heads.Count); foreach (var head in graph.Heads) { if (Table[head.State].ShiftActionsMap.TryGetValue(token, out int nextState)) { var newNode = new Node(token, nextState); newNode.PrevNodes.Add(new Edge { PrevNode = head, Meta = new ParseExplanation { ResultToken = token, RuleApplied = null, ChildrenExplained = null } }); resultNodes.Add(newNode); } else if (Table.Grammar.IsSkipGrammar && Table[head.State].ShiftActionsMap.TryGetValue(Table.Grammar.SkipToken, out int skipState)) { var newNode = new Node(token, nextState); newNode.PrevNodes.Add(new Edge { PrevNode = head, Meta = new ParseExplanation { ResultToken = token, RuleApplied = null, ChildrenExplained = null } }); resultNodes.Add(newNode); } } graph.Heads = CombineNodes(resultNodes).ToList(); }
public void Parse(string[] strTokens) { var tokens = strTokens.Select(s => new GrammarRuleToken { IsTerminal = true, Value = s.Trim() }).ToList(); int curTokenIndex = 0; var graph = new StackGraph(); graph.Heads.Add(new Node(null, 0)); while (curTokenIndex <= tokens.Count) { Reduce(graph); if (curTokenIndex < tokens.Count) { Shift(graph, tokens[curTokenIndex]); } curTokenIndex++; } }