internal static ReductionAction <SYMBOL_ENUM, TREE_NODE> Create <SYMBOL_ENUM, TREE_NODE>(SingleState <SYMBOL_ENUM, TREE_NODE> state, CoverSets <SYMBOL_ENUM> coverSets, HorizonSets <SYMBOL_ENUM> horizonSets) where SYMBOL_ENUM : struct where TREE_NODE : class { SymbolChunkSet <SYMBOL_ENUM> cover = coverSets[state.LhsSymbol]; SymbolChunkSet <SYMBOL_ENUM> horizon = horizonSets[state.LhsSymbol]; // if we have internal conflict between symbols, we cannot use horizon data (because we couldn't tell if we reached horizon) bool use_horizon = !horizon.IsEmpty && !cover.Overlaps(horizon); var action = new ReductionAction <SYMBOL_ENUM, TREE_NODE>(state.CreateCell(), use_horizon ? horizon : null, use_horizon ? new SymbolChunkSet <SYMBOL_ENUM>() : null); return(action); }
public ActionTable <SYMBOL_ENUM, TREE_NODE> FillActionTable(Productions <SYMBOL_ENUM, TREE_NODE> productions, FirstSets <SYMBOL_ENUM> firstSets, CoverSets <SYMBOL_ENUM> coverSets, HorizonSets <SYMBOL_ENUM> horizonSets, int lookaheadWidth, Dfa <SYMBOL_ENUM, TREE_NODE> dfa, PrecedenceTable <SYMBOL_ENUM> precedenceTable, GrammarReport <SYMBOL_ENUM, TREE_NODE> report) { this.coverSets = coverSets; this.horizonSets = horizonSets; this.report = report; this.precedenceTable = precedenceTable ?? new PrecedenceTable <SYMBOL_ENUM>(productions.SymbolsRep); this.symbolsRep = productions.SymbolsRep; actionTable = new ActionTable <SYMBOL_ENUM, TREE_NODE>(dfa, productions, lookaheadWidth); foreach (Node <SYMBOL_ENUM, TREE_NODE> node in dfa.Nodes) { foreach (SymbolChunk <SYMBOL_ENUM> chunk in node.State.PossibleInputs) { ParseAction <SYMBOL_ENUM, TREE_NODE> action_data = computeAction(node, chunk); if (!report.HasGrammarErrors) { actionTable.Add(node.State.Index, chunk, new[] { action_data }); } } // checking recovery conflicts IEnumerable <SingleState <SYMBOL_ENUM, TREE_NODE> > recovery_items = node.State.ParsingActiveItems .Where(it => it.IsAtRecoveryPoint); var recovery_stats = DynamicDictionary.CreateWithDefault <SYMBOL_ENUM, List <SingleState <SYMBOL_ENUM, TREE_NODE> > >(); foreach (SingleState <SYMBOL_ENUM, TREE_NODE> rec_state in recovery_items) { foreach (SymbolChunk <SYMBOL_ENUM> first in firstSets[rec_state.RecoveryMarkerSymbol].Chunks) { recovery_stats[first.Symbols.First()].Add(rec_state); } } foreach (var pair in recovery_stats.Where(it => it.Value.Count > 1)) { report.AddError(pair.Value.Select(it => it.IndexStr), "Recovery item conflict on \"" + symbolsRep.Get(pair.Key) + "\"."); } } report.AddWarnings(precedenceTable.GetUnusedEntries(symbolsRep)); if (report.HasGrammarErrors) { return(null); } else { report.ActionTable = actionTable; return(actionTable); } }