Change ebnf-action to properly nest with attached parser
This allows removal of last-parser hack. Syntax of EBNF changes though. Now an action must attach to a group: <EBNF foo = (a b c) [[ ...act on group... ]] EBNF>db4
parent
65fabeec11
commit
92d8140d87
|
@ -15,11 +15,8 @@ IN: peg.ebnf.tests
|
|||
{
|
||||
T{ ebnf-rule f
|
||||
"digit"
|
||||
V{
|
||||
T{ ebnf-choice f
|
||||
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
|
||||
}
|
||||
f
|
||||
T{ ebnf-choice f
|
||||
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
|
||||
}
|
||||
}
|
||||
} [
|
||||
|
@ -29,11 +26,8 @@ IN: peg.ebnf.tests
|
|||
{
|
||||
T{ ebnf-rule f
|
||||
"digit"
|
||||
V{
|
||||
T{ ebnf-sequence f
|
||||
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
|
||||
}
|
||||
f
|
||||
T{ ebnf-sequence f
|
||||
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
|
||||
}
|
||||
}
|
||||
} [
|
||||
|
@ -119,9 +113,9 @@ IN: peg.ebnf.tests
|
|||
] unit-test
|
||||
|
||||
{ V{ 1 "b" } } [
|
||||
"foo='a' [[ drop 1 ]] 'b'" ebnf>quot with-compilation-unit "ab" foo parse parse-result-ast
|
||||
"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
|
||||
"foo=('a') [[ drop 1 ]] ('b') [[ drop 2 ]]" ebnf>quot with-compilation-unit "ab" foo parse parse-result-ast
|
||||
] unit-test
|
|
@ -16,7 +16,7 @@ TUPLE: ebnf-repeat0 group ;
|
|||
TUPLE: ebnf-repeat1 group ;
|
||||
TUPLE: ebnf-optional elements ;
|
||||
TUPLE: ebnf-rule symbol elements ;
|
||||
TUPLE: ebnf-action code ;
|
||||
TUPLE: ebnf-action parser code ;
|
||||
TUPLE: ebnf rules ;
|
||||
|
||||
C: <ebnf-non-terminal> ebnf-non-terminal
|
||||
|
@ -34,12 +34,10 @@ C: <ebnf> ebnf
|
|||
|
||||
SYMBOL: parsers
|
||||
SYMBOL: non-terminals
|
||||
SYMBOL: last-parser
|
||||
|
||||
: reset-parser-generation ( -- )
|
||||
V{ } clone parsers set
|
||||
H{ } clone non-terminals set
|
||||
f last-parser set ;
|
||||
H{ } clone non-terminals set ;
|
||||
|
||||
: store-parser ( parser -- number )
|
||||
parsers get [ push ] keep length 1- ;
|
||||
|
@ -57,7 +55,7 @@ SYMBOL: last-parser
|
|||
GENERIC: (generate-parser) ( ast -- id )
|
||||
|
||||
: generate-parser ( ast -- id )
|
||||
(generate-parser) dup last-parser set ;
|
||||
(generate-parser) ;
|
||||
|
||||
M: ebnf-terminal (generate-parser) ( ast -- id )
|
||||
ebnf-terminal-symbol token sp store-parser ;
|
||||
|
@ -99,15 +97,12 @@ M: ebnf-rule (generate-parser) ( ast -- id )
|
|||
swap [ parsers get set-nth ] keep ;
|
||||
|
||||
M: ebnf-action (generate-parser) ( ast -- id )
|
||||
ebnf-action-code string-lines parse-lines
|
||||
last-parser get get-parser swap action store-parser ;
|
||||
[ ebnf-action-parser generate-parser get-parser ] keep
|
||||
ebnf-action-code string-lines parse-lines action store-parser ;
|
||||
|
||||
M: vector (generate-parser) ( ast -- id )
|
||||
[ generate-parser ] map peek ;
|
||||
|
||||
M: f (generate-parser) ( ast -- id )
|
||||
drop last-parser get ;
|
||||
|
||||
M: ebnf (generate-parser) ( ast -- id )
|
||||
ebnf-rules [
|
||||
generate-parser
|
||||
|
@ -199,6 +194,7 @@ DEFER: 'choice'
|
|||
"*" token sp ensure-not ,
|
||||
"+" token sp ensure-not ,
|
||||
"?" token sp ensure-not ,
|
||||
"[[" token sp ensure-not ,
|
||||
] seq* hide grouped ;
|
||||
|
||||
: 'repeat0' ( -- parser )
|
||||
|
@ -210,6 +206,19 @@ DEFER: 'choice'
|
|||
: 'optional' ( -- parser )
|
||||
[ <ebnf-optional> ] "?" syntax grouped ;
|
||||
|
||||
: 'factor-code' ( -- parser )
|
||||
[
|
||||
"]]" token ensure-not ,
|
||||
[ drop t ] satisfy ,
|
||||
] seq* [ first ] action repeat0 [ >string ] action ;
|
||||
|
||||
: 'action' ( -- parser )
|
||||
[
|
||||
"(" [ 'choice' sp ] delay ")" syntax-pack ,
|
||||
"[[" 'factor-code' "]]" syntax-pack ,
|
||||
] seq* [ first2 <ebnf-action> ] action ;
|
||||
|
||||
|
||||
: 'ensure-not' ( -- parser )
|
||||
#! Parses the '!' syntax to ensure that
|
||||
#! something that matches the following elements do
|
||||
|
@ -229,6 +238,7 @@ DEFER: 'choice'
|
|||
'repeat0' sp ,
|
||||
'repeat1' sp ,
|
||||
'optional' sp ,
|
||||
'action' sp ,
|
||||
] choice* repeat1 [
|
||||
dup length 1 = [ first ] [ <ebnf-sequence> ] if
|
||||
] action ;
|
||||
|
@ -237,29 +247,12 @@ DEFER: 'choice'
|
|||
'sequence' sp "|" token sp list-of [
|
||||
dup length 1 = [ first ] [ <ebnf-choice> ] if
|
||||
] action ;
|
||||
|
||||
: 'factor-code' ( -- parser )
|
||||
[
|
||||
"]]" token ensure-not ,
|
||||
[ drop t ] satisfy ,
|
||||
] seq* [ first ] action repeat0 [ >string ] action ;
|
||||
|
||||
: 'action' ( -- parser )
|
||||
"[[" 'factor-code' "]]" syntax-pack [ <ebnf-action> ] action ;
|
||||
|
||||
: 'rhs' ( -- parser )
|
||||
[
|
||||
'choice' ,
|
||||
'action' sp optional ,
|
||||
] seq* repeat1 [
|
||||
dup length 1 = [ first ] [ <ebnf-sequence> ] if
|
||||
] action ;
|
||||
|
||||
: 'rule' ( -- parser )
|
||||
[
|
||||
'non-terminal' [ ebnf-non-terminal-symbol ] action ,
|
||||
"=" syntax ,
|
||||
'rhs' ,
|
||||
'choice' ,
|
||||
] seq* [ first2 <ebnf-rule> ] action ;
|
||||
|
||||
: 'ebnf' ( -- parser )
|
||||
|
|
Loading…
Reference in New Issue