diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index 335607b463..4828ace9af 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -1,14 +1,19 @@ ! Copyright (C) 2007 Chris Double. ! 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 peg.parsers unicode.categories multiline combinators combinators.lib splitting accessors effects sequences.deep peg.search inference - io.streams.string io prettyprint ; + io.streams.string io prettyprint parser ; 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-terminal symbol ; +TUPLE: ebnf-foreign word rule ; TUPLE: ebnf-any-character ; TUPLE: ebnf-range pattern ; TUPLE: ebnf-ensure group ; @@ -27,6 +32,7 @@ TUPLE: ebnf rules ; C: ebnf-non-terminal C: ebnf-terminal +C: ebnf-foreign C: ebnf-any-character C: ebnf-range C: ebnf-ensure @@ -88,6 +94,8 @@ C: ebnf [ dup CHAR: ? = ] [ dup CHAR: : = ] [ dup CHAR: ~ = ] + [ dup CHAR: < = ] + [ dup CHAR: > = ] } 0|| not nip ] satisfy repeat1 [ >string ] action ; @@ -96,6 +104,24 @@ C: ebnf #! and it represents the literal value of the identifier. 'identifier' [ ] 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 + [ + "" syntax , + ] seq* [ first2 ] action ; + : 'any-character' ( -- parser ) #! A parser to match the symbol for any character match. [ CHAR: . = ] satisfy [ drop ] action ; @@ -117,6 +143,7 @@ C: ebnf [ 'non-terminal' , 'terminal' , + 'foreign' , 'range-parser' , 'any-character' , ] choice* , @@ -367,6 +394,15 @@ M: ebnf-var (transform) ( ast -- parser ) M: ebnf-terminal (transform) ( ast -- parser ) 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." % @@ -411,6 +447,3 @@ M: ebnf-non-terminal (transform) ( ast -- parser ) ";EBNF" parse-multiline-string replace-escapes ebnf>quot swapd 1 1 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 ; \ No newline at end of file