{ ... } whitespace grouping

db4
Chris Double 2008-04-29 14:15:05 +12:00
parent 7319dd5165
commit c671ccce99
3 changed files with 77 additions and 67 deletions

View File

@ -51,13 +51,15 @@ IN: peg.ebnf.tests
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" } }
T{ ebnf-whitespace f
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
"one {two | three}" 'choice' parse parse-result-ast
] unit-test
{
@ -302,26 +304,63 @@ main = Primary
"abc" [EBNF a="a" "b" foo=(a "c") EBNF] call parse-result-ast
] unit-test
{ V{ V{ "a" "b" } "c" } } [
"abc" [EBNF a="a" "b" foo={a "c"} EBNF] call parse-result-ast
] unit-test
{ V{ V{ "a" "b" } "c" } } [
"abc" [EBNF a="a" "b" foo=a "c" EBNF] call parse-result-ast
] unit-test
{ f } [
"a bc" [EBNF a="a" "b" foo=(a "c") EBNF] call
] unit-test
{ f } [
"a bc" [EBNF a="a" "b" foo=a "c" EBNF] call
] unit-test
{ f } [
"a bc" [EBNF a="a" "b" foo={a "c"} EBNF] call
] unit-test
{ f } [
"ab c" [EBNF a="a" "b" foo=a "c" EBNF] call
] unit-test
{ V{ V{ "a" "b" } "c" } } [
"ab c" [EBNF a="a" "b" foo={a "c"} EBNF] call parse-result-ast
] unit-test
{ f } [
"ab c" [EBNF a="a" "b" foo=(a "c") EBNF] call
] unit-test
{ f } [
"a b c" [EBNF a="a" "b" foo=(a "c") EBNF] call
] unit-test
{ V{ V{ "a" "b" } "c" } } [
"abc" [EBNF a="a" "b" foo=(a "c")~ EBNF] call parse-result-ast
] unit-test
{ V{ V{ "a" "b" } "c" } } [
"ab c" [EBNF a="a" "b" foo=(a "c")~ EBNF] call parse-result-ast
"a b c" [EBNF a="a" "b" foo=a "c" EBNF] call
] unit-test
{ f } [
"a bc" [EBNF a="a" "b" foo=(a "c")~ EBNF] call
"a b c" [EBNF a="a" "b" foo=(a "c") EBNF] call
] unit-test
{ f } [
"a b c" [EBNF a="a" "b" foo={a "c"} EBNF] call
] unit-test
{ V{ V{ V{ "a" "b" } "c" } V{ V{ "a" "b" } "c" } } } [
"ab cab c" [EBNF a="a" "b" foo={a "c"}* EBNF] call parse-result-ast
] unit-test
{ V{ } } [
"ab cab c" [EBNF a="a" "b" foo=(a "c")* EBNF] call parse-result-ast
] unit-test
{ V{ V{ V{ "a" "b" } "c" } V{ V{ "a" "b" } "c" } } } [
"ab c ab c" [EBNF a="a" "b" foo={a "c"}* EBNF] call parse-result-ast
] unit-test
{ V{ } } [
"ab c ab c" [EBNF a="a" "b" foo=(a "c")* EBNF] call parse-result-ast
] unit-test

View File

@ -137,9 +137,15 @@ DEFER: 'choice'
#! Parse a group of choices, with a suffix indicating
#! the type of group (repeat0, repeat1, etc) and
#! an quot that is the action that produces the AST.
"(" [ 'choice' sp ] delay ")" syntax-pack
swap 2seq
[ first ] rot compose action ;
2dup
[
"(" [ 'choice' sp ] delay ")" syntax-pack
swap 2seq
[ first ] rot compose action ,
"{" [ 'choice' sp ] delay "}" syntax-pack
swap 2seq
[ first <ebnf-whitespace> ] rot compose action ,
] choice* ;
: 'group' ( -- parser )
#! A grouping with no suffix. Used for precedence.
@ -147,7 +153,6 @@ DEFER: 'choice'
"*" token sp ensure-not ,
"+" token sp ensure-not ,
"?" token sp ensure-not ,
"~" token sp ensure-not ,
] seq* hide grouped ;
: 'repeat0' ( -- parser )
@ -159,9 +164,6 @@ DEFER: 'choice'
: 'optional' ( -- parser )
[ <ebnf-optional> ] "?" syntax grouped ;
: 'whitespace' ( -- parser )
[ <ebnf-whitespace> ] "~" syntax grouped ;
: 'factor-code' ( -- parser )
[
"]]" token ensure-not ,
@ -198,7 +200,6 @@ DEFER: 'choice'
'repeat0' sp ,
'repeat1' sp ,
'optional' sp ,
'whitespace' sp ,
] choice* ;
: 'action' ( -- parser )

View File

@ -7,52 +7,22 @@ IN: peg.pl0
#! Grammar for PL/0 based on http://en.wikipedia.org/wiki/PL/0
EBNF: pl0
_ = (" " | "\t" | "\n")* => [[ drop ignore ]]
BEGIN = "BEGIN" _
CALL = "CALL" _
CONST = "CONST" _
DO = "DO" _
END = "END" _
IF = "IF" _
THEN = "THEN" _
ODD = "ODD" _
PROCEDURE = "PROCEDURE" _
VAR = "VAR" _
WHILE = "WHILE" _
EQ = "=" _
LTEQ = "<=" _
LT = "<" _
GT = ">" _
GTEQ = ">=" _
NEQ = "#" _
COMMA = "," _
SEMICOLON = ";" _
ASSIGN = ":=" _
ADD = "+" _
SUBTRACT = "-" _
MULTIPLY = "*" _
DIVIDE = "/" _
LPAREN = "(" _
RPAREN = ")" _
block = ( CONST ident EQ number ( COMMA ident EQ number )* SEMICOLON )?
( VAR ident ( COMMA ident )* SEMICOLON )?
( PROCEDURE ident SEMICOLON ( block SEMICOLON )? )* statement
statement = ( ident ASSIGN expression
| CALL ident
| BEGIN statement ( SEMICOLON statement )* END
| IF condition THEN statement
| WHILE condition DO statement )?
condition = ODD expression
| expression (EQ | NEQ | LTEQ | LT | GTEQ | GT) expression
expression = (ADD | SUBTRACT)? term ( (ADD | SUBTRACT) term )* _
term = factor ( (MULTIPLY | DIVIDE) factor )*
factor = ident | number | LPAREN expression RPAREN
ident = (([a-zA-Z])+) _ => [[ >string ]]
block = { "CONST" ident "=" number { "," ident "=" number }* ";" }?
{ "VAR" ident { "," ident }* ";" }?
{ "PROCEDURE" ident ";" { block ";" }? }* statement
statement = { ident ":=" expression
| "CALL" ident
| "BEGIN" statement { ";" statement }* "END"
| "IF" condition "THEN" statement
| "WHILE" condition "DO" statement }?
condition = { "ODD" expression }
| { expression ("=" | "#" | "<=" | "<" | ">=" | ">") expression }
expression = {"+" | "-"}? term { {"+" | "-"} term }*
term = factor { {"*" | "/"} factor }*
factor = ident | number | "(" expression ")"
ident = (([a-zA-Z])+) => [[ >string ]]
digit = ([0-9]) => [[ digit> ]]
number = ((digit)+) _ => [[ 10 digits>integer ]]
program = _ block "."
number = (digit)+ => [[ 10 digits>integer ]]
program = { block "." }
;EBNF