// 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);
            }
        }
Example #2
0
 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);
                        }
                    }
                }
            }
        }