update metagrammar
[sbp.git] / tests / regression.tc
index faba28d..f13accf 100644 (file)
@@ -1,31 +1,17 @@
-//testcase {
-//    input  "x";
-//    output "a1:{x}";
-//
-//    s   = a1:: a
-//    a   = s1:: s
-//    a   = ^"x"
-//}
-//
-//testcase {
-//    input  "x";
-//    output "x";
-//    output "s2:{s2:{s0 s0} x}";
-//    output "s2:{s0 x}";
-//
-//
-//    s   = s2:: s s
-//    s   = ^"x"
-//    s   = s0:: ()
-//}
+testcase {
+    input "aaaaa";
+    s = A
+    A = "a" s &~ "a" A
+      | "a" A &~ "a" s
+}
 
 testcase {
     input "ab c";
     output "1:{{a b} {c}}";
 
     s     = ids
-    ids   = "1":: id (" " ids &~ id ~[]*)
-          | "2":: id (    ids &~ id ~[]*)
+    ids   = "1":: id (" " ids &~ id ((~[])*)!)
+          | "2":: id (    ids &~ id ((~[])*)!)
           | id
     id    = [a-z]++
 }
@@ -75,37 +61,16 @@ testcase {
     x     = ~[]
     s     = xbx:: x* b x*
     b     = abab:: [ab][ab]
-         &~ ( "aa" | "bb" )
-}
-
-testcase {
-    input "12111211";
-    output "ac:{{2 1 2 1}}";
-    //output "a:{{2 1 2 1}}";
-    //output "c:{{c:{1 1} c:{1 1}}}";
-
-    s   = ab:: ab
-        | ac:: ac
-        | bc:: bc
-        //| a  =>  "a"
-        //| b  =>  "b"
-        //| c  =>  "c"
-    ab   = a & b
-    ac   = a & c
-    bc   = b & c
-    a   = ("1" x)*
-    b   = ("b":: x "2")*
-    c   = ("c":: x "2" x "1")*
-    x   = [123]
+         &~ ("aa"|"bb")
 }
 
 testcase {
     input  "qxbambambam";
-    output "bam:{a bam:{a bam:{a x:{x}}}}";
+    output "bam:{a bam:{a bam:{a x}}}";
 
     s   = "q" z
     z   = a z ^"bam"
-    z   = ^"x"
+        | ^"x"
     a   = a:: ()
 }
 
@@ -127,7 +92,7 @@ testcase {
 
     s   = ^"q" x "q"
     x   = ^"a" a
-    x   = epsilon:: ()
+        | epsilon:: ()
     a   = s1:: x
 }
 
@@ -174,7 +139,7 @@ testcase {
     output "s:{aa:{aa:{a b} b}}";
     s   = s:: "b" a
     a   = aa:: "a" a b
-    a   = a:: ()
+        | a:: ()
     b   = b:: ()
 }
 
@@ -182,10 +147,10 @@ testcase {
     input "aaab";
     output "sx:{b aa:{aa:{b b} b}}";
     s   = sx:: b d "a" "b"
-    s   = sy:: "a" d "a" d
+        | sy:: "a" d "a" d
     d   = aa:: "a" a b
     a   = aa:: "a" b b
-    a   = a::  ()
+        | a::  ()
     b   = b::  ()
 }
 
@@ -222,23 +187,6 @@ testcase {
     idl    = [a-d]
 }
 
-//testcase {
-//    input "a*b*c";
-//    output "times:{stringify:{{a}} times:{stringify:{{b}} stringify:{{c}}}}";
-//    w    = " "
-//    l    = id
-//    s    = l "=" r  => "assign"
-//         | r
-//    r    = l
-//         | l "=" r       => "assign"
-//         | r "+" r       => "plus"
-//         | (r) "*" r       => "times"
-//         | "(" r ")"
-//         | r r           => "times"
-//    id     = idl++       => "stringify"
-//    idl    = [a-d]
-//}
-
 testcase {
     input "a+b*c";
     output "plus:{stringify:{{a}} times:{stringify:{{b}} stringify:{{c}}}}";
@@ -265,73 +213,71 @@ testcase {
   q    = q:: [a-z]++
 }
 
-//testcase {
-//
-//    input "
-//
-//
-//
-// while x>0
-//    while y>0
-//       foo()
-//          bar()
-//
-//
-// while x>0
-//    while y>0
-//          foo()
-//        bar()
-//
-//
-//
-//";
-//  output "smt:{while:{>:{{x} {0}} while:{>:{{y} {0}} sbb:{{f o o} {b a r}}}} while:{>:{{x} {0}} sbb:{while:{>:{{y} {0}} {f o o}} {b a r}}}}";
-//
-//indent  !  = ww
-//outdent !  = " "  outdent " "
-//           | " "  (~[]*)  "\n"
-//
-//w        !  = " " | "\n" | "\r"
-//ws       !  = w*
-//ww       !  = sp*
-//sp       !  = " "
-//any      !  = ~[]*
-//
-//s           = ws statement ws statement ws => smt
-//
-//block       = "\n" indent  blockBody
-//           &~ "\n" outdent ~[\ ] ~[]*
-//
-//blockBody   = statement
-//            > statement ws blockBody => "sbb"
-//
-//statement   = call
-//            | ^"while" expr block /ws
-//
-//expr        = ident
-//            | call
-//            | expr ^">" expr   /ws
-//            | num
-//
-//call        = expr "()"        /ws
-//
-//num         = [0-9]++
-//
-//ident       = [a-z]++ &~ keyword
-//keyword     = "if" | "then" | "else" | "while"
-//
-//
-//
-//}
-//
+testcase {
+
+    input "
+
+
+
+ while x>0
+    while y>0
+       foo()
+          bar()
+
+
+ while x>0
+    while y>0
+          foo()
+        bar()
+
+
+
+";
+  output "smt:{while:{>:{{x} {0}} while:{>:{{y} {0}} sbb:{{f o o} {b a r}}}} while:{>:{{x} {0}} sbb:{while:{>:{{y} {0}} {f o o}} {b a r}}}}";
+
+indent    = ww
+outdent   = " "  outdent " "
+          | " "  ((~[])*)  "\n"
+
+w          = " " | "\n" | "\r"
+ws         = w*
+ww         = sp*
+sp         = " "
+any        = (~[])*
+
+s          = smt:: ws! statement ws! statement ws!
+
+block       =        "\n"! indent!  blockBody
+           &~        "\n"! (" " outdent! " ") (~[\ ])! ((~[])*)!
+
+blockBody   =       statement
+            > sbb:: statement ws blockBody
+
+statement   = call
+            | ^"while" expr block /ws
+
+expr        = ident
+            | call
+            | expr ^">" expr   /ws
+            | num
 
+call        = expr "()"        /ws
+
+num         = [0-9]++
+
+ident       = [a-z]++ &~ keyword
+keyword     = "if" | "then" | "else" | "while"
+
+
+
+}
 
 testcase {
     input "abc                         ";
 
     s     = s2:: q " "*
     q     = a3:: [a-z] [a-z] [a-z]
-         &~ ~[] "b" ~[]*
+         &~ (~[])! "b" ((~[])*)!
 }
 
 testcase {
@@ -356,6 +302,7 @@ testcase {
 testcase {
     input "aaaaa";
     output "top:{a q:{{a a a}} a}";
+
     s = top:: z (q::"a"*) z
     z = a:: "a"
 }
@@ -368,7 +315,81 @@ testcase {
     Expr   = if::     "if" "(" Expr ")" IfBody     /ws
            | ident::  [a-z]++
     IfBody = else::   Expr            "else"  Expr /ws
-           | then::   Expr &~   (~[]* "else" !Expr /ws)
+           | then::   Expr &~   ((~[])* "else" Expr! /ws)
     ws     = [ ]**
 }
 
+
+testcase {
+    input "12111211";
+    output "ac:{{2 1 2 1}}";
+    //output "a:{{2 1 2 1}}";
+    //output "c:{{c:{1 1} c:{1 1}}}";
+
+    s   = ab:: ab
+        | ac:: ac
+        | bc:: bc
+        //| a  =>  "a"
+        //| b  =>  "b"
+        //| c  =>  "c"
+    ab   = a & b
+    ac   = a & c
+    bc   = b & c
+    a   = ("1" x)*
+    b   = ("b":: x "2")*
+    c   = ("c":: x "2" x "1")*
+    x   = [123]
+}
+
+// make sure follow restrictions are honored
+// when a string matches the empty string
+testcase {
+  input "xxx";
+  s = x:: "x" A "x" C "x"
+  A = B
+  B = "y"
+    | () -> ~"x"
+  C = D -> ~"x"
+  D = ()
+}
+
+testcase {
+  input "axxxxxc";
+  output "q:{a {x x x x x} c}";
+  s  = q:: A ws B? ws C
+  ws = [x]**
+  A  = a:: "a"
+  B  = b:: "b"
+  C  = c:: "c"
+}
+
+testcase {
+  input "aaaaaaaaaaaaaaaaaaaa";
+  output "";
+  s = As & AAs
+  As = () | As "a"
+  AAs = () | AAs "aa"
+}
+
+// pathological O(n^2) behavior
+testcase {
+  input "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+  output "x";
+          s = x:: ManyA!
+     ManyA =  ()
+            | x:: A ManyA
+          A = ()! ("a" & ManyAB)
+    ManyAB = ()
+            | "a" ManyAB
+            | "b" ManyAB
+
+}
+
+// another O(n^2) example, tickles different epsilon behaviors
+testcase {
+  input "aaaa";
+  output "x:{x:{x:{x}}}";
+  s = x:: s A! | ()
+  A = "a" & B
+  B = () | B "a"
+}