private int PrepareCurrent() { int token; this.currentPosition += (cursor.Marker - cursor.Start); this.hLocation = MakeHLoc(); this.location = new Loc(document, priorPosition, currentPosition); object tokenValue; this.skipCurrentToken = false; // TODO: // 1) cursor.Action -> list of real actions. for each real action create MsgData // 2) in build time ensure that within one state // actions cannot produce same token // 3) each action can produce multiple tokens (optional by now, but in future can be useful) cursor.CurrentActionId = cursor.Actions[0]; token = termFactory(cursor, out tokenValue); if (token >= 0 && !skipCurrentToken) { int id = cursor.EnvelopeId; // TODO: Amb & Main tokens for envelope.Id Current = new Msg(id, token, tokenValue, location, hLocation); // Shrodinger's token if (cursor.ActionCount > 1) { MsgData data = Current; for (int i = 1; i != cursor.ActionCount; ++i) { cursor.CurrentActionId = cursor.Actions[i]; this.skipCurrentToken = false; token = termFactory(cursor, out tokenValue); if (!skipCurrentToken) { data.Next = new MsgData(token, tokenValue); data = data.Next; } } } } else { token = -1; } return(token); }
public Msg CreateLeaf(Msg envelope, MsgData data) { return(data == (object)envelope ? envelope : new Msg(envelope.Id, data.Token, data.Value, envelope.Location, envelope.HLocation)); }
public SppfNode CreateLeaf(Msg envelope, MsgData data) { return(new SppfNode(data.Token, data.Value, envelope.Location, envelope.HLocation)); }
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 T CreateLeaf(Msg envelope, MsgData msg) { return(default(T)); }
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); }