private void ReduceViaPath(GssReducePath path, Msg item)
        {
            int          N       = path.Rule.Left;
            GssStateNode leftSib = path.LeftmostStateNode;
            State        k       = leftSib.State;

            // TODO: Apply 'Duplicate' to all path semantic values
            Msg newItem  = InvokeReduceAction(path, item);
            int newState = NonTermGoTo(k, N);
            var rightSib = gss.FindTopmost(newState);

            if (rightSib != null)
            {
                var link = gss.GetLink(rightSib, leftSib);
                if (link != null)
                {
                    link.Item = MergeValues(newState, link.Item, newItem);
                }
                else
                {
                    link = gss.AddLink(rightSib, leftSib, newItem);
                    EnqueueLimitedReductions(item.Id, link);
                }
            }
            else
            {
                rightSib = gss.AddTopmost(newState);
                var link = gss.AddLink(rightSib, leftSib, newItem);
                EnqueueLimitedReductions(item.Id, link);
            }
        }
        public ElkhoundGlrParser(
            object context,
            BnfGrammar grammar,
            TransitionDelegate transition,
            GrammarActionDelegate grammarAction,
            int[]                 stateToPriorToken,
            int[]                   conflictActionsTable,
            Func <object, int, IReciever <Msg>, IReciever <Msg> > makeSwitch)
        {
            this.context              = context;
            this.grammar              = grammar;
            this.grammarAction        = grammarAction;
            this.transition           = transition;
            this.stateToPriorToken    = stateToPriorToken;
            this.conflictActionsTable = conflictActionsTable;
            this.gss = new Gss();

            gss.AddTopmost(0);
        }