“Sprache”解析器`Present`语义
“Sprache” parser `Present` semantics
我正在编写一个符合 System for Cross-domain Identity Management: Protocol Filtering 规范的解析器。我几乎可以用 Sprache 解析任何表达式,除了“pr”运算符。不知道如何让它正常工作。
这里是主要的解析内容:
{
And = Operator("and", "And");
Or = Operator("or", "Or");
Le = Operator("le", "LessThanOrEqual");
Lt = Operator("lt", "LessThan");
Gt = Operator("gt", "GreaterThan");
Ge = Operator("ge", "GreaterThanOrEqual");
Eq = Operator("eq", "Equal");
Ne = Operator("ne", "NotEqual");
Co = Operator("co", "Contains");
Sw = Operator("sw", "StartsWith");
Ew = Operator("ew", "EndsWith");
Pr = Operator("pr", "Present");
...
Operand = (Parentheses
.XOr(Literal.Or(AttrPath.Token()))
.XOr(CaseInsensitiveString)).Token();
//compareOp = "eq" / "ne" / "co" /
// "sw" / "ew" /
// "gt" / "lt" /
// "ge" / "le"
CompareExpression = Parse.XChainOperator(Le.Or(Lt).XOr(Ge.Or(Gt)).XOr(Eq.Or(Ne)).XOr(Sw.Or(Ew)).XOr(Co).XOr(Pr), Operand, FilterExpression.Binary);
PresentsExpression = Parse.XChainRightOperator(Pr, Operand, FilterExpression.Binary).Or(CompareExpression);
// logExp = FILTER SP ("and" / "or") SP FILTER
AndExpression = Parse.XChainOperator(And, CompareExpression, FilterExpression.Binary);
// logExp = FILTER SP ("and" / "or") SP FILTER
OrExpression = Parse.XChainOperator(Or, AndExpression, FilterExpression.Binary);
Filter = OrExpression;
}
private static Parser<string> Operator(string op, string opName)
{
return Parse.String(op).Token().Return(opName);
}
这是我添加“pr”解析的地方:
Parse.XChainRightOperator(Pr, Operand, FilterExpression.Binary).Or(CompareExpression);
此过滤器失败:title pr and addresses[type eq \"work\"].streetAddress eq \"workStreet\"
这没关系:
addresses[type eq \"work\"].streetAddress eq \"workStreet\"
and (userType eq \"Employee\" or userType eq \"ParttimeEmployee\")
也许有人可以帮我解决这个问题。
编辑:
也许我应该在某个时候使用 XChainRightOperator 链接运算符,因为 pr title 工作正常。但是链扩展是针对二进制表达式的,我需要一元。
我找到答案了。
这是正确的解析代码:
Operand = (Parentheses
.XOr(Literal.Or(AttrPath.Token()))
.XOr(CaseInsensitiveString)).Token();
// compareOp = "eq" / "ne" / "co" /
// "sw" / "ew" /
// "gt" / "lt" /
// "ge" / "le"
Comparison = Parse.XChainOperator(Le.Or(Lt).XOr(Ge.Or(Gt)).XOr(Eq.Or(Ne)).XOr(Sw.Or(Ew)).XOr(Co).XOr(Pr), Operand, FilterExpression.Binary);
// attrPath SP "pr"
Presence = Operand.SelectMany(operand => Pr, (operand, pr) => FilterExpression.Unary(pr, operand));
// attrExp = (attrPath SP "pr") /
// (attrPath SP compareOp SP compValue)
AttributeExpression = Presence.Or(Comparison);
// logExp = FILTER SP ("and" / "or") SP FILTER
LogicalExpression = Parse.XChainOperator(Or.Or(And), AttributeExpression, FilterExpression.Binary);
Filter = LogicalExpression;
技巧是先检查操作数,然后检查操作数,然后在 AttributeExpression = Presence.Or(Comparison);
中使用 Or 而不是 XOr
我正在编写一个符合 System for Cross-domain Identity Management: Protocol Filtering 规范的解析器。我几乎可以用 Sprache 解析任何表达式,除了“pr”运算符。不知道如何让它正常工作。
这里是主要的解析内容:
{
And = Operator("and", "And");
Or = Operator("or", "Or");
Le = Operator("le", "LessThanOrEqual");
Lt = Operator("lt", "LessThan");
Gt = Operator("gt", "GreaterThan");
Ge = Operator("ge", "GreaterThanOrEqual");
Eq = Operator("eq", "Equal");
Ne = Operator("ne", "NotEqual");
Co = Operator("co", "Contains");
Sw = Operator("sw", "StartsWith");
Ew = Operator("ew", "EndsWith");
Pr = Operator("pr", "Present");
...
Operand = (Parentheses
.XOr(Literal.Or(AttrPath.Token()))
.XOr(CaseInsensitiveString)).Token();
//compareOp = "eq" / "ne" / "co" /
// "sw" / "ew" /
// "gt" / "lt" /
// "ge" / "le"
CompareExpression = Parse.XChainOperator(Le.Or(Lt).XOr(Ge.Or(Gt)).XOr(Eq.Or(Ne)).XOr(Sw.Or(Ew)).XOr(Co).XOr(Pr), Operand, FilterExpression.Binary);
PresentsExpression = Parse.XChainRightOperator(Pr, Operand, FilterExpression.Binary).Or(CompareExpression);
// logExp = FILTER SP ("and" / "or") SP FILTER
AndExpression = Parse.XChainOperator(And, CompareExpression, FilterExpression.Binary);
// logExp = FILTER SP ("and" / "or") SP FILTER
OrExpression = Parse.XChainOperator(Or, AndExpression, FilterExpression.Binary);
Filter = OrExpression;
}
private static Parser<string> Operator(string op, string opName)
{
return Parse.String(op).Token().Return(opName);
}
这是我添加“pr”解析的地方:
Parse.XChainRightOperator(Pr, Operand, FilterExpression.Binary).Or(CompareExpression);
此过滤器失败:title pr and addresses[type eq \"work\"].streetAddress eq \"workStreet\"
这没关系:
addresses[type eq \"work\"].streetAddress eq \"workStreet\"
and (userType eq \"Employee\" or userType eq \"ParttimeEmployee\")
也许有人可以帮我解决这个问题。
编辑: 也许我应该在某个时候使用 XChainRightOperator 链接运算符,因为 pr title 工作正常。但是链扩展是针对二进制表达式的,我需要一元。
我找到答案了。 这是正确的解析代码:
Operand = (Parentheses
.XOr(Literal.Or(AttrPath.Token()))
.XOr(CaseInsensitiveString)).Token();
// compareOp = "eq" / "ne" / "co" /
// "sw" / "ew" /
// "gt" / "lt" /
// "ge" / "le"
Comparison = Parse.XChainOperator(Le.Or(Lt).XOr(Ge.Or(Gt)).XOr(Eq.Or(Ne)).XOr(Sw.Or(Ew)).XOr(Co).XOr(Pr), Operand, FilterExpression.Binary);
// attrPath SP "pr"
Presence = Operand.SelectMany(operand => Pr, (operand, pr) => FilterExpression.Unary(pr, operand));
// attrExp = (attrPath SP "pr") /
// (attrPath SP compareOp SP compValue)
AttributeExpression = Presence.Or(Comparison);
// logExp = FILTER SP ("and" / "or") SP FILTER
LogicalExpression = Parse.XChainOperator(Or.Or(And), AttributeExpression, FilterExpression.Binary);
Filter = LogicalExpression;
技巧是先检查操作数,然后检查操作数,然后在 AttributeExpression = Presence.Or(Comparison);