Class ExpressionParser
Contains tools for parsing expression languages with associative infix operators.
To get started, write a Parser<TToken, T>, to parse an atomic term in your expression language, and use the Operator class to create a table of operator parsers in order of their precedence. Then call one of the Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) overloads to compile the table of operators into a Parser<TToken, T>.
Inheritance
- object
- ExpressionParser
Inherited Members
- object.GetType()
- object.MemberwiseClone()
- object.ToString()
- object.Equals(object)
- object.Equals(object, object)
- object.ReferenceEquals(object, object)
- object.GetHashCode()
Declaration
public static class ExpressionParser
Remarks
Since it's common for an expression language to have a recursive structure, overloads of Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) are provided which take a function. The function's argument will be the completed parser for a whole expression. This allows you to write recursive parsers.
Examples
Here is an example of a parser for mathematical expressions. The parser computes the result of the expression (although in practice your parser would probably return an AST).
var operators = new[]
{
Operator.Prefix(Char('-').ThenReturn<Func<int, int>>(x => -x)),
Operator.InfixL(Char('*').ThenReturn<Func<int, int, int>>((x, y) => x * y)),
Operator.InfixL(Char('+').ThenReturn<Func<int, int, int>>((x, y) => x + y))
};
var parser = ExpressionParser.Build(
expr => Num.Or(expr.Between(Char('('), Char(')'))),
operators
);
Console.WriteLine(parser.ParseOrThrow("-3*(370+9)*37"));
// Output:
// -42069
Methods
Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>)
Builds a parser for expressions built from the operators in operatorTable
.
operatorTable
is a sequence of operators in precedence order:
the operators in the first row have the highest precedence and operators in later rows have lower precedence.
Declaration
public static Parser<TToken, T> Build<TToken, T>(Parser<TToken, T> term, IEnumerable<OperatorTableRow<TToken, T>> operatorTable)
Parameters
Type | Name | Description |
---|---|---|
Parser<TToken, T> |
term |
A parser for a single term in an expression language. |
IEnumerable<OperatorTableRow<TToken, T>> |
operatorTable |
A table of operators. |
Returns
Type | Description |
---|---|
Parser<TToken, T> |
A parser for expressions built from the operators in |
Type Parameters
Name | Description |
---|---|
TToken |
The token type. |
T |
The return type of the parser. |
Remarks
Since it's common for an expression language to have a recursive structure, overloads of Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) are provided which take a function. The function's argument will be the completed parser for a whole expression. This allows you to write recursive parsers.
Build<TToken, T>(Parser<TToken, T>, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>>)
Builds a parser for expressions built from the operators in operatorTable
.
operatorTable
is a sequence of operators in precedence order:
the operators in the first row have the highest precedence and operators in later rows have lower precedence.
Declaration
public static Parser<TToken, T> Build<TToken, T>(Parser<TToken, T> term, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>> operatorTable)
Parameters
Type | Name | Description |
---|---|---|
Parser<TToken, T> |
term |
A parser for a single term in an expression language. |
IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>> |
operatorTable |
A table of operators. |
Returns
Type | Description |
---|---|
Parser<TToken, T> |
A parser for expressions built from the operators in |
Type Parameters
Name | Description |
---|---|
TToken |
The token type. |
T |
The return type of the parser. |
Remarks
Since it's common for an expression language to have a recursive structure, overloads of Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) are provided which take a function. The function's argument will be the completed parser for a whole expression. This allows you to write recursive parsers.
Build<TToken, T>(Parser<TToken, T>, Func<Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>>)
Builds a parser for expressions built from the operators in operatorTableFactory
's result.
The operator table is a sequence of operators in precedence order:
the operators in the first row have the highest precedence and operators in later rows have lower precedence.
This overload is useful for recursive expressions (for example, languages with parenthesised subexpressions).
operatorTableFactory
's argument will be a parser which parses a full subexpression.
Declaration
public static Parser<TToken, T> Build<TToken, T>(Parser<TToken, T> term, Func<Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>> operatorTableFactory)
Parameters
Type | Name | Description |
---|---|---|
Parser<TToken, T> |
term |
A parser for a single term in an expression language. |
Func<Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>> |
operatorTableFactory |
A function which produces a table of operators. |
Returns
Type | Description |
---|---|
Parser<TToken, T> |
A parser for expressions built from the operators in the operator table. |
Type Parameters
Name | Description |
---|---|
TToken |
The token type. |
T |
The return type of the parser. |
Remarks
Since it's common for an expression language to have a recursive structure, overloads of Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) are provided which take a function. The function's argument will be the completed parser for a whole expression. This allows you to write recursive parsers.
Build<TToken, T>(Parser<TToken, T>, Func<Parser<TToken, T>, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>>>)
Builds a parser for expressions built from the operators in operatorTableFactory
's result.
The operator table is a sequence of operators in precedence order:
the operators in the first row have the highest precedence and operators in later rows have lower precedence.
This overload is useful for recursive expressions (for example, languages with parenthesised subexpressions).
operatorTableFactory
's argument will be a parser which parses a full subexpression.
Declaration
public static Parser<TToken, T> Build<TToken, T>(Parser<TToken, T> term, Func<Parser<TToken, T>, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>>> operatorTableFactory)
Parameters
Type | Name | Description |
---|---|---|
Parser<TToken, T> |
term |
A parser for a single term in an expression language. |
Func<Parser<TToken, T>, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>>> |
operatorTableFactory |
A function which produces a table of operators. |
Returns
Type | Description |
---|---|
Parser<TToken, T> |
A parser for expressions built from the operators in the operator table. |
Type Parameters
Name | Description |
---|---|
TToken |
The token type. |
T |
The return type of the parser. |
Remarks
Since it's common for an expression language to have a recursive structure, overloads of Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) are provided which take a function. The function's argument will be the completed parser for a whole expression. This allows you to write recursive parsers.
Build<TToken, T>(Func<Parser<TToken, T>, Parser<TToken, T>>, IEnumerable<OperatorTableRow<TToken, T>>)
Builds a parser for expressions built from the operators in operatorTable
.
The operator table is a sequence of operators in precedence order:
the operators in the first row have the highest precedence and operators in later rows have lower precedence.
This overload is useful for recursive expressions (for example, languages with parenthesised subexpressions).
termFactory
's argument will be a parser which parses a full subexpression.
Declaration
public static Parser<TToken, T> Build<TToken, T>(Func<Parser<TToken, T>, Parser<TToken, T>> termFactory, IEnumerable<OperatorTableRow<TToken, T>> operatorTable)
Parameters
Type | Name | Description |
---|---|---|
termFactory |
A function which produces a parser for a single term. |
|
IEnumerable<OperatorTableRow<TToken, T>> |
operatorTable |
A table of operators. |
Returns
Type | Description |
---|---|
Parser<TToken, T> |
A parser for expressions built from the operators in |
Type Parameters
Name | Description |
---|---|
TToken |
The token type. |
T |
The return type of the parser. |
Remarks
Since it's common for an expression language to have a recursive structure, overloads of Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) are provided which take a function. The function's argument will be the completed parser for a whole expression. This allows you to write recursive parsers.
Build<TToken, T>(Func<Parser<TToken, T>, Parser<TToken, T>>, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>>)
Builds a parser for expressions built from the operators in operatorTable
.
The operator table is a sequence of operators in precedence order:
the operators in the first row have the highest precedence and operators in later rows have lower precedence.
This overload is useful for recursive expressions (for example, languages with parenthesised subexpressions).
termFactory
's argument will be a parser which parses a full subexpression.
Declaration
public static Parser<TToken, T> Build<TToken, T>(Func<Parser<TToken, T>, Parser<TToken, T>> termFactory, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>> operatorTable)
Parameters
Type | Name | Description |
---|---|---|
termFactory |
A function which produces a parser for a single term. |
|
IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>> |
operatorTable |
A table of operators. |
Returns
Type | Description |
---|---|
Parser<TToken, T> |
A parser for expressions built from the operators in |
Type Parameters
Name | Description |
---|---|
TToken |
The token type. |
T |
The return type of the parser. |
Remarks
Since it's common for an expression language to have a recursive structure, overloads of Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) are provided which take a function. The function's argument will be the completed parser for a whole expression. This allows you to write recursive parsers.
Build<TToken, T>(Func<Parser<TToken, T>, (Parser<TToken, T> term, IEnumerable<OperatorTableRow<TToken, T>> operatorTable)>)
Builds a parser for expressions built from the operators in termAndOperatorTableFactory
's second result.
The operator table is a sequence of operators in precedence order:
the operators in the first row have the highest precedence and operators in later rows have lower precedence.
This overload is useful for recursive expressions (for example, languages with parenthesised subexpressions).
termAndOperatorTableFactory
's argument will be a parser which parses a full subexpression.
Declaration
public static Parser<TToken, T> Build<TToken, T>(Func<Parser<TToken, T>, (Parser<TToken, T> term, IEnumerable<OperatorTableRow<TToken, T>> operatorTable)> termAndOperatorTableFactory)
Parameters
Type | Name | Description |
---|---|---|
Func<Parser<TToken, T>, (Parser<TToken, T> term, IEnumerable<OperatorTableRow<TToken, T>> operatorTable)> |
termAndOperatorTableFactory |
A function which produces a parser for a single term and a table of operators. |
Returns
Type | Description |
---|---|
Parser<TToken, T> |
A parser for expressions built from the operators in the operator table. |
Type Parameters
Name | Description |
---|---|
TToken |
The token type. |
T |
The return type of the parser. |
Remarks
Since it's common for an expression language to have a recursive structure, overloads of Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) are provided which take a function. The function's argument will be the completed parser for a whole expression. This allows you to write recursive parsers.
Build<TToken, T>(Func<Parser<TToken, T>, (Parser<TToken, T> term, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>> operatorTable)>)
Builds a parser for expressions built from the operators in termAndOperatorTableFactory
's second result.
The operator table is a sequence of operators in precedence order:
the operators in the first row have the highest precedence and operators in later rows have lower precedence.
This overload is useful for recursive expressions (for example, languages with parenthesised subexpressions).
termAndOperatorTableFactory
's argument will be a parser which parses a full subexpression.
Declaration
public static Parser<TToken, T> Build<TToken, T>(Func<Parser<TToken, T>, (Parser<TToken, T> term, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>> operatorTable)> termAndOperatorTableFactory)
Parameters
Type | Name | Description |
---|---|---|
Func<Parser<TToken, T>, (Parser<TToken, T> term, IEnumerable<IEnumerable<OperatorTableRow<TToken, T>>> operatorTable)> |
termAndOperatorTableFactory |
A function which produces a parser for a single term and a table of operators. |
Returns
Type | Description |
---|---|
Parser<TToken, T> |
A parser for expressions built from the operators in the operator table. |
Type Parameters
Name | Description |
---|---|
TToken |
The token type. |
T |
The return type of the parser. |
Remarks
Since it's common for an expression language to have a recursive structure, overloads of Build<TToken, T>(Parser<TToken, T>, IEnumerable<OperatorTableRow<TToken, T>>) are provided which take a function. The function's argument will be the completed parser for a whole expression. This allows you to write recursive parsers.