private string FormatToken(RuntimeGrammar grammar, Msg msg)
        {
            if (msg.Id == PredefinedTokens.Eoi)
            {
                return("end of file");
            }

            string result = grammar.SymbolName(msg.Id);

            if (!result.StartsWith("'") && msg.Value != null)
            {
                result = msg.Value.ToString();
            }

            return(result);
        }
示例#2
0
        private object DefaultMerge(
            int                 token,
            object              alt1,
            object              alt2,
            object              context,
            IStackLookback<Msg> stackLookback)
        {
            var result = alt2;
#if true
            Debug.WriteLine("------------------------------");
            Debug.WriteLine(
                "Default merging of token {0} values in state {1}:",
                (object)runtimeGrammar.SymbolName(token),
                stackLookback.GetParentState());
            Debug.WriteLine("  '{0}'", alt1);
            Debug.WriteLine(" and");
            Debug.WriteLine("  '{0}'", alt2);
            Debug.WriteLine(" into the value: '{0}'", (object)result);
#endif
            return result;
        }
示例#3
0
        public void WriteGraph(IGraphView view, RuntimeGrammar grammar, int[] stateToSymbol)
        {
            var allAccessibleByLayer = GetAllNodes().GroupBy(state => state.Layer);

            var layers = Enumerable
                         .Range(0, currentLayer + 1)
                         .Select(i => new List <GssNode <T> >(2))
                         .ToList();

            foreach (var group in allAccessibleByLayer)
            {
                layers[group.Key].AddRange(group);
            }

            view.BeginDigraph("Gss");

            view.SetGraphProperties(rankDir: RankDir.RightToLeft);

            for (int layerIndex = 0; layerIndex != layers.Count; ++layerIndex)
            {
                var layer = layers[layerIndex];
                view.BeginCluster(layerIndex.ToString());

                view.SetGraphProperties(style: Style.Dotted, label: "U" + layerIndex);
                view.SetNodeProperties(shape: Shape.Circle);

                for (int nodeIndex = 0; nodeIndex != layer.Count; ++nodeIndex)
                {
                    view.AddNode(
                        Tuple.Create("s", layerIndex, nodeIndex),
                        label: StateName(layer[nodeIndex]));
                }

                view.EndCluster();
            }

            view.SetNodeProperties(shape: Shape.Rect);

            int linkIndex = 0;

            for (int layerIndex = 0; layerIndex != layers.Count; ++layerIndex)
            {
                var layer = layers[layerIndex];
                for (int nodeIndex = 0; nodeIndex != layer.Count; ++nodeIndex)
                {
                    var from = layer[nodeIndex];
                    if (from.State < 0)
                    {
                        continue;
                    }

                    int token = stateToSymbol[from.State];
                    var link  = from.FirstLink;
                    while (link != null)
                    {
                        var to = link.LeftNode;

                        view.AddNode(Tuple.Create("t", linkIndex), grammar.SymbolName(token));

                        view.AddEdge(
                            Tuple.Create("s", layerIndex, nodeIndex),
                            Tuple.Create("t", linkIndex)
                            );

                        view.AddEdge(
                            Tuple.Create("t", linkIndex),
                            Tuple.Create("s", to.Layer, layers[to.Layer].IndexOf(to))
                            );

                        ++linkIndex;

                        link = link.NextLink;
                    }
                }
            }

            view.EndDigraph();
        }
        public IReceiver <Msg> Next(Msg envelope)
        {
            stateStack.BeginEdit();

            int     id   = envelope.Id;
            MsgData data = envelope.FirstData;

START:
            ParserAction action = LookaheadAction(id);

            switch (action.Kind)
            {
            case ParserActionKind.Fail:
                if (isVerifier)
                {
                    return(null);
                }

                // ReportUnexpectedToken(msg, stateStack.PeekTag());
                return(RecoverFromError(envelope));

            case ParserActionKind.Resolve:
                id = action.RolvedToken;
                while (true)
                {
                    if (data.Token == id)
                    {
                        // Successfully resolved to a particular token
                        goto START;
                    }

                    data = data.Next;
                    if (data == null)
                    {
                        // Desired token was not present in Msg
                        goto case ParserActionKind.Fail;
                    }
                }

            case ParserActionKind.Fork:
            case ParserActionKind.Conflict:
                logging.Write(
                    new LogEntry
                {
                    Severity  = Severity.Error,
                    Location  = envelope.Location,
                    HLocation = envelope.HLocation,
                    Message   = "Hit parser conflict on token " + grammar.SymbolName(envelope.Id)
                });
                return(null);

            case ParserActionKind.Shift:
            {
                stateStack.Push(action.State, producer.CreateLeaf(envelope, data));
                break;
            }

            case ParserActionKind.ShiftReduce:
            {
                TNode value = producer.CreateLeaf(envelope, data);
                do
                {
                    stateStack.Push(-1, value);
                    this.currentRule = grammar.Productions[action.ProductionId];
                    stateStack.Start = stateStack.Count - currentRule.PatternTokens.Length;
                    value            = producer.CreateBranch(
                        currentRule,
                        stateStack.PeekTail(currentRule.PatternTokens.Length),
                        (IStackLookback <TNode>)stateStack);
                    stateStack.Pop(currentRule.PatternTokens.Length);
                    action = ParserAction.Decode(actionTable(stateStack.PeekTag(), currentRule.OutcomeToken));
                }while (action.Kind == ParserActionKind.ShiftReduce);

                if (action.Kind == ParserActionKind.Fail)
                {
                    return(null);
                }

                Debug.Assert(action.Kind == ParserActionKind.Shift);
                stateStack.Push(action.State, value);
                break;
            }

            case ParserActionKind.Accept:
                producer.Result = stateStack.Peek();
                return(FinalReceiver <Msg> .Instance);

            default:
                throw new InvalidOperationException("Internal error: Unsupported parser action");
            }

            stateStack.EndEdit();
            this.priorInput = envelope;
            return(this);
        }
示例#5
0
        public IReceiver <Msg> Next(Msg envelope)
        {
            gss.BeginEdit();

            N.Clear();

            var     front = gss.FrontArray;
            MsgData data  = envelope.FirstData;

            do
            {
                int lookahead = data.Token;

                Actor(lookahead);
                Reducer(lookahead);

                if (accepted)
                {
                    int count = gss.Count;
                    for (int i = 0; i != count; ++i)
                    {
                        var node = front[i];
                        if (IsAccepting(node.State))
                        {
                            producer.Result = node.FirstLink.Label;
                            break;
                        }
                    }
                }

                var termValue = producer.CreateLeaf(envelope, data);
                N[GetNKey(lookahead, gss.CurrentLayer + 1)] = termValue;

                for (int i = 0; i != gss.Count; ++i)
                {
                    var frontNode = front[i];

                    // Plan shift
                    var shift = GetShift(frontNode.State, lookahead);
                    if (shift >= 0)
                    {
                        Q.Enqueue(new PendingShift(frontNode, shift, lookahead));
                    }

                    // Shift and plan reduce
                    var action = GetShiftReduce(frontNode.State, lookahead);
                    if (action.Kind == ParserActionKind.ShiftReduce)
                    {
                        PlanShiftReduce(
                            frontNode,
                            lookahead,
                            termValue,
                            action.ProductionId,
                            action.Size);
                    }
                }

                data = data.Next;
            }while (data != null);

            gss.PushLayer();
            Shifter();

            // Run reducer again to complete
            // shift-reduce and goto-reduce actions.
            Reducer();

#if DIAGNOSTICS
            if (!isVerifier)
            {
                using (var graphView = new GvGraphView("GlrState" + gss.CurrentLayer + ".gv"))
                {
                    gss.WriteGraph(graphView, grammar, stateToPriorToken);
                }
            }
#endif

            if (gss.IsEmpty)
            {
                if (accepted)
                {
                    return(FinalReceiver <Msg> .Instance);
                }

                if (isVerifier)
                {
                    return(null);
                }

                gss.Undo(0); // restore state before the current input token

                {
                    var message = new StringBuilder();
                    message
                    .Append("Unexpected token ")
                    .Append(grammar.SymbolName(envelope.Id))
                    .Append(" in state stacks: {");
                    bool firstStack = true;
                    for (int i = 0; i != gss.Count; ++i)
                    {
                        var node = gss.FrontArray[i];

                        if (firstStack)
                        {
                            firstStack = false;
                        }
                        else
                        {
                            message.Append(", ");
                        }



                        message.Append("[");
                        var  n          = node;
                        bool firstState = true;
                        while (true)
                        {
                            if (firstState)
                            {
                                firstState = false;
                            }
                            else
                            {
                                message.Append(", ");
                            }

                            message.Append(n.State);
                            if (n.State == 0)
                            {
                                break;
                            }

                            n = n.FirstLink.LeftNode;
                        }

                        message.Append("]");
                    }

                    message.Append("}");

                    logging.Write(
                        new LogEntry
                    {
                        Severity  = Severity.Verbose,
                        Location  = envelope.Location,
                        HLocation = envelope.HLocation,
                        Message   = message.ToString()
                    });
                }

                return(RecoverFromError(envelope));
            }

            gss.EndEdit();
            this.priorInput = envelope;
            return(this);
        }