// if Λ = (D ::= α·, h, w) { private void Complete(int i, Dictionary <Nonterminal, SppfNode> H, EarleySet R, EarleyItem Λ) { var D = Λ.DecoratedProduction.Production.Lhs; var w = Λ.SppfNode; var h = Λ.StartPosition; // if w = null { if (w == null) { // if there is no node v ∈ V labelled (D, i, i) create one var v = _V.GetOrSet(D, i, i); // set w = v w = v; Λ.SppfNode = v; // if w does not have family (ϵ) add one w.AddFamily(Λ.DecoratedProduction.Production, new SppfEpsilon(i, i)); } // if h = i { add (D, w) to H } if (h == i) { if (H.TryGetValue(D, out var oldw)) { if (w != oldw) { throw new Exception("Different D, w in H"); } } else { H[D] = w; } } var eh = _E[h]; // for all (A ::= τ · Dδ, k, z) in E_h { //var count = eh.Count; // TODO: notice this doesn't run on items added to eh during the loop, not sure if this is right //for (var itemi = 0; itemi < count; itemi++) { // var item = eh[itemi]; // if (item.DecoratedProduction.NextWord != D) { // continue; // } // LinkCompletedChildWithParent(V, i, item, Λ, R, Q, w); //} var list = eh.ItemsAtNonterminal(D); if (list == null) { return; } var count = list.Count; for (var listi = 0; listi < count; listi++) { var item = list[listi]; LinkCompletedChildWithParent(i, item, Λ, R, w); } }
public EarleySet(EarleySet earleySet) { foreach (var item in earleySet._items) { this.Add(item); } }
public EarleyParser2Helper(BaseGrammar grammar, Sentence a) { _grammar = grammar; _a = a; // SppfNode._nextId = 0; // TODO can't be thread safe // E_0, ..., E_n, R, Q′, V = ∅ _E = new EarleySet[a.Count + 1]; for (var i = 0; i < _E.Length; i++) { _E[i] = new EarleySet(); } _V = new SppfNodeDictionary(_E.Length); }
private void MainLoop() { // for 0 ≤ i ≤ n { for (var i = 0; i < _E.Length; i++) { // H = ∅, R = E_i , Q = Q ′ var H = new Dictionary <Nonterminal, SppfNode>(); var R = new EarleySet(_E[i]); _Q = _QPrime; // Q′ = ∅ _QPrime = new EarleySet(); ProcessR(i, H, R); _V.Clear(i); // _V = new SppfNodeDictionary(i + 1); ProcessQ(i); } }
private void ProcessR(int i, Dictionary <Nonterminal, SppfNode> H, EarleySet R) { // while R ̸= ∅ { while (!R.IsEmpty) { // remove an element, Λ say, from R var Λ = R.TakeOne(); var nextWord = Λ.DecoratedProduction.NextWord; // if Λ = (B ::= α · Cβ, h, w) { if (nextWord is Nonterminal C) { Predict(i, H, R, Λ, C); } // if Λ = (D ::= α·, h, w) { else if (nextWord == null) { Complete(i, H, R, Λ); } else { throw new Exception("Didn't expect a terminal"); } } }
private void LinkCompletedChildWithParent(int i, EarleyItem parent, EarleyItem child, EarleySet R, SppfNode w) { var k = parent.StartPosition; var z = parent.SppfNode; // var δ = item.Tail; var δ0 = parent.DecoratedProduction.TailFirst; // Λ is child, item is parent var gatherExcludes = GatherExcludes(parent, child); if (gatherExcludes) { return; } // let y = MAKE NODE(A ::= τD · δ, k, i, z, w, V) var productionAdvanced = parent.DecoratedProduction.Increment(); var y = MakeNode(productionAdvanced, k, i, z, w); var newItem = new EarleyItem(productionAdvanced, k, y); // if δ ∈ Σ_N and (A ::= τD · δ, k, y) ̸∈ E_i { if (PrefixInSigma(δ0)) { // add (A ::= τD · δ, k, y) to E_i and R if (_E[i].Add(newItem)) { R.Add(newItem); } } else { // if δ = a_i δ′ { add (A ::= τD · δ, k, y) to Q } } if (i < _a.Count) { var aCurr = _a[i]; if (δ0 == aCurr) { _Q.Add(newItem); } } } }
// if Λ = (B ::= α · Cβ, h, w) { private void Predict(int i, Dictionary <Nonterminal, SppfNode> H, EarleySet R, EarleyItem Λ, Nonterminal C) { //var β = Λ.Tail; var w = Λ.SppfNode; var h = Λ.StartPosition; var β0 = Λ.DecoratedProduction.TailFirst; // for all (C ::= δ) ∈ P { foreach (var production in _grammar.ProductionsFrom(C)) { // if δ ∈ Σ_N and (C ::= ·δ, i, null) ̸∈ E_i { var δ0 = production.Rhs.FirstOrDefault(); var newItem = new EarleyItem(new DecoratedProduction(production, 0), i, null); if (PrefixInSigma(δ0)) { // add (C ::= ·δ, i, null) to E_i and R } if (_E[i].Add(newItem)) { R.Add(newItem); } } else { // if δ = a_i δ′ { add (C ::= · δ, i, null) to Q } if (i < _a.Count) { var aCurr = _a[i]; if (δ0 == aCurr) { _Q.Add(newItem); } } } } // if ((C, v) ∈ H) { if (H.TryGetValue(C, out SppfNode v)) { // let y = MAKE_NODE(B ::= αC · β, h, i, w, v, V) var productionAdvanced = Λ.DecoratedProduction.Increment(); var y = MakeNode(productionAdvanced, h, i, w, v); var newItem = new EarleyItem(productionAdvanced, h, y); // if β ∈ Σ N and (B ::= αC · β, h, y) ̸∈ E_i { if (PrefixInSigma(β0)) { // add(B::= αC · β, h, y) to E_i and R } if (_E[i].Add(newItem)) { R.Add(newItem); } } else { // if β = a_i β′ { add (B ::= αC · β, h, y) to Q } } } if (i < _a.Count) { var aCurr = _a[i]; if (β0 == aCurr) { _Q.Add(newItem); } } } } }