private LookAheadSet FindLookAhead(ProductionPatternAlternative alt, int length, int pos, CallStack stack, LookAheadSet filter) { LookAheadSet follow; // Check trivial cases if (length <= 0 || pos >= alt.Count) { return(new LookAheadSet(0)); } // Find look-ahead for this element var first = FindLookAhead(alt[pos], length, stack, filter); if (alt[pos].MinCount == 0) { first.AddEmpty(); } // Find remaining look-ahead if (filter == null) { length -= first.GetMinLength(); if (length > 0) { follow = FindLookAhead(alt, length, pos + 1, stack, null); first = first.CreateCombination(follow); } } else if (filter.IsOverlap(first)) { var overlaps = first.CreateOverlaps(filter); length -= overlaps.GetMinLength(); filter = filter.CreateFilter(overlaps); follow = FindLookAhead(alt, length, pos + 1, stack, filter); first.RemoveAll(overlaps); first.AddAll(overlaps.CreateCombination(follow)); } return(first); }
private Node ParseAlternative(ProductionPatternAlternative alt) { var node = NewProduction(alt.Pattern); EnterNode(node); for (int i = 0; i < alt.Count; i++) { try { ParseElement(node, alt[i]); } catch (ParseException e) { AddError(e, true); NextToken(); i--; } } return(ExitNode(node)); }
private void CalculateLookAhead(ProductionPatternAlternative alt, int pos) { LookAheadSet previous = new LookAheadSet(0); int length = 1; // Check trivial cases if (pos >= alt.Count) { return; } // Check for non-optional element var pattern = alt.Pattern; var elem = alt[pos]; if (elem.MinCount == elem.MaxCount) { CalculateLookAhead(alt, pos + 1); return; } // Calculate simple look-aheads var first = FindLookAhead(elem, 1, new CallStack(), null); var follow = FindLookAhead(alt, 1, pos + 1, new CallStack(), null); // Resolve conflicts var location = "at position " + (pos + 1); var conflicts = FindConflicts(pattern.Name, location, first, follow); while (conflicts.Size() > 0) { length++; conflicts.AddAll(previous); first = FindLookAhead(elem, length, new CallStack(), conflicts); follow = FindLookAhead(alt, length, pos + 1, new CallStack(), conflicts); first = first.CreateCombination(follow); elem.LookAhead = first; if (first.Intersects(conflicts)) { first = first.CreateIntersection(conflicts); ThrowAmbiguityException(pattern.Name, location, first); } previous = conflicts; conflicts = FindConflicts(pattern.Name, location, first, follow); } // Check remaining elements CalculateLookAhead(alt, pos + 1); }