diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor index e3c6586c89..5a4ecc5c2f 100644 --- a/extra/peg/ebnf/ebnf-tests.factor +++ b/extra/peg/ebnf/ebnf-tests.factor @@ -448,7 +448,7 @@ foo= 'd' ] unit-test [ - "USING: peg.ebnf ; [EBNF foo='a' foo='b' EBNF]" eval + "USING: peg.ebnf ; [EBNF foo='a' foo='b' EBNF]" eval drop ] must-fail diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor index cba48f5892..8f36218b61 100644 --- a/extra/peg/ebnf/ebnf.factor +++ b/extra/peg/ebnf/ebnf.factor @@ -63,12 +63,17 @@ C: ebnf #! begin and end. [ syntax ] 2dip syntax pack ; -: replace-escapes ( string -- string ) +#! Don't want to use 'replace' in an action since replace doesn't infer. +#! Do the compilation of the peg at parse time and call (replace). +PEG: escaper ( string -- ast ) [ "\\t" token [ drop "\t" ] action , "\\n" token [ drop "\n" ] action , "\\r" token [ drop "\r" ] action , - ] choice* replace ; + ] choice* any-char-parser 2array choice repeat0 ; + +: replace-escapes ( string -- string ) + escaper sift [ [ tree-write ] each ] with-string-writer ; : insert-escapes ( string -- string ) [ @@ -319,7 +324,11 @@ M: ebnf (transform) ( ast -- parser ) M: ebnf-rule (transform) ( ast -- parser ) dup elements>> (transform) [ - swap symbol>> dup get [ "Rule '" over append "' defined more than once" append throw ] [ set ] if + swap symbol>> dup get { [ tuple? ] [ delegate parser? ] } 1&& [ + "Rule '" over append "' defined more than once" append throw + ] [ + set + ] if ] keep ; M: ebnf-sequence (transform) ( ast -- parser )