问题
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:
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 $-
.
来源:https://stackoverflow.com/questions/42034072/petitparser-evaluator-not-working-properly