public void Enqueue(GssNode <T> rightNode, Production rule, int size)
        {
            if (size == 0)
            {
                reductions.Enqueue(
                    new Reduction <T>(
                        rightNode,
                        rule,
                        0,
                        -1,
                        null));
            }
            else
            {
                var link = rightNode.FirstLink;
                while (link != null)
                {
                    reductions.Enqueue(
                        new Reduction <T>(
                            link.LeftNode,
                            rule,
                            size,
                            -1,
                            link));

                    link = link.NextLink;
                }
            }
        }
Exemple #2
0
        public Gss <T> CloneWithoutData()
        {
            var newFront = new GssNode <T> [front.Length];

            front.CopyTo(newFront, 0);
            return(new Gss <T>(currentLayer, newFront, Count));
        }
Exemple #3
0
        private GssNode <T> AddTopmost(State state, int lookahead = -1)
        {
            var result = new GssNode <T>(state, currentLayer, currentStage, lookahead);

            front[Count++] = result;
            return(result);
        }
Exemple #4
0
        public GssLink <T> Push(GssNode <T> leftNode, int rightState, T label, int lookahead = -1)
        {
            GssNode <T> rightmostNode = GetFrontNode(rightState, lookahead) ?? AddTopmost(rightState, lookahead);

            var link = GetLink(rightmostNode, leftNode);

            if (link != null)
            {
                // Side-effect! How to undo it before the error recovery?
                link.AssignLabel(label);
                return(null);
            }

            var result = rightmostNode.AddLink(leftNode, label);

            if (result.NextLink != null)
            {
                rightmostNode.DeterministicDepth = 0;
                UpdateDeterministicDepths();
            }
            else
            {
                rightmostNode.DeterministicDepth = leftNode.DeterministicDepth + 1;
            }

            return(result);
        }
Exemple #5
0
 public GssReducePath(GssNode <T> leftNode, GssLink <T>[] links, Production rule, int size)
 {
     this.LeftNode = leftNode;
     this.Links    = links;
     this.Rule     = rule;
     this.Size     = size;
 }
Exemple #6
0
        public GssLink <T> AddLink(GssNode <T> leftNode, T label)
        {
            var result = new GssLink <T>(leftNode, label, firstLink);

            firstLink = result;
            return(result);
        }
Exemple #7
0
 public Reduction(GssNode <T> rightNode, Production rule, int size, int epsilonIndex, GssLink <T> rightLink)
 {
     this.Rule         = rule;
     this.RightNode    = rightNode;
     this.Token        = rule.OutcomeToken;
     this.Size         = size;
     this.EpsilonIndex = epsilonIndex;
     this.RightLink    = rightLink;
 }
        private void PlanShiftReduce(GssNode <T> frontNode, int shiftToken, T shiftValue, int rule, int size)
        {
            int fakeState = MakeFakeDestState(frontNode.State, shiftToken);

            var newLink = gss.Push(frontNode, fakeState, shiftValue);

            if (newLink != null)
            {
                R.Enqueue(newLink, grammar.Productions[rule], size);
            }
        }
Exemple #9
0
        private static GssLink <T> GetLink(GssNode <T> fromNode, GssNode <T> toNode)
        {
            var link = fromNode.FirstLink;

            while (link != null)
            {
                if (link.LeftNode == toNode)
                {
                    return(link);
                }

                link = link.NextLink;
            }

            return(default(GssLink <T>));
        }
Exemple #10
0
        public void Enqueue(GssNode <T> rightNode, Production rule, int size)
        {
            if (size == 0)
            {
                GssReducePath <T> .GetAll(rightNode, 0, 0, rule, null, InternalEnqueue);
            }
            else
            {
                var link = rightNode.FirstLink;

                while (link != null)
                {
                    Enqueue(link, rule, size);

                    link = link.NextLink;
                }
            }
        }
Exemple #11
0
        T IStackLookback <T> .GetValueAt(int count)
        {
            GssNode <T> node = this;

            Debug.Assert(count > 0, "Lookback should be at least 1 token back");
            Debug.Assert(node.DeterministicDepth >= count, "Non-deterministic lookback.");

            GssLink <T> lastLink = null;
            GssNode <T> lastNode = null;

            do
            {
                lastNode = node;
                lastLink = node.FirstLink;
                node     = lastLink.LeftNode;
            }while (--count != 0);

            return(lastLink.Label);
        }
Exemple #12
0
        public static Msg GssLookback(object glrLookback, int count)
        {
            GssNode <Msg> node = (GssNode <Msg>)glrLookback;

            Debug.Assert(count > 0, "Lookback should be at least 1 token back");
            Debug.Assert(node.DeterministicDepth >= count, "Non-deterministic lookback.");

            GssLink <Msg> lastLink = null;
            GssNode <Msg> lastNode = null;

            do
            {
                lastNode = node;
                lastLink = node.FirstLink;
                node     = lastLink.LeftNode;
            }while (--count != 0);

            // Make new Msg to replace token Id with state Id
            return(new Msg(lastNode.State, lastLink.Label.Value, lastLink.Label.Location));
        }
Exemple #13
0
 private static string StateName(GssNode <T> node)
 {
     return(string.Format("{0}:{1}", node.State, node.Stage));
 }
Exemple #14
0
 public PendingShift(GssNode <T> frontNode, State toState, int token)
 {
     this.FrontNode = frontNode;
     this.ToState   = toState;
     this.Token     = token;
 }
Exemple #15
0
        private void Reducer(int lookahead = -1)
        {
            while (!R.IsEmpty)
            {
                GssReducePath <T> path = R.Dequeue();

                int X = path.Rule.OutcomeToken;
                int m = path.Size;

                GssNode <T> u = path.LeftNode;
                State       k = u.State;
                T           z;
                if (m == 0)
                {
                    z = producer.GetDefault(X, (IStackLookback <T>)u);
                }
                else
                {
                    path.CopyDataTo(nodeBuffer);
                    T Λ = producer.CreateBranch(
                        path.Rule,
                        new ArraySlice <T>(nodeBuffer, 0, path.Size),
                        lookback: path.LeftNode);

                    int c = u.Layer;
                    T   currentValue;
                    var Nkey = GetNKey(X, c);
                    if (N.TryGetValue(Nkey, out currentValue))
                    {
                        z = producer.Merge(currentValue, Λ, (IStackLookback <T>)u);
                    }
                    else
                    {
                        z = Λ;
                    }

                    N[Nkey] = z;
                }

                State l;

                var action = ParserAction.Decode(transition(k, X));
                switch (action.Kind)
                {
                case ParserActionKind.Shift:
                    l = action.State;
                    break;

                case ParserActionKind.ShiftReduce:     // Goto-Reduce action
                    PlanShiftReduce(
                        u,
                        X,
                        z,
                        action.ProductionId,
                        action.Size);
                    continue;

                default:
                    throw new InvalidOperationException(
                              "Internal error: Non-term action should be shift or shift-reduce, but got "
                              + Enum.GetName(typeof(ParserActionKind), action.Kind));
                }

                bool stateAlreadyExists = gss.GetFrontNode(l, lookahead) != null;

                // Goto on non-term produced by rule.
                var newLink = gss.Push(u, l, z, lookahead);

                if (lookahead < 0)
                {
                    continue;
                }

                if (stateAlreadyExists)
                {
                    if (newLink != null && m != 0)
                    {
                        GetReductions(l, lookahead);
                        for (int i = 0; i != pendingReductionsCount; ++i)
                        {
                            var red = pendingReductions[i];
                            if (red.Size != 0)
                            {
                                R.Enqueue(newLink, red.Rule, red.Size);
                            }
                        }
                    }
                }
                else
                {
                    var w = gss.GetFrontNode(l, lookahead);

                    GetReductions(l, lookahead);
                    //foreach (var red in reductions)
                    for (int i = 0; i != pendingReductionsCount; ++i)
                    {
                        var red = pendingReductions[i];
                        if (red.Size == 0)
                        {
                            R.Enqueue(w, red.Rule, 0);
                        }
                    }

                    if (m != 0)
                    {
                        for (int i = 0; i != pendingReductionsCount; ++i)
                        {
                            var red = pendingReductions[i];
                            if (red.Size != 0)
                            {
                                R.Enqueue(newLink, red.Rule, red.Size);
                            }
                        }
                    }
                }
            }
        }
Exemple #16
0
        public static void GetAll(
            GssNode <T> rightNode,
            int size,
            int tail,
            Production rule,
            GssLink <T> rightLink,
            Action <GssReducePath <T> > action0)
        {
            Action <GssReducePath <T> > action;

            if (tail == 0)
            {
                action = action0;
            }
            else
            {
                action = path =>
                {
                    path.Links[size] = rightLink;
                    action0(path);
                };
            }

            int fullSize = size + tail;

            if (size == 0)
            {
                action(new GssReducePath <T>(rightNode, new GssLink <T> [tail], rule, fullSize));
            }
            else if (size <= rightNode.DeterministicDepth)
            {
                var links = new GssLink <T> [fullSize];

                GssNode <T> node = rightNode;
                int         i    = size;
                while (i-- != 0)
                {
                    var link = node.FirstLink;
                    links[i] = link;

                    node = link.LeftNode;
                }

                action(new GssReducePath <T>(node, links, rule, fullSize));
            }
            else
            {
                // TODO: Get rid of front. 'front link' is frontPaths[j][k]
                var front      = new List <GssLink <T> >(2);
                var frontPaths = new List <GssLink <T>[]>(rightNode.LinkCount);

                var frontLink = rightNode.FirstLink;
                while (frontLink != null)
                {
                    front.Add(frontLink);
                    frontPaths.Add(new GssLink <T> [fullSize]);

                    frontLink = frontLink.NextLink;
                }

                int k = size;
                while (0 != k--)
                {
                    int frontCount = front.Count;
                    for (int j = 0; j != frontCount; ++j)
                    {
                        var currLink = front[j];
                        frontPaths[j][k] = currLink;

                        if (k != 0)
                        {
                            front[j] = currLink.LeftNode.FirstLink;
                            var link = front[j].NextLink;

                            while (link != null)
                            {
                                front.Add(link);
                                var newPathLinks = (GssLink <T>[])frontPaths[j].Clone();
                                frontPaths.Add(newPathLinks);

                                link = link.NextLink;
                            }
                        }
                    }
                }

                int count = front.Count;
                for (int i = 0; i != count; ++i)
                {
                    action(new GssReducePath <T>(front[i].LeftNode, frontPaths[i], rule, fullSize));
                }
            }
        }