2017-02-03 3 views
1

wenn ich versuche, diesen Code auf Pharo laufen, sind meine Antworten etwas aus. Ich versuche, 1-2 + 3 zu bewerten, aber aus irgendeinem Grund macht es 1- (2 + 3) und ich verstehe nicht, warum das so ist. Vielen Dank für Ihre Zeit.PetitParser Evaluator funktioniert nicht richtig

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' 

Antwort

2

Betrachten wir die Definition von term

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

Der / term2 Teil ist ein OR zwischen

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

und

term2 

Le t's mental analysieren '1 - 2 + 3' nach term.

Wir lesen zuerst $1 und müssen zwischen den beiden oben genannten Optionen entscheiden. Die erste wird fehlschlagen, es sei denn prod verbraucht '1 - 2'. Aber das ist unmöglich, weil

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

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

und es keine $* oder $( kommt, und '1 - 2' wird nicht von #number analysiert.

Also, versuchen wir mit term2, die in ähnlicher Weise definiert ist

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

so jetzt haben wir eine OR zwischen zwei Möglichkeiten.

Wie oben, schlägt die erste Option fehl, also versuchen wir als nächstes , dann prim und schließlich number. Der number Parser beginnt mit

#digit asParser plus 

, die die Ziffer verbraucht $1 und produziert die ganze Zahl 1.

Wir sind jetzt zurück in term2. Wir verbrauchen ' - ' und sind mit '2 + 3' verlassen; was gemäß term5 produziert. So erhalten wir 1 - 5 = -4.


kurze Erklärung

Für term zu analysieren als (1 - 2) + 3, prod1 - 2 verbrauchen sollte, was nicht da prod keine $- beinhaltet.