//* // * Returns a look-ahead set with all conflicts between two // * look-ahead sets. // * // * @param pattern the pattern name being analyzed // * @param location the pattern location // * @param set1 the first look-ahead set // * @param set2 the second look-ahead set // * // * @return a look-ahead set with the conflicts found // * // * @throws ParserCreationException if an inherent ambiguity was // * found among the look-ahead sets // private LookAheadSet FindConflicts(string pattern, string location, LookAheadSet set1, LookAheadSet set2) { LookAheadSet result = default(LookAheadSet); result = set1.CreateIntersection(set2); if (result.IsRepetitive()) { ThrowAmbiguityException(pattern, location, result); } return(result); }
//* // * Calculates the look-aheads needed for the specified pattern // * alternative. This method attempts to resolve any conflicts in // * optional elements by recalculating look-aheads for referenced // * productions. // * // * @param alt the production pattern alternative // * @param pos the pattern element position // * // * @throws ParserCreationException if the look-ahead set couldn't // * be determined due to inherent ambiguities // private void CalculateLookAhead(ProductionPatternAlternative alt, int pos) { ProductionPattern pattern = default(ProductionPattern); ProductionPatternElement elem = default(ProductionPatternElement); LookAheadSet first = default(LookAheadSet); LookAheadSet follow = default(LookAheadSet); LookAheadSet conflicts = default(LookAheadSet); LookAheadSet previous = new LookAheadSet(0); string location = null; int length = 1; // Check trivial cases if (pos >= alt.Count) { return; } // Check for non-optional element pattern = alt.Pattern; elem = alt[pos]; if (elem.MinCount == elem.MaxCount) { CalculateLookAhead(alt, pos + 1); return; } // Calculate simple look-aheads first = FindLookAhead(elem, 1, new CallStack(), null); follow = FindLookAhead(alt, 1, pos + 1, new CallStack(), null); // Resolve conflicts location = "at position " + (pos + 1); conflicts = FindConflicts(pattern.Name, location, first, follow); while (conflicts.Size() > 0) { length += 1; 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); }
//* // * Returns a look-ahead set with all conflics between // * alternatives in a production pattern. // * // * @param pattern the production pattern // * @param maxLength the maximum token sequence length // * // * @return a look-ahead set with the conflicts found // * // * @throws ParserCreationException if an inherent ambiguity was // * found among the look-ahead sets // private LookAheadSet FindConflicts(ProductionPattern pattern, int maxLength) { LookAheadSet result = new LookAheadSet(maxLength); LookAheadSet set1 = default(LookAheadSet); LookAheadSet set2 = default(LookAheadSet); for (int i = 0; i <= pattern.Count - 1; i++) { set1 = pattern[i].LookAhead; for (int j = 0; j <= i - 1; j++) { set2 = pattern[j].LookAhead; result.AddAll(set1.CreateIntersection(set2)); } } if (result.IsRepetitive()) { ThrowAmbiguityException(pattern.Name, null, result); } return(result); }