将数学表达式与控制流相结合



我想知道,当表达式与控制流混合时,是如何解析的。

让我们假设这样的语法:

case 
when a == Method() + 1 
then Something(1) 
when a == Other() - 2
then 1
else 0
end

这里有两个条件表达式,Method() + 1Something(1)0。每一个都可以由Shunting-yard algorithm翻译成后缀,然后很容易地翻译成AST。但是,是否有可能将该算法扩展到处理控制流?或者还有其他方法可以解决表达式和控制流的混合问题吗?

另一个例子:

a == b ? 1 : 2  

我如何对这样的表达式进行分类:a between b and c,我可以说between是三元函数吗?或者这种表达方式有什么特别的名字吗?

您当然可以使用运算符优先语法来解析三元运算符。在中

expr ? expr : expr

这里的二进制"运算符"是? expr :,它方便地以运算符标记(尽管不同)开始和结束。为了使调车场适应这种情况,分配的正确优先级的左优先级:到CCD_ 9运算符的优先级。的左优先级的右优先级是±infin;,就像括号一样(实际上,它们是)。

由于case语句基本上是三元运算符的重复应用,因此对标记使用略有不同的拼写,并得出类似的解决方案。(这里case whenend是纯父母代,而then和剩余的when对应于?:。)

话虽如此,使用LALR(1)语法分析器生成器确实更简单,而且几乎可以肯定的是,无论你用什么语言编写,都有一个可用的语法分析器生成器


很明显,三元运算符和OP的case语句都是运算符语法:

  1. 三元算子:

    ternary-expr: non-ternary-expr
    | non-ternary-expr '?' expr ':' ternary-expr
    

    通常,三元运算符的优先级将低于任何其他运算符,并关联到右侧,这就是上面的编写方式。在C和其他语言中,三元表达式与赋值表达式具有相同的优先级,添加起来很简单。这导致了之间的关系

    • X ·> ?
    • ? <· X
    • ? ·=· :
    • X ·> :
    • : <· X
  2. 案例说明(多种可能的配方之一):

    case_statement: 'case' case_body 'else' expr 'end'
    case_body: 'when' expr 'then' expr
    | case_body 'when' expr 'then' expr
    

    以下是上述语法的优先级关系:

    • case <· when
    • case ·=· else
    • when <· X(见下文)
    • when ·=· then
    • then ·> when
    • then ·> else
    • else <· X
    • else ·=· end
    • X ·> then
    • X ·> when
    • X ·> end

    上述关系中的X是指任何二进制或一元运算符、任何值终端、()

    很容易找到所有这些终端的左优先级函数和右优先级函数;该模式将类似于标准代数语法中的括号。

调车场算法适用于带有一元和二元运算符的表达式。你需要一些更强大的东西,比如LL(1)或LALR(1)来解析控制流语句,一旦你有了这些,它也将处理表达式。根本不需要调车场算法。

最新更新