Main ArticleExamples TOC

Takmela: Parsing arithmetic expression example (more complicated and with ambiguity)

An aritmetic expression grammar that is both more complicated than 1+2, and has a deliberate (and useless) ambiguity, to show how the more interesting parts of Takmela work.

Grammar
// Arithmetic expressions with deliberate ambiguity
// to see how Takmela handles it
// e.g 1+a(3) -> [1+a](3) or 1 + [a(3)]

expr :   expr '+' term
       | term ;
term : 
      ID 
    | NUM
    | expr '(' expr ')';
    
ID: [a-zA-Z] [a-zA-Z0-9]*;

NUM: [0-9]+;

WS skip: [ \r\n\t]*;
Grammar
12 + f(13)

Hint: Hovering over a graph expands it

Trace appears confusing? This might help

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