public void AddItem(LR0Item core) { //Check if a core had been already added. If yes, simply return if (!_allCores.Add(core)) { return; } //Create new item, add it to AllItems, InitialItems, ReduceItems or ShiftItems var item = new LRItem(_state, core); AllItems.Add(item); if (item.Core.IsFinal) { ReduceItems.Add(item); } else { ShiftItems.Add(item); } if (item.Core.IsInitial) { InitialItems.Add(item); } if (core.IsFinal) { return; } //Add current term to ShiftTerms if (!ShiftTerms.Add(core.Current)) { return; } if (core.Current is Terminal) { ShiftTerminals.Add(core.Current as Terminal); } //If current term (core.Current) is a new non-terminal, expand it var currNt = core.Current as NonTerminal; if (currNt == null) { return; } foreach (var prod in currNt.Productions) { AddItem(prod.LR0Items[0]); } }
private Production CreateProduction(NonTerminal lvalue, BnfTermList operands) { var prod = new Production(lvalue); GrammarHintList hints = null; //create RValues list skipping Empty terminal and collecting grammar hints foreach (var operand in operands) { if (operand == _grammar.Empty) { continue; } //Collect hints as we go - they will be added to the next non-hint element if (operand is GrammarHint hint) { if (hints == null) { hints = new GrammarHintList(); } hints.Add(hint); continue; } //Add the operand and create LR0 Item prod.RValues.Add(operand); var lr0 = new LR0Item(_lastItemId++, prod, prod.RValues.Count - 1, hints); prod.LR0Items.Add(lr0); hints = null; } //set the flags if (prod.RValues.Count == 0) { prod.Flags |= ProductionFlags.IsEmpty; } //Add final LRItem ComputeProductionFlags(prod); prod.LR0Items.Add(new LR0Item(_lastItemId++, prod, prod.RValues.Count, hints)); return(prod); }
public LRItem FindByCore(LR0Item core) { return(this.FirstOrDefault(item => item.Core == core)); }