Minor tidyup of ebnf

db4
Chris Double 2008-03-19 17:34:28 +13:00
parent cc9a17b551
commit 7578538122
2 changed files with 49 additions and 10 deletions

View File

@ -97,3 +97,20 @@ IN: peg.ebnf.tests
} [ } [
"one [ two ] three" 'choice' parse parse-result-ast "one [ two ] three" 'choice' parse parse-result-ast
] unit-test ] 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

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel parser words arrays strings math.parser sequences USING: kernel parser words arrays strings math.parser sequences
quotations vectors namespaces math assocs continuations peg quotations vectors namespaces math assocs continuations peg
peg.parsers unicode.categories multiline ; peg.parsers unicode.categories multiline combinators.lib ;
IN: peg.ebnf IN: peg.ebnf
TUPLE: ebnf-non-terminal symbol ; TUPLE: ebnf-non-terminal symbol ;
@ -99,18 +99,40 @@ M: ebnf (generate-parser) ( ast -- id )
DEFER: 'rhs' DEFER: 'rhs'
: 'non-terminal' ( -- parser ) : 'identifier' ( -- parser )
#! Return a parser that parses an identifer delimited by
#! a quotation character. The quotation can be single
#! or double quotes. The AST produced is the identifier
#! between the quotes.
[ [
CHAR: a CHAR: z range , [ CHAR: " = not ] satisfy repeat1 "\"" "\"" surrounded-by ,
"-" token [ first ] action , [ CHAR: ' = not ] satisfy repeat1 "'" "'" surrounded-by ,
] choice* repeat1 [ >string <ebnf-non-terminal> ] action ; ] choice* [ >string ] action ;
: 'non-terminal' ( -- parser )
#! A non-terminal is the name of another rule. It can
#! be any non-blank character except for characters used
#! in the EBNF syntax itself.
[
{
[ dup blank? ]
[ dup CHAR: " = ]
[ dup CHAR: ' = ]
[ dup CHAR: | = ]
[ dup CHAR: { = ]
[ dup CHAR: } = ]
[ dup CHAR: = = ]
[ dup CHAR: ) = ]
[ dup CHAR: ( = ]
[ dup CHAR: ] = ]
[ dup CHAR: [ = ]
} || not nip
] satisfy repeat1 [ >string <ebnf-non-terminal> ] action ;
: 'terminal' ( -- parser ) : 'terminal' ( -- parser )
[ #! A terminal is an identifier enclosed in quotations
"'" token hide , #! and it represents the literal value of the identifier.
[ CHAR: ' = not ] satisfy repeat1 , 'identifier' [ <ebnf-terminal> ] action ;
"'" token hide ,
] seq* [ first >string <ebnf-terminal> ] action ;
: 'element' ( -- parser ) : 'element' ( -- parser )
[ [