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]
e/0 → t/0 ; t → e• `(` e `)`
e/0 → e/0 ; e → e• `+` t
t/0 → e/0 ; e → t•
|
||
t/0 → 1, t('12')
| |||
| Iteration 0 | |||
| |||
![]() |
#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 | |||
| |||
![]() |
#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]
e/2 → t/2 ; t → e• `(` e `)`
e/2 → e/2 ; e → e• `+` t
t/2 → e/2 ; e → t•
t/2 → e/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 | |||
| |||
![]() |
#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 | |||
| |||
![]() |
#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]
e/4 → t/0 ; t → e `(` e• `)`
e/4 → t/4 ; t → e• `(` e `)`
e/4 → e/4 ; e → e• `+` t
t/4 → e/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]
e/4 → t/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 | |||
| |||
![]() |
#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 | |||
| |||
![]() |
#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 | |||
| |||
![]() |
#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 | |||
| |||
![]() |
#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 | |||
| |||
| (No new calls or successes that can be further processed) | |||
| Iteration 9 [Fixed point reached] | |||