Example #1
0
        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);
        }
Example #2
0
        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);
        }