美好的一天,我有简单的语法来描述选择的列。用户可以为它们指定简单的列名、列名和子列(等等),或者使用'*'来选择所有字段。
一些例子:
exp = "(Id)" - select only Id column
exp = "(Id, Name)" - select Id and Name columns
exp = "(Id, Type(Id, Name)" - select Id, Type.Id, Type.Name columns
exp = "(Id, Type(*))" - select Id and all columns in Type
所以,我定义了令牌枚举:
enum FieldExpressionToken
{
Undefined,
[Token(Example = "(")]
LBracket,
[Token(Example = ")")]
RBracket,
[Token(Example = ",")]
Comma,
[Token(Example = ":")]
Colon,
[Token(Example = "*")]
Star,
Identifier
}
和他们的标记器:
static class FieldExpressionTokenizer
{
private static TextParser<TextSpan> FieldNameToken { get; } =
Span.Regex(@"@?[a-zA-Z_]\w*(\.@?[a-zA-Z_]\w*)*");
public static Tokenizer<FieldExpressionToken> Instance { get; } =
new TokenizerBuilder<FieldExpressionToken>()
.Match(Character.EqualTo('*'), FieldExpressionToken.Star)
.Match(Character.EqualTo('('), FieldExpressionToken.LBracket)
.Match(Character.EqualTo(')'), FieldExpressionToken.RBracket)
.Match(Character.EqualTo(','), FieldExpressionToken.Comma)
.Match(Character.EqualTo(':'), FieldExpressionToken.Colon)
.Match(FieldNameToken, FieldExpressionToken.Identifier)
.Build();
}
现在我尝试创建解析器。单个字段的解析器:
private static readonly TokenListParser<FieldExpressionToken, Field> Field =
from identifier in Token
.EqualTo(FieldExpressionToken.Identifier)
.Or(Token.EqualTo(FieldExpressionToken.Star))
.Named("column name")
select new Field(identifier.ToStringValue());
复合字段解析器:
private static readonly TokenListParser<FieldExpressionToken, Field> ComplexField =
from identifier in Token
.EqualTo(FieldExpressionToken.Identifier)
.Or(Token.EqualTo(FieldExpressionToken.Star))
.Named("column name")
.Try()
.Then(x => Token
.EqualTo(FieldExpressionToken.Colon)
.IgnoreThen(Parse.Ref(() => FieldList))
.Named("child fields")
.Select(value => new Field(x.ToStringValue(), new[] {value})))
select identifier;
列表解析器:
private static readonly TokenListParser<FieldExpressionToken, Field> FieldList =
from begin in Token.EqualTo(FieldExpressionToken.LBracket)
from fields in Parse
.Ref(() => FieldExpression)
.Named("fields")
.ManyDelimitedBy(
Token.EqualTo(FieldExpressionToken.Comma),
end: Token.EqualTo(FieldExpressionToken.RBracket))
select new Field("", fields.Select(x => new Field(x.ToString())));
和总表达式解析器:
private static TokenListParser<FieldExpressionToken, Field> FieldExpression { get; } =
Field
.Or(ComplexField)
.Or(FieldList);
我可以解析像(Name)
or这样的简单表达式(Id,Name)
,但是在表达式上我(Name:(Id))
得到错误Syntax error (line 1, column 6): unexpected
:), expected
.
谁能帮我纠正我的解析器?