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
|
T{ ebnf-rule f
|
||||||
"digit"
|
"digit"
|
||||||
V{
|
T{ ebnf-choice f
|
||||||
T{ ebnf-choice f
|
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
|
||||||
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
|
|
||||||
}
|
|
||||||
f
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} [
|
} [
|
||||||
|
@ -29,11 +26,8 @@ IN: peg.ebnf.tests
|
||||||
{
|
{
|
||||||
T{ ebnf-rule f
|
T{ ebnf-rule f
|
||||||
"digit"
|
"digit"
|
||||||
V{
|
T{ ebnf-sequence f
|
||||||
T{ ebnf-sequence f
|
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
|
||||||
V{ T{ ebnf-terminal f "1" } T{ ebnf-terminal f "2" } }
|
|
||||||
}
|
|
||||||
f
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} [
|
} [
|
||||||
|
@ -119,9 +113,9 @@ IN: peg.ebnf.tests
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
{ V{ 1 "b" } } [
|
{ 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
|
] unit-test
|
||||||
|
|
||||||
{ V{ 1 2 } } [
|
{ 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
|
] unit-test
|
|
@ -16,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 code ;
|
TUPLE: ebnf-action parser code ;
|
||||||
TUPLE: ebnf rules ;
|
TUPLE: ebnf rules ;
|
||||||
|
|
||||||
C: <ebnf-non-terminal> ebnf-non-terminal
|
C: <ebnf-non-terminal> ebnf-non-terminal
|
||||||
|
@ -34,12 +34,10 @@ C: <ebnf> ebnf
|
||||||
|
|
||||||
SYMBOL: parsers
|
SYMBOL: parsers
|
||||||
SYMBOL: non-terminals
|
SYMBOL: non-terminals
|
||||||
SYMBOL: last-parser
|
|
||||||
|
|
||||||
: reset-parser-generation ( -- )
|
: reset-parser-generation ( -- )
|
||||||
V{ } clone parsers set
|
V{ } clone parsers set
|
||||||
H{ } clone non-terminals set
|
H{ } clone non-terminals set ;
|
||||||
f last-parser set ;
|
|
||||||
|
|
||||||
: store-parser ( parser -- number )
|
: store-parser ( parser -- number )
|
||||||
parsers get [ push ] keep length 1- ;
|
parsers get [ push ] keep length 1- ;
|
||||||
|
@ -57,7 +55,7 @@ SYMBOL: last-parser
|
||||||
GENERIC: (generate-parser) ( ast -- id )
|
GENERIC: (generate-parser) ( ast -- id )
|
||||||
|
|
||||||
: generate-parser ( ast -- id )
|
: generate-parser ( ast -- id )
|
||||||
(generate-parser) dup last-parser set ;
|
(generate-parser) ;
|
||||||
|
|
||||||
M: ebnf-terminal (generate-parser) ( ast -- id )
|
M: ebnf-terminal (generate-parser) ( ast -- id )
|
||||||
ebnf-terminal-symbol token sp store-parser ;
|
ebnf-terminal-symbol token sp store-parser ;
|
||||||
|
@ -99,15 +97,12 @@ 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-code string-lines parse-lines
|
[ ebnf-action-parser generate-parser get-parser ] keep
|
||||||
last-parser get get-parser swap action store-parser ;
|
ebnf-action-code string-lines parse-lines action store-parser ;
|
||||||
|
|
||||||
M: vector (generate-parser) ( ast -- id )
|
M: vector (generate-parser) ( ast -- id )
|
||||||
[ generate-parser ] map peek ;
|
[ generate-parser ] map peek ;
|
||||||
|
|
||||||
M: f (generate-parser) ( ast -- id )
|
|
||||||
drop last-parser get ;
|
|
||||||
|
|
||||||
M: ebnf (generate-parser) ( ast -- id )
|
M: ebnf (generate-parser) ( ast -- id )
|
||||||
ebnf-rules [
|
ebnf-rules [
|
||||||
generate-parser
|
generate-parser
|
||||||
|
@ -199,6 +194,7 @@ DEFER: 'choice'
|
||||||
"*" token sp ensure-not ,
|
"*" token sp ensure-not ,
|
||||||
"+" token sp ensure-not ,
|
"+" token sp ensure-not ,
|
||||||
"?" token sp ensure-not ,
|
"?" token sp ensure-not ,
|
||||||
|
"[[" token sp ensure-not ,
|
||||||
] seq* hide grouped ;
|
] seq* hide grouped ;
|
||||||
|
|
||||||
: 'repeat0' ( -- parser )
|
: 'repeat0' ( -- parser )
|
||||||
|
@ -210,6 +206,19 @@ DEFER: 'choice'
|
||||||
: 'optional' ( -- parser )
|
: 'optional' ( -- parser )
|
||||||
[ <ebnf-optional> ] "?" syntax grouped ;
|
[ <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 )
|
: 'ensure-not' ( -- parser )
|
||||||
#! Parses the '!' syntax to ensure that
|
#! Parses the '!' syntax to ensure that
|
||||||
#! something that matches the following elements do
|
#! something that matches the following elements do
|
||||||
|
@ -229,6 +238,7 @@ DEFER: 'choice'
|
||||||
'repeat0' sp ,
|
'repeat0' sp ,
|
||||||
'repeat1' sp ,
|
'repeat1' sp ,
|
||||||
'optional' sp ,
|
'optional' sp ,
|
||||||
|
'action' sp ,
|
||||||
] choice* repeat1 [
|
] choice* repeat1 [
|
||||||
dup length 1 = [ first ] [ <ebnf-sequence> ] if
|
dup length 1 = [ first ] [ <ebnf-sequence> ] if
|
||||||
] action ;
|
] action ;
|
||||||
|
@ -237,29 +247,12 @@ DEFER: 'choice'
|
||||||
'sequence' sp "|" token sp list-of [
|
'sequence' sp "|" token sp list-of [
|
||||||
dup length 1 = [ first ] [ <ebnf-choice> ] if
|
dup length 1 = [ first ] [ <ebnf-choice> ] if
|
||||||
] action ;
|
] 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 )
|
: 'rule' ( -- parser )
|
||||||
[
|
[
|
||||||
'non-terminal' [ ebnf-non-terminal-symbol ] action ,
|
'non-terminal' [ ebnf-non-terminal-symbol ] action ,
|
||||||
"=" syntax ,
|
"=" syntax ,
|
||||||
'rhs' ,
|
'choice' ,
|
||||||
] seq* [ first2 <ebnf-rule> ] action ;
|
] seq* [ first2 <ebnf-rule> ] action ;
|
||||||
|
|
||||||
: 'ebnf' ( -- parser )
|
: 'ebnf' ( -- parser )
|
||||||
|
|
Loading…
Reference in New Issue