-//testcase {
-// input "x";
-// output "a:{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 {
+testcase "pathological O(n^2) behavior" {
+ input "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ output "x";
+ s = x:: ManyA!
+ ManyA = ()
+ | x:: A ManyA
+ A = ()! ("a" & ManyAB)
+ ManyAB = ()
+ | "a" ManyAB
+ | "b" ManyAB
+
+}
+
+testcase "another O(n^2) example, tickles different epsilon behaviors" {
+ input "aaaa";
+ output "x:{x:{x:{x}}}";
+ s = x:: s A! | ()
+ A = "a" & B
+ B = () | B "a"
+}
+
+testcase "unnamed" {
input "aaaaa";
s = A
A = "a" s &~ "a" A
| "a" A &~ "a" s
}
-//testcase {
-// input "a";
-// output "yes:{}";
-// s = A
-// A = "a" s &~ "a" A
-// | "a" A &~ "a" s
-// | ()
-//}
-
-testcase {
+testcase "unnamed" {
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]++
+ id = "":: [a-z]++
}
-testcase {
+testcase "unnamed" {
input "ab c";
output "2:{{a} 1:{{b} {c}}}";
ids = "1":: id " " ids
| "2":: id ids
| id
- id = [a-z]+
+ id = "":: [a-z]+
}
-testcase {
+testcase "unnamed" {
input "aaabbbccc";
output "ab";
d = "a" d "b" | ()
}
-testcase {
+testcase "unnamed" {
input "aaabbbbccc";
s = ab & dc
d = "a" d "b" | ()
}
-testcase {
+testcase "unnamed" {
input "aabb";
output "xbx:{{a} abab:{a b} {b}}";
x = ~[]
- s = xbx:: x* b x*
+ s = xbx:: ("":: x*) b ("":: x*)
b = abab:: [ab][ab]
- &~ ( "aa" | "bb" )
+ &~ ("aa"|"bb")
}
-testcase {
+testcase "unnamed" {
input "qxbambambam";
output "bam:{a bam:{a bam:{a x}}}";
a = a:: ()
}
-testcase {
+testcase "unnamed" {
input "baaaa";
output "s2:{b0 a:{a:{epsilon}}}";
output "b:{a:{a:{epsilon}} epsilon}";
| epsilon:: ()
}
-testcase {
+testcase "qaq" {
input "qaq";
- output "q:{a:{s1:{epsilon}}}";
+ output "q:{a:{s1}}";
s = ^"q" x "q"
x = ^"a" a
a = s1:: x
}
-testcase {
+testcase "unnamed" {
input "baa";
output "s1:{a2:{a2:{a0 b0} b0}}";
b = b0:: ()
}
-testcase {
+testcase "epsilon forests" {
input "aaa";
output "s3:{s3:{epsilon a0 epsilon epsilon} epsilon epsilon epsilon}";
| epsilon:: ()
}
-testcase {
+testcase "unnamed" {
input "aa";
output "poo:{poo:{poox poox} poox}";
output "poo:{poox poo:{poox poox}}";
| poox:: ()
}
-testcase {
+testcase "unnamed" {
input "baa";
output "s:{aa:{aa:{a b} b}}";
s = s:: "b" a
b = b:: ()
}
-testcase {
+testcase "unnamed" {
input "aaab";
output "sx:{b aa:{aa:{b b} b}}";
s = sx:: b d "a" "b"
b = b:: ()
}
-testcase {
+testcase "a+(b*c)" {
input "a+(b*c)";
output "+:{{a} *:{{b} {c}}}";
| r ^"*" r
| r ^"+" r
| "(" r ")"
- id = [a-z]++
+ id = "":: [a-z]++
}
-testcase {
+testcase "a+b-d*c" {
input "a+b-d*c";
- output "plus:{stringify:{{a}} minus:{stringify:{{b}} times:{stringify:{{d}} stringify:{{c}}}}}";
- output "times:{plus:{stringify:{{a}} minus:{stringify:{{b}} stringify:{{d}}}} stringify:{{c}}}";
- output "plus:{stringify:{{a}} times:{minus:{stringify:{{b}} stringify:{{d}}} stringify:{{c}}}}";
- output "times:{minus:{plus:{stringify:{{a}} stringify:{{b}}} stringify:{{d}}} stringify:{{c}}}";
- output "minus:{plus:{stringify:{{a}} stringify:{{b}}} times:{stringify:{{d}} stringify:{{c}}}}";
+ output "times:{plus:{stringify:{a} minus:{stringify:{b} stringify:{d}}} stringify:{c}}";
+ output "plus:{stringify:{a} times:{minus:{stringify:{b} stringify:{d}} stringify:{c}}}";
+ output "minus:{plus:{stringify:{a} stringify:{b}} times:{stringify:{d} stringify:{c}}}";
+ output "plus:{stringify:{a} minus:{stringify:{b} times:{stringify:{d} stringify:{c}}}}";
+ output "times:{minus:{plus:{stringify:{a} stringify:{b}} stringify:{d}} stringify:{c}}";
w = " "
l = id
s = assign:: l "=" q
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 {
+testcase "priority" {
input "a+b*c";
- output "plus:{stringify:{{a}} times:{stringify:{{b}} stringify:{{c}}}}";
+ output "plus:{stringify:{a} times:{stringify:{b} stringify:{c}}}";
w = " "
l = id
s = assign:: l "=" r
idl = [a-d]
}
-testcase {
+testcase "associativity" {
+ input "a*b*c";
+ output "times:{stringify:{a} times:{stringify:{b} stringify:{c}}}";
+ w = " "
+ l = id
+ s = assign:: l "=" r
+ | r
+ r = l
+ | assign:: l "=" r
+ | plus:: r "+" r
+ | times:: r "*" (r)
+ | "(" r ")"
+ | times:: r r
+ id = stringify:: idl++
+ idl = [a-d]
+}
+
+testcase "unnamed" {
input "aa bb";
- output "{q:{{a a}} q:{{b b}}}";
+ output "{q:{a a} q:{b b}}";
- s = q */ ws
+ s = "":: q */ ws
ws = " "*
q = q:: [a-z]++
}
-testcase {
+testcase "indentation" {
input "
indent = ww
outdent = " " outdent " "
- | " " ((~[])*) "\n"
+ | " " ("":: (~[])*) "\n"
w = " " | "\n" | "\r"
-ws = w*
-ww = sp*
+ws = "":: w*
+ww = "":: sp*
sp = " "
-any = (~[])*
+any = "":: (~[])*
s = smt:: ws! statement ws! statement ws!
-block = "\n"! indent! blockBody
- &~ "\n"! (" " outdent! " ") (~[\ ])! ((~[])*)!
+block = "\n" indent! blockBody
+ &~ "\n" (" " outdent! " ") ~[\ ]! ("":: ~[]*)!
blockBody = statement
> sbb:: statement ws blockBody
call = expr "()" /ws
-num = [0-9]++
+num = "":: [0-9]++
-ident = [a-z]++ &~ keyword
+ident = "":: [a-z]++ &~ keyword
keyword = "if" | "then" | "else" | "while"
}
-
-testcase {
+testcase "unnamed" {
input "abc ";
s = s2:: q " "*
q = a3:: [a-z] [a-z] [a-z]
- &~ (~[])! "b" ((~[])*)!
+ &~ ("":: ~[])! "b" ("":: ~[]*)!
}
-testcase {
+testcase "unnamed" {
input "abc ";
output "s:{a b c}";
s = s:: [a-z] [a-z] [a-z] " "*
}
-testcase {
+testcase "a+2" {
input "a+2";
output "Plus:{left:{Foo} right:{{2}}}";
s = Expr
- Expr = [0-9]++
+ Expr = "":: [0-9]++
| Plus:: (left::Expra) "+" (right::Expr)
Expra = Foo:: ("a" | "b")
}
-testcase {
+testcase "unnamed" {
input "aaaaa";
- output "top:{a q:{{a a a}} a}";
+ output "top:{a q a}";
s = top:: z (q::"a"*) z
z = a:: "a"
}
-testcase {
+testcase "dangling else" {
input "if (x) if (y) z else q";
- output "if:{ident:{{x}} else:{if:{ident:{{y}} then:{ident:{{z}}}} ident:{{q}}}}";
+ output "if:{ident:{x} else:{if:{ident:{y} then:{ident:{z}}} ident:{q}}}";
s = Expr
Expr = if:: "if" "(" Expr ")" IfBody /ws
| ident:: [a-z]++
IfBody = else:: Expr "else" Expr /ws
- | then:: Expr &~ ((~[])* "else" Expr! /ws)
- ws = [ ]**
+ | then:: Expr &~ (("":: (~[])*) "else" Expr! /ws)
+ ws = "":: [ ]**
}
-testcase {
+testcase "unnamed" {
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")*
+ a = "":: ("1" x)*
+ b = "":: ("b":: x "2")*
+ c = "":: ("c":: x "2" x "1")*
x = [123]
}
+testcase "follow restrictions on empty string" {
+ input "xxx";
+ s = x:: "x" A "x" C "x"
+ A = B
+ B = "y"
+ | () -> ~"x"
+ C = D -> ~"x"
+ D = ()
+}
-//testcase {
-// input "ab";
-//
-// s = a:"a" b:"b"
-//}
+testcase "unnamed" {
+ 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 "unnamed" {
+ input "aaaaaaaaaaaaaaaaaaaa";
+ output "";
+ s = As & AAs
+ As = () | As "a"
+ AAs = () | AAs "aa"
+}
+
+testcase "question mark" {
+ input "aa aba abba";
+ output "s:{Y Y Z}";
+ s = s:: X " " X " " X
+ X = Y > Z
+ Y = Y:: "a" B? "a"
+ Z = Z:: "a" "b"* "a"
+ B = "b"
+}
+
+testcase "operator: ... " {
+ input "aaabbbaaa abababababa";
+ output "s:{C:{a a a b b b a a a} B:{a b a b a b a b a b a}}";
+ s:: = A " " A
+ A = B > C
+ B:: = [ab]* &~ (... "bbb" ...)
+ C:: = [ab]*
+}
+
+testcase "operator: ~~" {
+ input "aaabbbaaa abababababa";
+ output "s:{C:{a a a b b b a a a} B:{a b a b a b a b a b a}}";
+ s:: = A " " A
+ A = B > C
+ B:: = ~~(... "bbb" ...)
+ C:: = [ab]*
+}
+
+testcase "lifts" {
+ input "a+(b*c)";
+ output "+:{a *:{id:{b} c}}";
+
+ s = r
+ r = id
+ | r ^"*" `r
+ | `r ^"+" r
+ | "(" r ")"
+ id:: = [a-z]++
+}
+
+testcase "epsilon as a positive conjunct" {
+ input "abababab";
+ s:: = X*
+ X:: = "a" ("b"+ & ())
+}
+testcase "epsilon as a negative conjunct" {
+ input "aaaaa";
+ s:: = X*
+ X:: = "a" ("b"* &~ ())
+}