Add optional to ebnf

release
Chris Double 2007-11-28 15:49:14 +13:00
parent d68a78c4a6
commit e0adc1a7fa
2 changed files with 29 additions and 3 deletions

View File

@ -84,4 +84,16 @@ IN: temporary
}
} [
"one {(two | three) four}" 'choice' parse parse-result-ast
] unit-test
] 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

View File

@ -8,6 +8,7 @@ TUPLE: ebnf-terminal symbol ;
TUPLE: ebnf-choice options ;
TUPLE: ebnf-sequence elements ;
TUPLE: ebnf-repeat0 group ;
TUPLE: ebnf-optional elements ;
TUPLE: ebnf-rule symbol elements ;
TUPLE: ebnf-action word ;
TUPLE: ebnf rules ;
@ -17,6 +18,7 @@ C: <ebnf-terminal> ebnf-terminal
C: <ebnf-choice> ebnf-choice
C: <ebnf-sequence> ebnf-sequence
C: <ebnf-repeat0> ebnf-repeat0
C: <ebnf-optional> ebnf-optional
C: <ebnf-rule> ebnf-rule
C: <ebnf-action> ebnf-action
C: <ebnf> ebnf
@ -30,7 +32,8 @@ M: ebnf-terminal ebnf-compile ( ast -- quot )
M: ebnf-non-terminal ebnf-compile ( ast -- quot )
[
ebnf-non-terminal-symbol , \ in , \ get , \ lookup , \ execute ,
[ ebnf-non-terminal-symbol , \ search , \ execute , ] [ ] make
, \ delay ,
] [ ] make ;
M: ebnf-choice ebnf-compile ( ast -- quot )
@ -58,6 +61,11 @@ M: ebnf-repeat0 ebnf-compile ( ast -- quot )
ebnf-repeat0-group ebnf-compile % \ repeat0 ,
] [ ] make ;
M: ebnf-optional ebnf-compile ( ast -- quot )
[
ebnf-optional-elements ebnf-compile % \ optional ,
] [ ] make ;
M: ebnf-rule ebnf-compile ( ast -- quot )
[
dup ebnf-rule-symbol , \ in , \ get , \ create ,
@ -109,8 +117,14 @@ DEFER: 'choice'
"}" token sp hide
3array seq [ first <ebnf-repeat0> ] action ;
: 'optional' ( -- parser )
"[" token sp hide
[ 'choice' sp ] delay
"]" token sp hide
3array seq [ first <ebnf-optional> ] action ;
: 'sequence' ( -- parser )
'element' sp 'group' sp 'repeat0' sp 3array choice
'element' sp 'group' sp 'repeat0' sp 'optional' sp 4array choice
repeat1 [
dup length 1 = [ first ] [ <ebnf-sequence> ] if
] action ;