//tenhle overload se volá po posledním výpočtu lookaheadů, kde jsme ochotni tolerovat i shift/reduce //konflikty, kde budeme preferovat shift; proto tento overload zjišťuje, zda se v daném automatu //nacházejí i reduce/reduce konflikty, se kterými už bychom si neuměli rozumně poradit private bool checkForConflicts(LookaheadComplexity lastStage, out bool reduceReduceConflictsInAutomaton) { bool conflictsInAutomaton = false; reduceReduceConflictsInAutomaton = false; foreach (State state in parserStates) { if (stateResolvedAt[state.StateNumber] == LookaheadComplexity.Unresolved) { BitVectorSet accumulator = new BitVectorSet(grammar.NumTerminals); BitVectorSet reduceAccumulator = new BitVectorSet(grammar.NumTerminals); foreach (Transition trans in state.Transitions) { if (trans is TerminalTransition) { accumulator.Add(trans.TransitionSymbol); } } bool conflictsInThisState = false; foreach (BitVectorSet lookaheadSet in lookaheadSets[stateLookaheadIndex[state.StateNumber]]) { if (!reduceAccumulator.IsDisjointWith(lookaheadSet)) { conflictsInThisState = true; reduceReduceConflictsInAutomaton = true; break; } else { if (!accumulator.IsDisjointWith(lookaheadSet)) { conflictsInThisState = true; } reduceAccumulator.UnionWith(lookaheadSet); } } if (conflictsInThisState) { conflictsInAutomaton = true; } else { numInconsistentStates--; stateResolvedAt[state.StateNumber] = lastStage; } } } return(conflictsInAutomaton); }
//projde všechny dosud nevyřešené stavy a podívá se, jestli byla minulá fáze výpočtu dostatečná //na to, aby rozřešila konflikty, které se v nich objevují; parametr lastStage popisuje, jak vypadala //poslední fáze výpočtu a můžeme tak pro diagnostické důvody sledovat, které stavy jsou vyřešeny //v kterém stádiu výpočtu private bool checkForConflicts(LookaheadComplexity lastStage) { bool conflictsInAutomaton = false; foreach (State state in parserStates) { if (stateResolvedAt[state.StateNumber] == LookaheadComplexity.Unresolved) { BitVectorSet accumulator = new BitVectorSet(grammar.NumTerminals); //inicializujeme akumulační proměnnou na množinu terminálů, které v daném stavu můžeme přečíst foreach (Transition trans in state.Transitions) { if (trans is TerminalTransition) { accumulator.Add(trans.TransitionSymbol); } } bool conflictsInThisState = false; //akumulační proměnná prochází kolem všech lookahead množin a testuje se s nimi na disjunktnost, //sama potom přebírá jejich prvky (nemusíme tak testovat každou dvojici množin) foreach (BitVectorSet lookaheadSet in lookaheadSets[stateLookaheadIndex[state.StateNumber]]) { if (!accumulator.IsDisjointWith(lookaheadSet)) { conflictsInThisState = true; break; } else { accumulator.UnionWith(lookaheadSet); } } if (conflictsInThisState) { conflictsInAutomaton = true; } else { numInconsistentStates--; stateResolvedAt[state.StateNumber] = lastStage; } } } return(conflictsInAutomaton); }