From 65fabeec11956cf7d2d7ddacd50b33b7d6e10823 Mon Sep 17 00:00:00 2001 From: Chris Double Date: Thu, 20 Mar 2008 02:16:30 +1300 Subject: [PATCH] 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 } ; aword EBNF> Now actions can appear anywhere after an element, and can be any factor code between [[ ... ]] delimiters: 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. --- extra/peg/ebnf/ebnf-tests.factor | 12 +++++++++++- extra/peg/ebnf/ebnf.factor | 25 ++++++++++++++----------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index 6838bf3eca..63cec2f120 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2007 Chris Double. ! 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 { 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 ] 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 \ No newline at end of file diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index b500d82e98..2e0740663a 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -2,7 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel parser words arrays strings math.parser sequences 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 TUPLE: ebnf-non-terminal symbol ; @@ -15,7 +16,7 @@ TUPLE: ebnf-repeat0 group ; TUPLE: ebnf-repeat1 group ; TUPLE: ebnf-optional elements ; TUPLE: ebnf-rule symbol elements ; -TUPLE: ebnf-action word ; +TUPLE: ebnf-action code ; TUPLE: ebnf rules ; C: ebnf-non-terminal @@ -98,7 +99,7 @@ M: ebnf-rule (generate-parser) ( ast -- id ) swap [ parsers get set-nth ] keep ; 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 ; M: vector (generate-parser) ( ast -- id ) @@ -237,20 +238,22 @@ DEFER: 'choice' dup length 1 = [ first ] [ ] if ] action ; -: 'action' ( -- parser ) +: 'factor-code' ( -- parser ) [ - "=>" token hide , - [ - [ blank? ] satisfy ensure-not , - [ drop t ] satisfy , - ] seq* [ first ] action repeat1 [ >string ] action sp , - ] seq* [ first ] action ; + "]]" token ensure-not , + [ drop t ] satisfy , + ] seq* [ first ] action repeat0 [ >string ] action ; + +: 'action' ( -- parser ) + "[[" 'factor-code' "]]" syntax-pack [ ] action ; : 'rhs' ( -- parser ) [ 'choice' , 'action' sp optional , - ] seq* ; + ] seq* repeat1 [ + dup length 1 = [ first ] [ ] if + ] action ; : 'rule' ( -- parser ) [