예제 #1
0
        private void Initialize()
        {
            // for all (S ::= α) ∈ P {
            foreach (var production in _grammar.ProductionsFrom(_grammar.Start))
            {
                var α0            = production.Rhs.FirstOrDefault();
                var potentialItem = new EarleyItem(new DecoratedProduction(production, 0), 0, null);

                // if α ∈ Σ_N, add (S ::= · α, 0, null) to E_0
                if (PrefixInSigma(α0))
                {
                    _E[0].Add(potentialItem);
                }
                // if α = a_0 α′, add (S ::= · α, 0, null) to Q′
                else
                {
                    if (_a.Count > 0)
                    {
                        var a1 = _a.First();
                        if (α0 == a1)
                        {
                            _QPrime.Add(potentialItem);
                        }
                    }
                }
            }
        }
예제 #2
0
        private void ProcessQ(int i)
        {
            if (i < _a.Count)
            {
                // create an SPPF node v labelled(a_i, i, i + 1)
                var v2 = new SppfWord(_a[i], i, i + 1);

                // while Q ̸= ∅ {
                while (!_Q.IsEmpty)
                {
                    // remove an element, Λ = (B ::= α · a_i β, h, w) say, from Q
                    var Λ = _Q.TakeOne();
                    if (Λ.DecoratedProduction.NextWord != _a[i])
                    {
                        throw new Exception();
                        // continue;
                    }
                    var h  = Λ.StartPosition;
                    var w  = Λ.SppfNode;
                    var β0 = Λ.DecoratedProduction.TailFirst;

                    // let y = MAKE NODE(B ::= α a_i · β, h, i + 1, w, v, V)
                    var productionAdvanced = Λ.DecoratedProduction.Increment();
                    var y = MakeNode(productionAdvanced, h, i + 1, w, v2);

                    var newItem = new EarleyItem(productionAdvanced, h, y);
                    // if β ∈ Σ_N { add (B ::= α a_i · β, h, y) to E_i+1 }
                    if (PrefixInSigma(β0))
                    {
                        _E[i + 1].Add(newItem);
                    }

                    // if β = a_i+1 β′ { add (B ::= α a_i · β, h, y) to Q′ }
                    else
                    {
                        if (i + 1 < _a.Count)
                        {
                            var aNext = _a[i + 1];
                            if (β0 == aNext)
                            {
                                _QPrime.Add(newItem);
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        private bool GatherExcludes(EarleyItem parent, EarleyItem child)
        {
            var parentProduction = parent.DecoratedProduction.Production;
            var parentGathers    = parentProduction.Annotations.Gather;

            if (parentGathers == null)
            {
                return(false);
            }
            var parentPrecedence = parentProduction.Annotations.Precedence;

            if (parentPrecedence == null)
            {
                return(false);
            }
            var childPrecedence = child.DecoratedProduction.Production.Annotations.Precedence;

            if (childPrecedence == null)
            {
                return(false);
            }
            // S + * S [* is at 2]
            //var subSentence = parent.DecoratedProduction.Production.Rhs.Take(parent.DecoratedProduction.CurrentPosition);
            //var numNonterminals = subSentence.Count(word => word.IsNonterminal);
            var numNonterminals = parentProduction.NumNonterminalsBefore(parent.DecoratedProduction.CurrentPosition);
            var parentGather    = parentGathers.Value[numNonterminals];

            switch (parentGather)
            {
            case GatherOption.SameOrLower:
                if (childPrecedence.Value > parentPrecedence.Value)
                {
                    return(true);
                }
                break;

            case GatherOption.StrictlyLower:
                if (childPrecedence.Value >= parentPrecedence.Value)
                {
                    return(true);
                }
                break;
            }

            return(false);
        }
예제 #4
0
        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);
                    }
                }
            }
        }
예제 #5
0
        // 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);
            }
        }
예제 #6
0
        // 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);
                        }
                    }
                }
            }
        }