factor/extra/peg/ebnf/ebnf-tests.factor

209 lines
5.0 KiB
Factor

! Copyright (C) 2007 Chris Double.
! See http://factorcode.org/license.txt for BSD license.
!
USING: kernel tools.test peg peg.ebnf words ;
IN: peg.ebnf.tests
{ T{ ebnf-non-terminal f "abc" } } [
"abc" 'non-terminal' parse parse-result-ast
] unit-test
{ T{ ebnf-terminal f "55" } } [
"'55'" 'terminal' parse parse-result-ast
] unit-test
{
T{ ebnf-rule f
"digit"
T{ ebnf-choice f
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
}
}
} [
"digit = '1' | '2'" 'rule' parse parse-result-ast
] unit-test
{
T{ ebnf-rule f
"digit"
T{ ebnf-sequence f
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
}
}
} [
"digit = '1' '2'" 'rule' parse parse-result-ast
] unit-test
{
T{ ebnf-choice f
V{
T{ ebnf-sequence f
V{ T{ ebnf-non-terminal f "one" } T{ ebnf-non-terminal f "two" } }
}
T{ ebnf-non-terminal f "three" }
}
}
} [
"one two | three" 'choice' parse parse-result-ast
] unit-test
{
T{ ebnf-sequence f
V{
T{ ebnf-non-terminal f "one" }
T{ ebnf-choice f
V{ T{ ebnf-non-terminal f "two" } T{ ebnf-non-terminal f "three" } }
}
}
}
} [
"one (two | three)" 'choice' parse parse-result-ast
] unit-test
{
T{ ebnf-sequence f
V{
T{ ebnf-non-terminal f "one" }
T{ ebnf-repeat0 f
T{ ebnf-sequence f
V{
T{ ebnf-choice f
V{ T{ ebnf-non-terminal f "two" } T{ ebnf-non-terminal f "three" } }
}
T{ ebnf-non-terminal f "four" }
}
}
}
}
}
} [
"one ((two | three) four)*" 'choice' parse parse-result-ast
] unit-test
{
T{ ebnf-sequence f
V{
T{ ebnf-non-terminal f "one" }
T{ ebnf-optional f T{ ebnf-non-terminal f "two" } }
T{ ebnf-non-terminal f "three" }
}
}
} [
"one ( two )? three" 'choice' parse parse-result-ast
] unit-test
{ "foo" } [
"\"foo\"" 'identifier' parse parse-result-ast
] unit-test
{ "foo" } [
"'foo'" 'identifier' parse parse-result-ast
] unit-test
{ "foo" } [
"foo" 'non-terminal' parse parse-result-ast ebnf-non-terminal-symbol
] unit-test
{ "foo" } [
"foo]" 'non-terminal' parse parse-result-ast ebnf-non-terminal-symbol
] unit-test
{ V{ "a" "b" } } [
"ab" [EBNF foo='a' 'b' EBNF] call parse-result-ast
] unit-test
{ V{ 1 "b" } } [
"ab" [EBNF foo=('a')[[ drop 1 ]] 'b' EBNF] call parse-result-ast
] unit-test
{ V{ 1 2 } } [
"ab" [EBNF foo=('a') [[ drop 1 ]] ('b') [[ drop 2 ]] EBNF] call parse-result-ast
] unit-test
{ CHAR: A } [
"A" [EBNF foo=[A-Z] EBNF] call parse-result-ast
] unit-test
{ CHAR: Z } [
"Z" [EBNF foo=[A-Z] EBNF] call parse-result-ast
] unit-test
{ f } [
"0" [EBNF foo=[A-Z] EBNF] call
] unit-test
{ CHAR: 0 } [
"0" [EBNF foo=[^A-Z] EBNF] call parse-result-ast
] unit-test
{ f } [
"A" [EBNF foo=[^A-Z] EBNF] call
] unit-test
{ f } [
"Z" [EBNF foo=[^A-Z] EBNF] call
] unit-test
{ V{ V{ 49 } "+" V{ 49 } } } [
#! Test direct left recursion.
#! Using packrat, so first part of expr fails, causing 2nd choice to be used
"1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] call parse-result-ast
] unit-test
{ V{ V{ V{ 49 } "+" V{ 49 } } "+" V{ 49 } } } [
#! Test direct left recursion.
#! Using packrat, so first part of expr fails, causing 2nd choice to be used
"1+1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] call parse-result-ast
] unit-test
{ V{ V{ V{ 49 } "+" V{ 49 } } "+" V{ 49 } } } [
#! Test indirect left recursion.
#! Using packrat, so first part of expr fails, causing 2nd choice to be used
"1+1+1" [EBNF num=([0-9])+ x=expr expr=x "+" num | num EBNF] call parse-result-ast
] unit-test
EBNF: primary
Primary = PrimaryNoNewArray
PrimaryNoNewArray = ClassInstanceCreationExpression
| MethodInvocation
| FieldAccess
| ArrayAccess
| "this"
ClassInstanceCreationExpression = "new" ClassOrInterfaceType "(" ")"
| Primary "." "new" Identifier "(" ")"
MethodInvocation = Primary "." MethodName "(" ")"
| MethodName "(" ")"
FieldAccess = Primary "." Identifier
| "super" "." Identifier
ArrayAccess = Primary "[" Expression "]"
| ExpressionName "[" Expression "]"
ClassOrInterfaceType = ClassName | InterfaceTypeName
ClassName = "C" | "D"
InterfaceTypeName = "I" | "J"
Identifier = "x" | "y" | ClassOrInterfaceType
MethodName = "m" | "n"
ExpressionName = Identifier
Expression = "i" | "j"
main = Primary
;EBNF
{ "this" } [
"this" primary parse-result-ast
] unit-test
{ V{ "this" "." "x" } } [
"this.x" primary parse-result-ast
] unit-test
{ V{ V{ "this" "." "x" } "." "y" } } [
"this.x.y" primary parse-result-ast
] unit-test
{ V{ V{ "this" "." "x" } "." "m" "(" ")" } } [
"this.x.m()" primary parse-result-ast
] unit-test
{ V{ V{ V{ "x" "[" "i" "]" } "[" "j" "]" } "." "y" } } [
"x[i][j].y" primary parse-result-ast
] unit-test