首页 > 解决方案 > 如何使用 Sprache 解析条件三元语法 (a > b ? a : b)

问题描述

我一直在想我用得越多就明白 Sprache 解析,但后来我遇到了一个让我困惑的新语法,而且网上没有很多例子。此时,我试图让我的字符串具有条件语法(如 C#),例如:

(A > B ? A : B)
A+2 > 7 ? (A + 2) : -1
(A*B) < 12 ? "Real" : "Fake"

我使用以下解析让常规运算符正常工作(>、<、!、= 等):

private Parser<ExpressionType> Operator(string op, ExpressionType opType)
        => Parse.String(op).Token().Return(opType);

但当然,常规运算符都使用单个字符串(例如:“<”)作为运算符字符串,而条件运算符需要更复杂的内容,例如:

{Expression} ? {Expression} : {Expression}

因此,我尝试将这样的Parser ExpressionType拼凑在一起,但是我当然不能完全正确地使用语法:

Parser<ExpressionType> Conditional = Parse.Ref(() => Expr)
                  .Parse.String("?")
                  .Parse.Ref(() => Expr)
                  .Parse.String(":")
                  .Parse.Ref(() => Expr)
                  .Token().Return(ExpressionType.Conditional);

然后,一旦我弄清楚了,我是否将这个 Conditional与其他运算符一起传递给Parse.ChainOperator方法?其他运算符都没有在其定义的任一侧引用表达式,所以我认为可能不会。

我还尝试像这样创建一个单独的解析器表达式(但我不会以允许条件语法在字符串中的任何位置使用的方式工作(而不仅仅是作为顶级一次性表达式):

    Parser<Expression> Conditional = from test in Expr
                  from q in Parse.String("?")
                  from ifTrue in Expr
                  from c in Parse.String(":")
                  from ifFalse in Expr
                  select (Expression)Expression.Condition(test, ifTrue, ifFalse, typeof(RawResult));

[此解决方案的另一个问题是它声称“测试”不是布尔值]

这一切都表明条件运算符在很多方面都很特别。欢迎提出建议。感谢您提供的任何意见。

更新#1 这是我的 Expr 的代码。在这篇文章中,我不确定兔子洞要走多深......

    Parser<Expression> Expr = Parse.ChainOperator(LessThanEq.Or(GreaterThanEq)
                                    .Or(EqualTo2).Or(EqualTo1)
                                    .Or(NotEqualTo1).Or(NotEqualTo2)
                                    .Or(LessThan).Or(GreaterThan)
                                    .Or(And1).Or(And2).Or(Or1).Or(Or2)
                                    .Or(Plus).Or(Minus)
                                    .Or(Multiply).Or(Divide),
                                   Operand, Expression.MakeBinary);

标签: c#parsinglambdalinq-expressionssprache

解决方案


推荐阅读