// nested direct left recursion test ometa NestedDirectLR { top = a:va -> ['', va], a = a:va 'a' -> ['', va, 'a'] | c:vc 'a' -> ['', vc, 'a'], c = c:vc 'c' -> ['', vc, 'c'] | 'c' -> ['', 'c'] } //test:: NestedDirectLR.matchAll('ccaa', 'top') [, [, [, [, [, c], c], a], a]] // silly grammar to test backtracking and priorities ometa Silly { top = a:va b:vb -> ['', va, vb], a = 'a' -> ['', 'a'], b = 'b' -> ['', 'b'] | 'b' 'b' -> ['', "bb"] } // good, obvious Silly.matchAll('ab', 'top') [, [, a], [, b]] Silly.matchAll('abb', 'top') [, [, a], [, b]] // silly grammar to test backtracking and priorities ometa Silly2 { top = a:va b:vb -> ['', va, vb], a = 'a' -> ['', 'a'], b = 'b' 'b' -> ['', "bb"] | 'b' -> ['', 'b'] } // good, obvious Silly2.matchAll('ab', 'top') [, [, a], [, b]] Silly2.matchAll('abb', 'top') [, [, a], [, bb]] // test backtracking and left recursion: backtracking at the end of recursion ometa BacktrackLR1 { top = a:va b:vb -> ['', va, vb], a = a:v1 'a' 'a' -> ['', v1, "aa"] | a:v2 'a' -> ['', v2, 'a'] | 'a' 'a' -> ['', "aa"], b = 'a' 'b' -> ['', "ab"] } //BAD: match fails because applications of rule a consume all of 'a's in input string BacktrackLR1.matchAll('aaab', 'top') // test backtracking and left recursion ometa BacktrackLR2 { top = a:va b:vb -> ['', va, vb], a = a:v1 'a' 'a' -> ['', v1, "aa"] | a:v2 'a' -> ['', v2, 'a'] | 'a' 'c' -> ['', "ac"], b = 'a' 'b' -> ['', "ab"] } //BAD: Again, this fails. I suppose it's because rule matches somehow? BacktrackLR2.matchAll('acab', 'top') //// OLD:: based on assumption that OMeta backtracks to consume entire string //// // quick grammar to play around with direct left recursion ometa DirectLR { top = a:va b:vb -> ['', va, vb], a = a:v1 'a' -> ['', v1] | a:v2 'a' 'b' -> ['', v2] | 'a' -> ['', 'a'], b = 'b' -> ['', 'b'] } //BAD: this "match" does not cover the end of the string. Also, it should use // the second choice '' for the second node DirectLR.matchAll('aabb', 'top') [, [, [, a]], [, b]] // variation on last grammar to illustrate shortcomings in left recursion handling ometa DirectLR2 { top = a:va b:vb -> ['', va, vb], a = a:v1 'a' -> ['', v1] | 'ab' -> ['', 'ab'] | 'a' -> ['', 'a'], b = 'b' -> ['', 'b'] } //BAD: again, the string is only partially matched DirectLR2.matchAll('aabb', 'top') [, [, [, a]], [, b]] //BAD: am I doing something wrong so the last character is being ignored? DirectLR2.matchAll('abb', 'top') [, [, a], [, b]] //NOTE: I just found http://vpri.org/pipermail/ometa/2008-June/000006.html which // disclaims support of indirect left recursion in OMeta. So the failures below // are moot. // quick grammar to play around with indirect left recursion ometa MultiChoiceLR { top = ad:v -> ['', v], a = ab:vab -> ['', vab] | ac:vac -> ['', vac] | ad:vad -> ['', vad], ab = a:va 'b' -> ['', va, 'b'] | 'b' -> ['', 'b'], ac = a:v1 'c' -> ['', v1, 'c'] | a:v2 'cb' -> ['', v2, 'bc'] | 'c' -> ['', 'c'], ad = a:va 'd' -> ['', va, 'd'] } //BAD: this match fails -- it needs to backtrack and reevaluate rule without the // cached result for (which is not in the parse stack for the seed trace). Also // note that I think the result should be // [, [, [, [, [, [, c]], b]], d]] // i.e. it should use the higher-precedence rule for instead of a single // application of which would give // [, [, [, [, cb]], d]] MultiChoiceLR.matchAll('cbd', 'top') //BAD: this match fails, though I think it should be // [, [, [, [, [, [, cb]], c]], d]] MultiChoiceLR.matchAll('cbcd', 'top') //GOOD: this one looks good MultiChoiceLR.matchAll('bd', 'top') [, [, [, [, b]], d]] //BAD: this one should have a few extra applications of rule , right? MultiChoiceLR.matchAll('bddd', 'top') [, [, [, [, b]], d]] //BAD: still missing an application of rule MultiChoiceLR.matchAll('cdd', 'top') [, [, [, [, c]], d]] //BAD: match fails, likely same problem as the first example MultiChoiceLR.matchAll('cbbcbbd', 'top')