Add support for calling foreign peg.ebnf rules

db4
Chris Double 2008-06-18 15:07:23 +12:00
parent dfa4926a84
commit 479fa6a5b5
1 changed files with 38 additions and 5 deletions

View File

@ -1,14 +1,19 @@
! Copyright (C) 2007 Chris Double. ! Copyright (C) 2007 Chris Double.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel compiler.units parser words arrays strings math.parser sequences USING: kernel compiler.units 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 combinators combinators.lib peg.parsers unicode.categories multiline combinators combinators.lib
splitting accessors effects sequences.deep peg.search inference splitting accessors effects sequences.deep peg.search inference
io.streams.string io prettyprint ; io.streams.string io prettyprint parser ;
IN: peg.ebnf IN: peg.ebnf
: rule ( name word -- parser )
#! Given an EBNF word produced from EBNF: return the EBNF rule
"ebnf-parser" word-prop at ;
TUPLE: ebnf-non-terminal symbol ; TUPLE: ebnf-non-terminal symbol ;
TUPLE: ebnf-terminal symbol ; TUPLE: ebnf-terminal symbol ;
TUPLE: ebnf-foreign word rule ;
TUPLE: ebnf-any-character ; TUPLE: ebnf-any-character ;
TUPLE: ebnf-range pattern ; TUPLE: ebnf-range pattern ;
TUPLE: ebnf-ensure group ; TUPLE: ebnf-ensure group ;
@ -27,6 +32,7 @@ TUPLE: ebnf rules ;
C: <ebnf-non-terminal> ebnf-non-terminal C: <ebnf-non-terminal> ebnf-non-terminal
C: <ebnf-terminal> ebnf-terminal C: <ebnf-terminal> ebnf-terminal
C: <ebnf-foreign> ebnf-foreign
C: <ebnf-any-character> ebnf-any-character C: <ebnf-any-character> ebnf-any-character
C: <ebnf-range> ebnf-range C: <ebnf-range> ebnf-range
C: <ebnf-ensure> ebnf-ensure C: <ebnf-ensure> ebnf-ensure
@ -88,6 +94,8 @@ C: <ebnf> ebnf
[ dup CHAR: ? = ] [ dup CHAR: ? = ]
[ dup CHAR: : = ] [ dup CHAR: : = ]
[ dup CHAR: ~ = ] [ dup CHAR: ~ = ]
[ dup CHAR: < = ]
[ dup CHAR: > = ]
} 0|| not nip } 0|| not nip
] satisfy repeat1 [ >string <ebnf-non-terminal> ] action ; ] satisfy repeat1 [ >string <ebnf-non-terminal> ] action ;
@ -96,6 +104,24 @@ C: <ebnf> ebnf
#! and it represents the literal value of the identifier. #! and it represents the literal value of the identifier.
'identifier' [ <ebnf-terminal> ] action ; 'identifier' [ <ebnf-terminal> ] action ;
: 'foreign-name' ( -- parser )
#! Parse a valid foreign parser name
[
{
[ dup blank? ]
[ dup CHAR: > = ]
} 0|| not nip
] satisfy repeat1 [ >string ] action ;
: 'foreign' ( -- parser )
#! A foreign call is a call to a rule in another ebnf grammar
[
"<foreign" syntax ,
'foreign-name' sp ,
'foreign-name' sp optional ,
">" syntax ,
] seq* [ first2 <ebnf-foreign> ] action ;
: 'any-character' ( -- parser ) : 'any-character' ( -- parser )
#! A parser to match the symbol for any character match. #! A parser to match the symbol for any character match.
[ CHAR: . = ] satisfy [ drop <ebnf-any-character> ] action ; [ CHAR: . = ] satisfy [ drop <ebnf-any-character> ] action ;
@ -117,6 +143,7 @@ C: <ebnf> ebnf
[ [
'non-terminal' , 'non-terminal' ,
'terminal' , 'terminal' ,
'foreign' ,
'range-parser' , 'range-parser' ,
'any-character' , 'any-character' ,
] choice* , ] choice* ,
@ -367,6 +394,15 @@ M: ebnf-var (transform) ( ast -- parser )
M: ebnf-terminal (transform) ( ast -- parser ) M: ebnf-terminal (transform) ( ast -- parser )
symbol>> token ; symbol>> token ;
M: ebnf-foreign (transform) ( ast -- parser )
dup word>> search
[ "Foreign word " swap word>> append " not found" append throw ] unless*
swap rule>> dup [
swap rule
] [
execute
] if ;
: parser-not-found ( name -- * ) : parser-not-found ( name -- * )
[ [
"Parser " % % " not found." % "Parser " % % " not found." %
@ -411,6 +447,3 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
";EBNF" parse-multiline-string replace-escapes ";EBNF" parse-multiline-string replace-escapes
ebnf>quot swapd 1 1 <effect> define-declared "ebnf-parser" set-word-prop ; parsing ebnf>quot swapd 1 1 <effect> define-declared "ebnf-parser" set-word-prop ; parsing
: rule ( name word -- parser )
#! Given an EBNF word produced from EBNF: return the EBNF rule
"ebnf-parser" word-prop at ;