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); }
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; }
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); }
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); }