/** * Finds the look-ahead set for a production pattern element. The * maximum look-ahead length must be specified. This method does * NOT take the element repeat into consideration when creating * the look-ahead set. It is also possible to specify a look-ahead * set filter, which will make sure that unnecessary token * sequences will be avoided. * * @param elem the production pattern element * @param length the maximum look-ahead length * @param dummy a parameter to distinguish the method * @param stack the call stack used for loop detection * @param filter the look-ahead set filter * * @return the look-ahead set for the pattern element * * @throws ParserCreationException if an infinite loop was found * in the grammar */ private LookAheadSet FindLookAhead(ProductionPatternElement elem, int length, int dummy, CallStack stack, LookAheadSet filter) { LookAheadSet result; ProductionPattern pattern; if (elem.IsToken()) { result = new LookAheadSet(length); result.Add(elem.Id); } else { pattern = GetPattern(elem.Id); result = FindLookAhead(pattern, length, stack, filter); if (stack.Contains(pattern.Name)) { result = result.CreateRepetitive(); } } return(result); }
/// <summary> /// Finds the look-ahead set for a production pattern element. The /// maximum look-ahead length must be specified. This method does /// NOT take the element repeat into consideration when creating /// the look-ahead set. It is also possible to specify a look-ahead /// set filter, which will make sure that unnecessary token /// sequences will be avoided. /// </summary> /// <param name="elem">The production pattern element</param> /// <param name="length">The maximum look ahead length</param> /// <param name="dummy">A parameter to distinguish the method</param> /// <param name="stack">The call stack used for loop detection</param> /// <param name="filter">The look ahead set filter</param> /// <returns>The look-ahead set for the pattern element</returns> /// <exception cref="ParserCreationException"> /// If an infinite loop was found in the grammar /// </exception> private LookAheadSet FindLookAhead( ProductionPatternElement elem, int length, #pragma warning disable IDE0060 // Remove unused parameter int dummy, #pragma warning restore IDE0060 // Remove unused parameter CallStack stack, LookAheadSet filter) { LookAheadSet result; ProductionPattern pattern; if (elem.IsToken) { result = new LookAheadSet(length); result.Add(elem.Id); } else { pattern = this.GetPattern(elem.Id); result = this.FindLookAhead(pattern, length, stack, filter); if (stack.Contains(pattern.Name)) { result = result.CreateRepetitive(); } } return(result); }
/** * Parses a production pattern element. All nodes parsed may * or may not be added to the parse tree node specified, * depending on the analyzer callbacks. * * @param node the production parse tree node * @param elem the production pattern element to parse * * @throws ParseException if the input couldn't be parsed * correctly */ private void ParseElement(Production node, ProductionPatternElement elem) { Node child; for (int i = 0; i < elem.MaxCount; i++) { if (i < elem.MinCount || IsNext(elem)) { if (elem.IsToken()) { child = NextToken(elem.Id); EnterNode(child); AddNode(node, ExitNode(child)); } else { child = ParsePattern(GetPattern(elem.Id)); AddNode(node, child); } } else { break; } } }
/// <summary> /// Adds a production pattern element to this alternative. The /// multiplicity values in the element will be overridden with /// the specified values. The element is appended to the end of /// the element list. /// </summary> /// <param name="elem">The production pattern element</param> /// <param name="min">The minimum number of occurrences</param> /// <param name="max"> /// The maximum number of occurrences, or -1 for infinite /// </param> public void AddElement(ProductionPatternElement elem, int min, int max) { if (elem.IsToken) { this.AddToken(elem.Id, min, max); } else { this.AddProduction(elem.Id, min, max); } }
/** * Checks a production pattern element for completeness. If * the element references a production pattern not added to * this parser, a parser creation exception will be thrown. * * @param name the name of the pattern being checked * @param elem the production pattern element to check * * @throws ParserCreationException if the element referenced a * pattern not added to this parser */ private void CheckElement(string name, ProductionPatternElement elem) { if (elem.IsProduction() && GetPattern(elem.Id) == null) { throw new ParserCreationException( ParserCreationException.ErrorType.INVALID_PRODUCTION, name, "an undefined production pattern id (" + elem.Id + ") is referenced"); } }
/// <summary> /// Finds the look-ahead set for a production pattern element. The /// maximum look-ahead length must be specified. This method takes /// the element repeats into consideration when creating the /// look-ahead set, but does NOT include an empty sequence even if /// the minimum count is zero (0). It is also possible to specify a /// look-ahead set filter, which will make sure that unnecessary /// token sequences will be avoided. /// </summary> /// <param name="elem">The production pattern element</param> /// <param name="length">The maximum look-ahead length</param> /// <param name="stack">The call stack used for loop detection</param> /// <param name="filter">The look-ahead set filter</param> /// <returns>The look-ahead set for the pattern element</returns> /// <exception cref="ParserCreationException"> /// If an infinite loop was found in the grammar /// </exception> private LookAheadSet FindLookAhead( ProductionPatternElement elem, int length, CallStack stack, LookAheadSet filter) { LookAheadSet result; LookAheadSet first; LookAheadSet follow; int max; // Find initial element look-ahead first = this.FindLookAhead(elem, length, 0, stack, filter); result = new LookAheadSet(length); result.AddAll(first); if (filter == null || !filter.IsOverlap(result)) { return(result); } // Handle element repetitions if (elem.MaxCount == int.MaxValue) { first = first.CreateRepetitive(); } max = elem.MaxCount; if (length < max) { max = length; } for (int i = 1; i < max; i++) { first = first.CreateOverlaps(filter); if (first.Size <= 0 || first.MinLength >= length) { break; } follow = this.FindLookAhead( elem, length, 0, stack, filter.CreateFilter(first)); first = first.CreateCombination(follow); result.AddAll(first); } return(result); }
/// <summary> /// Checks a production pattern element for completeness. If /// the element references a production pattern not added to /// this parser, a parser creation exception will be thrown. /// </summary> /// <param name="name">The name of the pattern being checked</param> /// <param name="elem">The production pattern element to check</param> /// <exception cref="ParserCreationException"> /// If the element referenced a pattern not added to this parser /// </exception> private void CheckElement( string name, ProductionPatternElement elem) { if (elem.IsProduction && this.GetPattern(elem.Id) == null) { string msg = "an undefined production pattern id (" + elem.Id + ") is referenced"; throw new ParserCreationException( ParserCreationException.ErrorType.InvalidProduction, name, msg); } }
/** * Checks if the next tokens match a production pattern * element. If the element has a look-ahead set it will be * used, otherwise the look-ahead set of the referenced * production or token will be used. * * @param elem the pattern element to check * * @return true if the next tokens match, or * false otherwise */ private bool IsNext(ProductionPatternElement elem) { LookAheadSet set = elem.LookAhead; if (set != null) { return(set.IsNext(this)); } else if (elem.IsToken()) { return(elem.IsMatch(PeekToken(0))); } else { return(IsNext(GetPattern(elem.Id))); } }
/// <summary> /// Returns a string representation of a production pattern /// element. /// </summary> /// <param name="elem">The production pattern element</param> /// <returns> /// A detailed string representation of the element /// </returns> private string ToString(ProductionPatternElement elem) { StringBuilder buffer = new StringBuilder(); int min = elem.MinCount; int max = elem.MaxCount; if (min == 0 && max == 1) { buffer.Append("["); } if (elem.IsToken) { buffer.Append(this.GetTokenDescription(elem.Id)); } else { buffer.Append(this.GetPattern(elem.Id).Name); } if (min == 0 && max == 1) { buffer.Append("]"); } else if (min == 0 && max == int.MaxValue) { buffer.Append("*"); } else if (min == 1 && max == int.MaxValue) { buffer.Append("+"); } else if (min != 1 || max != 1) { buffer.Append("{"); buffer.Append(min); buffer.Append(","); buffer.Append(max); buffer.Append("}"); } return(buffer.ToString()); }
/** * Finds the look-ahead set for a production pattern element. The * maximum look-ahead length must be specified. This method takes * the element repeats into consideration when creating the * look-ahead set, but does NOT include an empty sequence even if * the minimum count is zero (0). It is also possible to specify a * look-ahead set filter, which will make sure that unnecessary * token sequences will be avoided. * * @param elem the production pattern element * @param length the maximum look-ahead length * @param stack the call stack used for loop detection * @param filter the look-ahead set filter * * @return the look-ahead set for the pattern element * * @throws ParserCreationException if an infinite loop was found * in the grammar */ private LookAheadSet FindLookAhead(ProductionPatternElement elem, int length, CallStack stack, LookAheadSet filter) { LookAheadSet result; LookAheadSet first; LookAheadSet follow; int max; // Find initial element look-ahead first = FindLookAhead(elem, length, 0, stack, filter); result = new LookAheadSet(length); result.AddAll(first); if (filter == null || !filter.IsOverlap(result)) { return result; } // Handle element repetitions if (elem.MaxCount == Int32.MaxValue) { first = first.CreateRepetitive(); } max = elem.MaxCount; if (length < max) { max = length; } for (int i = 1; i < max; i++) { first = first.CreateOverlaps(filter); if (first.Size() <= 0 || first.GetMinLength() >= length) { break; } follow = FindLookAhead(elem, length, 0, stack, filter.CreateFilter(first)); first = first.CreateCombination(follow); result.AddAll(first); } return result; }
/// <summary> /// Adds a production pattern element to this alternative. The /// element is appended to the end of the element list. /// </summary> /// <param name="elem">The production pattern element</param> public void AddElement(ProductionPatternElement elem) { this.elements.Add(elem); }
/** * Adds a production pattern element to this alternative. The * multiplicity values in the element will be overridden with * the specified values. The element is appended to the end of * the element list. * * @param elem the production pattern element * @param min the minimum number of occurancies * @param max the maximum number of occurancies, or * -1 for infinite */ public void AddElement(ProductionPatternElement elem, int min, int max) { if (elem.IsToken()) { AddToken(elem.Id, min, max); } else { AddProduction(elem.Id, min, max); } }
/** * Adds a production pattern element to this alternative. The * element is appended to the end of the element list. * * @param elem the production pattern element */ public void AddElement(ProductionPatternElement elem) { elements.Add(elem); }
/** * Finds the look-ahead set for a production pattern element. The * maximum look-ahead length must be specified. This method does * NOT take the element repeat into consideration when creating * the look-ahead set. It is also possible to specify a look-ahead * set filter, which will make sure that unnecessary token * sequences will be avoided. * * @param elem the production pattern element * @param length the maximum look-ahead length * @param dummy a parameter to distinguish the method * @param stack the call stack used for loop detection * @param filter the look-ahead set filter * * @return the look-ahead set for the pattern element * * @throws ParserCreationException if an infinite loop was found * in the grammar */ private LookAheadSet FindLookAhead(ProductionPatternElement elem, int length, int dummy, CallStack stack, LookAheadSet filter) { LookAheadSet result; ProductionPattern pattern; if (elem.IsToken()) { result = new LookAheadSet(length); result.Add(elem.Id); } else { pattern = GetPattern(elem.Id); result = FindLookAhead(pattern, length, stack, filter); if (stack.Contains(pattern.Name)) { result = result.CreateRepetitive(); } } return result; }
/** * Checks a production pattern element for completeness. If * the element references a production pattern not added to * this parser, a parser creation exception will be thrown. * * @param name the name of the pattern being checked * @param elem the production pattern element to check * * @throws ParserCreationException if the element referenced a * pattern not added to this parser */ private void CheckElement(string name, ProductionPatternElement elem) { if (elem.IsProduction() && GetPattern(elem.Id) == null) { throw new ParserCreationException( ParserCreationException.ErrorType.INVALID_PRODUCTION, name, "an undefined production pattern id (" + elem.Id + ") is referenced"); } }
/** * Checks if the next tokens match a production pattern * element. If the element has a look-ahead set it will be * used, otherwise the look-ahead set of the referenced * production or token will be used. * * @param elem the pattern element to check * * @return true if the next tokens match, or * false otherwise */ private bool IsNext(ProductionPatternElement elem) { LookAheadSet set = elem.LookAhead; if (set != null) { return set.IsNext(this); } else if (elem.IsToken()) { return elem.IsMatch(PeekToken(0)); } else { return IsNext(GetPattern(elem.Id)); } }
/** * Parses a production pattern element. All nodes parsed may * or may not be added to the parse tree node specified, * depending on the analyzer callbacks. * * @param node the production parse tree node * @param elem the production pattern element to parse * * @throws ParseException if the input couldn't be parsed * correctly */ private void ParseElement(Production node, ProductionPatternElement elem) { Node child; for (int i = 0; i < elem.MaxCount; i++) { if (i < elem.MinCount || IsNext(elem)) { if (elem.IsToken()) { child = NextToken(elem.Id); EnterNode(child); AddNode(node, ExitNode(child)); } else { child = ParsePattern(GetPattern(elem.Id)); AddNode(node, child); } } else { break; } } }
/** * Returns a string representation of a production pattern * element. * * @param elem the production pattern element * * @return a detailed string representation of the element */ private string ToString(ProductionPatternElement elem) { StringBuilder buffer = new StringBuilder(); int min = elem.MinCount; int max = elem.MaxCount; if (min == 0 && max == 1) { buffer.Append("["); } if (elem.IsToken()) { buffer.Append(GetTokenDescription(elem.Id)); } else { buffer.Append(GetPattern(elem.Id).Name); } if (min == 0 && max == 1) { buffer.Append("]"); } else if (min == 0 && max == Int32.MaxValue) { buffer.Append("*"); } else if (min == 1 && max == Int32.MaxValue) { buffer.Append("+"); } else if (min != 1 || max != 1) { buffer.Append("{"); buffer.Append(min); buffer.Append(","); buffer.Append(max); buffer.Append("}"); } return buffer.ToString(); }