Sprache Part 12: Ref, Named, End, Not, Except, Then, Where, Preview, Concat
Contents
This is the last in a series of posts documenting Sprache:
- Sprache Part 1: Parsing Characters
- Sprache Part 2: Parsing Strings
- Sprache Part 3: Repetition (Many, AtLeastOnce, Until, Repeat, Once)
- Sprache Part 4: Or and XOr
- Sprache Part 5: Select, Return, and Regex
- Sprache Part 6: DelimitedBy
- Sprache Part 7: ChainOperator and ChainRightOperator
- Sprache Part 8: Token, Contained, Identifier, LineTerminator
- Sprache Part 9: Positioned
- Sprache Part 10: Optional and XOptional
- Sprache Part 11: Parsing Comments
- Sprache Part 12: Ref, Named, End, Not, Except, Then, Where, Preview, Concat
This post covers a number of less frequently used methods not already covered in other posts.
Ref
Refer to another parser indirectly. This allows circular compile-time dependency between parsers.
Parser<T> Ref<T>(Func<Parser<T>> reference)
For example, in this extremely simple expression parser the Ref is required - static fields are initialized in order, and so AdditiveExpression
is still null at the point where the PrimaryExpression
field is initialized.
|
|
Named
Names part of the grammar for help with error messages.
Parser<T> Named<T>(this Parser<T> parser, string name)
|
|
End
Parse end-of-input.
Parser<T> End<T>(this Parser<T> parser)
Here we use End
to make sure there isn’t any left-over unparsed garbage after parsing the expression:
|
|
Not
Constructs a parser that will fail if the given parser succeeds, and will succeed if the given parser fails. In any case, it won’t consume any input. It’s like a negative look-ahead in regex.
Parser<object> Not<T>(this Parser<T> parser)
Example taken from ApexSharp parser:
|
|
Except
Attempt parsing only if the except
parser fails.
Parser<T> Except<T, U>(this Parser<T> parser, Parser<U> except)
Example taken from XAML binding expression parser in OmniXaml:
|
|
Then
Parse first
, and if successful, then parse second
. Returns the result of the second parser.
Parser<U> Then<T, U>(this Parser<T> first, Func<T, Parser<U>> second)
|
|
Where
Succeed if the parsed value matches predicate.
Parser<T> Where<T>(this Parser<T> parser, Func<T, bool> predicate)
|
|
Can also be used as part of a linq expression:
|
|
Concat
Concatenate two streams of elements.
Parser<IEnumerable<T>> Concat<T>(this Parser<IEnumerable<T>> first, Parser<IEnumerable<T>> second)
The only example I could find of this was in the construction of IgnoreCase
:
|
|
Preview
Construct a parser that indicates that the given parser is optional and non-consuming. The returned parser will succeed on any input no matter whether the given parser succeeds or not. In any case, it won’t consume any input, like a positive look-ahead in regex.
Parser<IOption<T>> Preview<T>(this Parser<T> parser)
The only example I was able to find was in the Commented method in Sprache itself.
Span
Constructs a parser that returns the ITextSpan
of the parsed value, which includes information about the position of the parsed value in the original source.
Parser<ITextSpan<T>> Span<T>(this Parser<T> parser)
The following example is taken from this issue in the Sprache project on GitHub and parses conditionally based on the position of the parsed value.
|
|
Author Justin Pealing
LastMod 2020-08-12