Main ArticleExamples TOC

Takmela: Parsing arithmetic expression example (1+2+3)

The next step in learning Takmela's algorithm, after tracing 1+2

Grammar
expr : expr '+' term 
    | term ;

term : 
    NUM
    ;
    
NUM: [0-9]+;

WS skip: [ \r\n\t]*;
Input
1+2+3

Trace appears confusing? This might help

Call start nonterminal
#0: Called expr/0 at the top level (will process)
Processing expr/0 codePos expr → • expr `+` term inputPos 0
Calling: expr/0 with Cont expr/0 ; expr → expr• `+` term ; expr [already processed]
Processing expr/0 codePos expr → • term inputPos 0
Calling: term/0 with Cont expr/0 ; expr → term• ; expr [will process]
Processing term/0 codePos term → • NUM inputPos 0
Match NUM to 1, matched; inputPos now 1
Reached end of rule, success! term/0 → 1
New continuations:
term/0expr/0 ; expr → term• ; expr
expr/0expr/0 ; expr → expr• `+` term ; expr
term/0 → 1, term('1')
Iteration 0
Worklist - successes
jS term/0 → 1 term('1')
Worklist - continuations
S⤚ term/0expr/0 ; expr → term•
nJ expr/0expr/0 ; expr → expr• `+` term
#1: JoinS: term/0 → 1 will resume cont: expr/0 ; expr → term•
Processing expr/0 codePos expr → term• inputPos 1
Reached end of rule, success! expr/0 → 1
term/0 → 1, term('1') expr/0 → 1, expr(term('1'))
Iteration 1
Worklist - successes
jS expr/0 → 1 expr(term('1'))
Worklist - continuations
#2: JoinS: expr/0 → 1 will resume cont: expr/0 ; expr → expr• `+` term
Processing expr/0 codePos expr → expr• `+` term inputPos 1
Match + to +, matched; inputPos now 2
Calling: term/2 with Cont expr/0 ; expr → expr `+` term• ; expr(expr(term('1')), '+') [will process]
Processing term/2 codePos term → • NUM inputPos 2
Match NUM to 2, matched; inputPos now 3
Reached end of rule, success! term/2 → 3
New continuations:
term/2expr/0 ; expr → expr `+` term• ; expr(expr(term('1')), '+')
term/0 → 1, term('1') expr/0 → 1, expr(term('1')) term/2 → 3, term('2')
#3: JoinS: expr/0 → 1 will resume cont: Root/0 ; Root → expr•
×Didn't reach end of input, not a successful parse
term/0 → 1, term('1') expr/0 → 1, expr(term('1')) term/2 → 3, term('2')
Iteration 2
Worklist - successes
jS term/2 → 3 term('2')
Worklist - continuations
S⤚ term/2expr/0 ; expr → expr `+` term•
#4: JoinS: term/2 → 3 will resume cont: expr/0 ; expr → expr `+` term•
Processing expr/0 codePos expr → expr `+` term• inputPos 3
Reached end of rule, success! expr/0 → 3
term/0 → 1, term('1') expr/0 → 1, expr(term('1')) term/2 → 3, term('2') expr/0 → 3, expr(expr(term('1')),'+',term('2'))
Iteration 3
Worklist - successes
jS expr/0 → 3 expr(expr(term('1')),'+',term('2'))
Worklist - continuations
#5: JoinS: expr/0 → 3 will resume cont: expr/0 ; expr → expr• `+` term
Processing expr/0 codePos expr → expr• `+` term inputPos 3
Match + to +, matched; inputPos now 4
Calling: term/4 with Cont expr/0 ; expr → expr `+` term• ; expr(expr(expr(term('1')), '+', term('2')), '+') [will process]
Processing term/4 codePos term → • NUM inputPos 4
Match NUM to 3, matched; inputPos now 5
Reached end of rule, success! term/4 → 5
New continuations:
term/4expr/0 ; expr → expr `+` term• ; expr(expr(expr(term('1')), '+', term('2')), '+')
term/0 → 1, term('1') expr/0 → 1, expr(term('1')) term/2 → 3, term('2') expr/0 → 3, expr(expr(term('1')),'+',term('2')) term/4 → 5, term('3')
#6: JoinS: expr/0 → 3 will resume cont: Root/0 ; Root → expr•
×Didn't reach end of input, not a successful parse
term/0 → 1, term('1') expr/0 → 1, expr(term('1')) term/2 → 3, term('2') expr/0 → 3, expr(expr(term('1')),'+',term('2')) term/4 → 5, term('3')
Iteration 4
Worklist - successes
jS term/4 → 5 term('3')
Worklist - continuations
S⤚ term/4expr/0 ; expr → expr `+` term•
#7: JoinS: term/4 → 5 will resume cont: expr/0 ; expr → expr `+` term•
Processing expr/0 codePos expr → expr `+` term• inputPos 5
Reached end of rule, success! expr/0 → 5
term/0 → 1, term('1') expr/0 → 1, expr(term('1')) term/2 → 3, term('2') expr/0 → 3, expr(expr(term('1')),'+',term('2')) term/4 → 5, term('3') expr/0 → 5, expr(expr(expr(term('1')),'+',term('2')),'+',term('3'))
Iteration 5
Worklist - successes
jS expr/0 → 5 expr(expr(expr(term('1')),'+',term('2')),'+',term('3'))
Worklist - continuations
#8: JoinS: expr/0 → 5 will resume cont: expr/0 ; expr → expr• `+` term
Processing expr/0 codePos expr → expr• `+` term inputPos 5
Match `+` to (eof), fail
term/0 → 1, term('1') expr/0 → 1, expr(term('1')) term/2 → 3, term('2') expr/0 → 3, expr(expr(term('1')),'+',term('2')) term/4 → 5, term('3') expr/0 → 5, expr(expr(expr(term('1')),'+',term('2')),'+',term('3'))
#9: JoinS: expr/0 → 5 will resume cont: Root/0 ; Root → expr•
Reached end of input, successful parse!
term/0 → 1, term('1') expr/0 → 1, expr(term('1')) term/2 → 3, term('2') expr/0 → 3, expr(expr(term('1')),'+',term('2')) term/4 → 5, term('3') expr/0 → 5, expr(expr(expr(term('1')),'+',term('2')),'+',term('3')) Root/0 → 5, Root(expr(expr(expr(term('1')),'+',term('2')),'+',term('3')))
Iteration 6
Worklist - successes
nJ Root/0 → 5 Root(expr(expr(expr(term('1')),'+',term('2')),'+',term('3')))
Worklist - continuations
(No new calls or successes that can be further processed)
Iteration 7 [Fixed point reached]