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; } } }
public Gss <T> CloneWithoutData() { var newFront = new GssNode <T> [front.Length]; front.CopyTo(newFront, 0); return(new Gss <T>(currentLayer, newFront, Count)); }
private GssNode <T> AddTopmost(State state, int lookahead = -1) { var result = new GssNode <T>(state, currentLayer, currentStage, lookahead); front[Count++] = result; return(result); }
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); }
public GssReducePath(GssNode <T> leftNode, GssLink <T>[] links, Production rule, int size) { this.LeftNode = leftNode; this.Links = links; this.Rule = rule; this.Size = size; }
public GssLink <T> AddLink(GssNode <T> leftNode, T label) { var result = new GssLink <T>(leftNode, label, firstLink); firstLink = result; return(result); }
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); } }
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>)); }
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; } } }
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); }
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)); }
private static string StateName(GssNode <T> node) { return(string.Format("{0}:{1}", node.State, node.Stage)); }
public PendingShift(GssNode <T> frontNode, State toState, int token) { this.FrontNode = frontNode; this.ToState = toState; this.Token = token; }
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); } } } } } }
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)); } } }