How to parse Conditional Ternary syntax (a > b ? a : b) using Sprache

倖福魔咒の 提交于 2019-12-13 16:29:02

问题


I keep thinking I understand Sprache parsing the more I use it, but then I come across a new syntax that baffles me, and there are not a lot of examples online. At this time, I'm trying to allow my string to have conditional syntax (like C#) such as:

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

I have the regular operators working fine (>,<,!,=,etc.) using the following parse:

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

But of course the regular operators all use a single string (eg: "<") as the operator string, whereas the conditional operator requires something more complex like:

{Expression} ? {Expression} : {Expression}

So I've tried cobbling together a Parser ExpressionType like this, but of course I can't get the syntax quite right:

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

And then once I figure it out, do I pass this Conditional into the Parse.ChainOperator method along with the other operators? None of the other operators references Expressions on either side of their definition, so I think probably not.

I also tried creating a separate Parser Expression like this (but I don't this will work in a way that would allow the Conditional syntax to be used anywhere in the string (not just as the top-level-once-only expression):

    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));

[One additional problem with this solution is that it claims that "test" is not boolean]

This all points to the Conditional operator being special in so many ways. Suggestions welcome. Thanks for any input you can provide.

Update#1 Here's the code for my Expr. I wasn't sure how deep to go down the rabbit hole, in this post...

    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);

来源:https://stackoverflow.com/questions/56990021/how-to-parse-conditional-ternary-syntax-a-b-a-b-using-sprache

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!