/// <summary> /// Honalee algorithm /// </summary> /// <param name="state"></param> /// <param name="actionBuilder"></param> /// <param name="queue"></param> private void Goto(State state, ActionBuilder actionBuilder, Queue <State> queue) { foreach (var symbol in state.NextSymbols()) { var newState = new State(States.Count, symbol); foreach (var item in state.Where(x => x.IsSymbol(symbol))) { newState.Add(item.Production, item.Position + 1, item.Lookahead); } if (newState.Count > 0) { if (!States.TryGetId(newState, out var stateId)) { States.Add(newState); newState.Closure(grammar); queue.Enqueue(newState); stateId = newState.Index; } actionBuilder.AddGoto(state.Index, symbol.Id, stateId); //For debug purposes, we'll record the transition it the item foreach (var item in state.Where(x => x.IsSymbol(symbol))) { item.SetGoto(stateId); } } } foreach (var item in state.Where(x => x.AtEnd)) { actionBuilder.AddReduce(state.Index, item.Lookahead.Id, item.Production.Id); } }
public LR1Parser(ILogger logger, Grammar grammar, ConflictList conflicts) { this.grammar = grammar; var endSymbol = grammar.Symbols[0]; //Honalee Algorithm //Create kernel item from augmented gramar production var kernel = new LR1Item(grammar[0], 0, endSymbol); var startState = new State(0) { kernel }; States = new States { startState }; startState.Closure(this.grammar); var queue = new Queue <State>(); queue.Enqueue(startState); var actionBuilder = new ActionBuilder(this.grammar); //Method2 while (queue.Count > 0) { startState = queue.Dequeue(); Goto(startState, actionBuilder, queue); } var resolver = new ConflictResolvers(conflicts, grammar.Symbols, logger); Actions = actionBuilder.Build(logger, States, this.grammar.Symbols, resolver); }