{ ... } 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 T{ ebnf-sequence f
V{ V{
T{ ebnf-non-terminal f "one" } T{ ebnf-non-terminal f "one" }
T{ ebnf-choice f T{ ebnf-whitespace f
V{ T{ ebnf-non-terminal f "two" } T{ ebnf-non-terminal f "three" } } 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 ] unit-test
{ {
@ -302,26 +304,63 @@ main = Primary
"abc" [EBNF a="a" "b" foo=(a "c") EBNF] call parse-result-ast "abc" [EBNF a="a" "b" foo=(a "c") EBNF] call parse-result-ast
] unit-test ] 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 } [ { f } [
"a bc" [EBNF a="a" "b" foo=(a "c") EBNF] call "a bc" [EBNF a="a" "b" foo=(a "c") EBNF] call
] unit-test ] 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 } [ { f } [
"ab c" [EBNF a="a" "b" foo=(a "c") EBNF] call "ab c" [EBNF a="a" "b" foo=(a "c") EBNF] call
] unit-test ] unit-test
{ f } [ { f } [
"a b c" [EBNF a="a" "b" foo=(a "c") EBNF] call "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
] unit-test ] unit-test
{ f } [ { 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 ] 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 #! Parse a group of choices, with a suffix indicating
#! the type of group (repeat0, repeat1, etc) and #! the type of group (repeat0, repeat1, etc) and
#! an quot that is the action that produces the AST. #! an quot that is the action that produces the AST.
"(" [ 'choice' sp ] delay ")" syntax-pack 2dup
swap 2seq [
[ first ] rot compose action ; "(" [ '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 ) : 'group' ( -- parser )
#! A grouping with no suffix. Used for precedence. #! 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 ,
"?" token sp ensure-not , "?" token sp ensure-not ,
"~" token sp ensure-not ,
] seq* hide grouped ; ] seq* hide grouped ;
: 'repeat0' ( -- parser ) : 'repeat0' ( -- parser )
@ -159,9 +164,6 @@ DEFER: 'choice'
: 'optional' ( -- parser ) : 'optional' ( -- parser )
[ <ebnf-optional> ] "?" syntax grouped ; [ <ebnf-optional> ] "?" syntax grouped ;
: 'whitespace' ( -- parser )
[ <ebnf-whitespace> ] "~" syntax grouped ;
: 'factor-code' ( -- parser ) : 'factor-code' ( -- parser )
[ [
"]]" token ensure-not , "]]" token ensure-not ,
@ -198,7 +200,6 @@ DEFER: 'choice'
'repeat0' sp , 'repeat0' sp ,
'repeat1' sp , 'repeat1' sp ,
'optional' sp , 'optional' sp ,
'whitespace' sp ,
] choice* ; ] choice* ;
: 'action' ( -- parser ) : 'action' ( -- parser )

View File

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