Sprache Part 7: ChainOperator and ChainRightOperator
Contents
This is part of 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
The ChainOperator
and ChainRightOperator
methods are helpers for parsing left and right-associative operators respectivey, e.g. 1 + 2
or 5 ^ 2
.
ChainOperator
Chain a left-associative operator of operations matched by op
and operands matched by operand
.
Parser<T> ChainOperator<T, TOp>(Parser<TOp> op, Parser<T> operand, Func<TOp, T, T, T> apply)
op
is a parser for the operator (e.g +
, ^
), and operand
is the parser for the operands such as numbers or other expressions. apply
is a function that combines the terms and operand, into a return value. This parser can match zero or more operations, however at least one operand must be matched. The parser in the following example parses a chain or zero or more additions between numbers.
|
|
Note that the type returned from apply
must match the operand type, so that the operators can be chained together. In this example the operand type and the returned value is a string so we can visualize how the chaining works:
|
|
XChainOperator
XChainOperator
is similar to ChainOperator
, however fails in cases where certain inputs are only partially parsed.
Parser<T> XChainOperator<T, TOp>(Parser<TOp> op, Parser<T> operand, Func<TOp, T, T, T> apply)
|
|
Like all the other X
methods, this is intended to improve handling of errors by failing fast. In some cases (such as the first example), it helps by returning a more specific error message, however in the second example it successfully matched a chained operator, " + 4”, and so the result was the same as using ChainOperator
.
ChainRightOperator
Like ChainOperator
, however for right-associative operators, like ^
.
Parser<T> ChainRightOperator<T, TOp>(Parser<TOp> op, Parser<T> operand, Func<TOp, T, T, T> apply)
|
|
XChainRightOperator
Like ChainRightOperator
, however fails on some partially parsed inputs. See XChainOperator
for examples.
Parser<T> XChainRightOperator<T, TOp>(Parser<TOp> op, Parser<T> operand, Func<TOp, T, T, T> apply)
Author Justin Pealing
LastMod 2020-04-20