1

当我尝试在 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'
4

1 回答 1

2

考虑定义term

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

/ term2部分是OR介于

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两个选择。

如上,第一个选项失败,所以我们 next try prod,然后prim, finally numbernumber解析器以

#digit asParser plus 

它消耗数字$1并产生整数1

我们现在又回来了term2。我们消费' - '并留下'2 + 3'; 根据term生产5。所以我们得到1 - 5 = -4.


简短说明

对于term解析为(1 - 2) + 3prod应该使用1 - 2,这不因为prod涉及 no $-

于 2017-02-04T02:27:06.327 回答