@@ -359,6 +359,23 @@ def test_leftrecursion(self):
359
359
self .assertEqual (g .num ("32767" ), 32767 )
360
360
361
361
362
+ def test_mutual_leftrecursion (self ):
363
+ g = self .compile ("""
364
+ num ::= (<num>:n <digit>:d => n * 10 + d
365
+ | <digit>)
366
+ digit ::= :x ?(x.isdigit()) => int(x)
367
+ x ::= <expr>
368
+ expr ::= <x>:e '-' <num>:n => e - n
369
+ | <num>
370
+ """ )
371
+ self .assertEqual (g .expr ("3" ), 3 )
372
+ self .assertEqual (g .expr ("3-2" ), 1 )
373
+ self .assertEqual (g .expr ("3-2-1" ), 0 )
374
+ self .assertEqual (g .x ("3" ), 3 )
375
+ self .assertEqual (g .x ("3-2" ), 1 )
376
+ self .assertEqual (g .x ("3-2-1" ), 0 )
377
+
378
+
362
379
def test_characterVsSequence (self ):
363
380
"""
364
381
Characters (in single-quotes) are not regarded as sequences.
@@ -806,6 +823,23 @@ def test_leftrecursion(self):
806
823
self .assertEqual (g .num ("32767" ), 32767 )
807
824
808
825
826
+ def test_mutual_leftrecursion (self ):
827
+ g = self .compile ("""
828
+ num = (num:n digit:d -> n * 10 + d
829
+ | digit)
830
+ digit = :x ?(x.isdigit()) -> int(x)
831
+ x = expr
832
+ expr = x:e '-' num:n -> e - n
833
+ | num
834
+ """ )
835
+ self .assertEqual (g .expr ("3" ), 3 )
836
+ self .assertEqual (g .expr ("3-2" ), 1 )
837
+ self .assertEqual (g .expr ("3-2-1" ), 0 )
838
+ self .assertEqual (g .x ("3" ), 3 )
839
+ self .assertEqual (g .x ("3-2" ), 1 )
840
+ self .assertEqual (g .x ("3-2-1" ), 0 )
841
+
842
+
809
843
def test_characterVsSequence (self ):
810
844
"""
811
845
Characters (in single-quotes) are not regarded as sequences.
@@ -1011,6 +1045,25 @@ def test_leftrecursion(self):
1011
1045
self .assertEqual (g .num ("3" ), 3 )
1012
1046
self .assertEqual (g .num ("32767" ), 32767 )
1013
1047
1048
+ def test_mutual_leftrecursion (self ):
1049
+ g = self .compile ("""
1050
+ num = (num:n digit:d -> makeInt(n, d)
1051
+ | digit)
1052
+ digit = :x ?(isdigit(x)) -> int(x)
1053
+ x = expr
1054
+ expr = x:e '-' num:n -> subtract(e, n)
1055
+ | num
1056
+ """ , {"makeInt" : lambda x , y : x * 10 + y ,
1057
+ "isdigit" : lambda x : x .isdigit (),
1058
+ "subtract" : lambda x , y : x - y })
1059
+ self .assertEqual (g .expr ("3" ), 3 )
1060
+ self .assertEqual (g .expr ("3-2" ), 1 )
1061
+ self .assertEqual (g .expr ("3-2-1" ), 0 )
1062
+ self .assertEqual (g .x ("3" ), 3 )
1063
+ self .assertEqual (g .x ("3-2" ), 1 )
1064
+ self .assertEqual (g .x ("3-2-1" ), 0 )
1065
+
1066
+
1014
1067
def test_characterVsSequence (self ):
1015
1068
"""
1016
1069
Characters (in single-quotes) are not regarded as sequences.
0 commit comments