PetitParser evaluator not working properly

2019-07-25 17:59发布

when I try running this code on pharo, my answers are somewhat off. I try evaluating 1-2+3 but for some reason, it does 1- (2+3) and I do not understand why this is so. Thanks for your time.

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条回答
迷人小祖宗
2楼-- · 2019-07-25 18:55

Consider the definition of term

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

The / term2 part is an OR between

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

and

term2 

Let's mentally parse '1 - 2 + 3' according to term.

We first read $1 and have to decide between the two options above. The first one will fail unless prod consumes '1 - 2'. But this is impossible because

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

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

and there is no $* or $( coming, and '1 - 2' is not parsed by #number.

So, we try with term2, which is defined in a similar way

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

so now we have a OR between two options.

As above, the first option fails, so we next try prod, then prim and finally number. The number parser begins with

#digit asParser plus 

which consumes the digit $1 and produces the integer 1.

We are now back in term2. We consume ' - ' and are left with '2 + 3'; which according to term produces 5. So we get 1 - 5 = -4.


SHORT EXPLANATION

For term to parse as (1 - 2) + 3, prod should consume 1 - 2, which doesn't because prod involves no $-.

查看更多
登录 后发表回答