remove => action and replace it with [[ code ]] in EBNF

Previously the action had to be a factor word and could only appear at the end of a rule:

  : aword ( ast -- ast ) drop V{ 1 2 } ;
  <EBNF foo = "a" "b" => aword EBNF>

Now actions can appear anywhere after an element, and can be any factor code between [[ ... ]] delimiters:

  <EBNF foo = "a" "b" [[ drop V{ 1 2 } ]] EBNF>
  <EBNF foo = "a" [[ drop 1 ]] "b" [[ drop 2 ]] EBNF>

Unfortunately since this means the ebnf>quot code uses the equivalent of eval, it no longer compiles nicely since it can't be inferred. The generated parsers however do compile.
db4
Chris Double 2008-03-20 02:16:30 +13:00
parent c0b7bdf823
commit 65fabeec11
2 changed files with 25 additions and 12 deletions

View File

@ -1,7 +1,7 @@
! 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 tools.test peg peg.ebnf ; USING: kernel tools.test peg peg.ebnf compiler.units ;
IN: peg.ebnf.tests IN: peg.ebnf.tests
{ T{ ebnf-non-terminal f "abc" } } [ { T{ ebnf-non-terminal f "abc" } } [
@ -114,4 +114,14 @@ IN: peg.ebnf.tests
"foo]" 'non-terminal' parse parse-result-ast ebnf-non-terminal-symbol "foo]" 'non-terminal' parse parse-result-ast ebnf-non-terminal-symbol
] unit-test ] unit-test
{ V{ "a" "b" } } [
"foo='a' 'b'" ebnf>quot with-compilation-unit "ab" foo parse parse-result-ast
] unit-test
{ V{ 1 "b" } } [
"foo='a' [[ drop 1 ]] 'b'" ebnf>quot with-compilation-unit "ab" foo parse parse-result-ast
] unit-test
{ V{ 1 2 } } [
"foo='a' [[ drop 1 ]] 'b' [[ drop 2 ]]" ebnf>quot with-compilation-unit "ab" foo parse parse-result-ast
] unit-test

View File

@ -2,7 +2,8 @@
! 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 combinators.lib ; peg.parsers unicode.categories multiline combinators.lib
splitting ;
IN: peg.ebnf IN: peg.ebnf
TUPLE: ebnf-non-terminal symbol ; TUPLE: ebnf-non-terminal symbol ;
@ -15,7 +16,7 @@ TUPLE: ebnf-repeat0 group ;
TUPLE: ebnf-repeat1 group ; TUPLE: ebnf-repeat1 group ;
TUPLE: ebnf-optional elements ; TUPLE: ebnf-optional elements ;
TUPLE: ebnf-rule symbol elements ; TUPLE: ebnf-rule symbol elements ;
TUPLE: ebnf-action word ; TUPLE: ebnf-action code ;
TUPLE: ebnf rules ; TUPLE: ebnf rules ;
C: <ebnf-non-terminal> ebnf-non-terminal C: <ebnf-non-terminal> ebnf-non-terminal
@ -98,7 +99,7 @@ M: ebnf-rule (generate-parser) ( ast -- id )
swap [ parsers get set-nth ] keep ; swap [ parsers get set-nth ] keep ;
M: ebnf-action (generate-parser) ( ast -- id ) M: ebnf-action (generate-parser) ( ast -- id )
ebnf-action-word search 1quotation ebnf-action-code string-lines parse-lines
last-parser get get-parser swap action store-parser ; last-parser get get-parser swap action store-parser ;
M: vector (generate-parser) ( ast -- id ) M: vector (generate-parser) ( ast -- id )
@ -237,20 +238,22 @@ DEFER: 'choice'
dup length 1 = [ first ] [ <ebnf-choice> ] if dup length 1 = [ first ] [ <ebnf-choice> ] if
] action ; ] action ;
: 'action' ( -- parser ) : 'factor-code' ( -- parser )
[ [
"=>" token hide , "]]" token ensure-not ,
[ [ drop t ] satisfy ,
[ blank? ] satisfy ensure-not , ] seq* [ first ] action repeat0 [ >string ] action ;
[ drop t ] satisfy ,
] seq* [ first ] action repeat1 [ >string ] action sp , : 'action' ( -- parser )
] seq* [ first <ebnf-action> ] action ; "[[" 'factor-code' "]]" syntax-pack [ <ebnf-action> ] action ;
: 'rhs' ( -- parser ) : 'rhs' ( -- parser )
[ [
'choice' , 'choice' ,
'action' sp optional , 'action' sp optional ,
] seq* ; ] seq* repeat1 [
dup length 1 = [ first ] [ <ebnf-sequence> ] if
] action ;
: 'rule' ( -- parser ) : 'rule' ( -- parser )
[ [