PetitParser评估程序无法正常工作

时间:2017-02-03 22:33:51

标签: smalltalk evaluation pharo petitparser

当我尝试在pharo上运行此代码时,我的答案有点偏离。我尝试评估1-2 + 3,但由于某种原因,它确实1-(2 + 3),我不明白为什么会这样。谢谢你的时间。

number :=  #digit asParser plus token trim ==> [ :token | token inputValue asNumber ].

term := PPUnresolvedParser new.
prod := PPUnresolvedParser new.
term2 := PPUnresolvedParser new.
prod2 := PPUnresolvedParser new.
prim := PPUnresolvedParser new.

term def: (prod , $+ asParser trim , term ==> [ :nodes | nodes first + nodes last ]) / term2.

term2 def: (prod , $- asParser trim , term ==> [ :nodes | nodes first - nodes last ])/ prod.

prod def: (prim , $* asParser trim , prod ==> [ :nodes | nodes first * nodes last ])/ prim.

prod2 def: (prim , $/ asParser trim , prod ==> [ :nodes | nodes first / nodes last ])/ prim.

prim def: ($( asParser trim , term , $) asParser trim ==> [ :nodes | nodes second ]) / number.

start := term end.

start parse: '1 - 2 + 3'

1 个答案:

答案 0 :(得分:2)

考虑term

的定义
term
    def: prod , $+ asParser trim , term
        ==> [:nodes | nodes first + nodes last]
        / term2.

/ term2部分是OR之间的<{p}}

prod , $+ asParser trim, term ==> [something]

term2 

让我们根据'1 - 2 + 3'进行精神上的解析term

我们首先阅读$1并且必须在上述两个选项之间做出决定。除非prod消耗'1 - 2',否则第一个将失败。但这是不可能的,因为

prod
    def: prim , $* asParser trim , prod
        ==> [:nodes | nodes first * nodes last]
        / prim.

prim
    def: $( asParser trim , term , $) asParser trim
        ==> [:nodes | nodes second]
        / number

并且没有$*$(即将到来,'1 - 2'未解析#number

所以,我们尝试term2,它以类似的方式定义

term2
    def: prod , $- asParser trim , term
        ==> [:nodes | nodes first - nodes last]
        / prod.

所以现在我们在两个选项之间有一个OR

如上所述,第一个选项失败,因此我们接下来尝试prod,然后是prim,最后是numbernumber解析器以

开头
#digit asParser plus 

消耗数字$1并生成整数1

我们现在回到term2。我们使用' - '并留下'2 + 3';根据{{​​1}}生成term。我们得到5

简短说明

1 - 5 = -4解析为term(1 - 2) + 3应该使用prod,因为1 - 2不涉及prod