Add tests for semantic and add syntax for it to ebnf

Syntax is ?[ ...]?
For example:
[EBNF num=. ?[ number? ]? list=list:x num:y => [[ drop x y + ]] | num EBNF] { 1 2 3 4 5 6 } swap call .
db4
Chris Double 2008-03-31 16:50:05 +13:00
parent c45eba6898
commit f66774e875
3 changed files with 35 additions and 6 deletions

View File

@ -168,6 +168,18 @@ IN: peg.ebnf.tests
"4+2" [EBNF foo=[0-9]:x '+' [0-9]:y => [[ drop x digit> y digit> + ]] EBNF] call parse-result-ast "4+2" [EBNF foo=[0-9]:x '+' [0-9]:y => [[ drop x digit> y digit> + ]] EBNF] call parse-result-ast
] unit-test ] unit-test
{ 10 } [
{ 1 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ drop x y + ]] | num EBNF] call parse-result-ast
] unit-test
{ f } [
{ "a" 2 3 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ drop x y + ]] | num EBNF] call
] unit-test
{ 3 } [
{ 1 2 "a" 4 } [EBNF num=. ?[ number? ]? list=list:x num:y => [[ drop x y + ]] | num EBNF] call parse-result-ast
] unit-test
{ V{ V{ 49 } "+" V{ 49 } } } [ { V{ V{ 49 } "+" V{ 49 } } } [
#! Test direct left recursion. #! Test direct left recursion.
#! Using packrat, so first part of expr fails, causing 2nd choice to be used #! Using packrat, so first part of expr fails, causing 2nd choice to be used

View File

@ -20,6 +20,7 @@ TUPLE: ebnf-optional group ;
TUPLE: ebnf-rule symbol elements ; TUPLE: ebnf-rule symbol elements ;
TUPLE: ebnf-action parser code ; TUPLE: ebnf-action parser code ;
TUPLE: ebnf-var parser name ; TUPLE: ebnf-var parser name ;
TUPLE: ebnf-semantic parser code ;
TUPLE: ebnf rules ; TUPLE: ebnf rules ;
C: <ebnf-non-terminal> ebnf-non-terminal C: <ebnf-non-terminal> ebnf-non-terminal
@ -36,6 +37,7 @@ C: <ebnf-optional> ebnf-optional
C: <ebnf-rule> ebnf-rule C: <ebnf-rule> ebnf-rule
C: <ebnf-action> ebnf-action C: <ebnf-action> ebnf-action
C: <ebnf-var> ebnf-var C: <ebnf-var> ebnf-var
C: <ebnf-semantic> ebnf-semantic
C: <ebnf> ebnf C: <ebnf> ebnf
: syntax ( string -- parser ) : syntax ( string -- parser )
@ -156,6 +158,7 @@ DEFER: 'choice'
: 'factor-code' ( -- parser ) : 'factor-code' ( -- parser )
[ [
"]]" token ensure-not , "]]" token ensure-not ,
"]?" token ensure-not ,
[ drop t ] satisfy , [ drop t ] satisfy ,
] seq* [ first ] action repeat0 [ >string ] action ; ] seq* [ first ] action repeat0 [ >string ] action ;
@ -193,14 +196,15 @@ DEFER: 'choice'
: 'action' ( -- parser ) : 'action' ( -- parser )
"[[" 'factor-code' "]]" syntax-pack ; "[[" 'factor-code' "]]" syntax-pack ;
: 'semantic' ( -- parser )
"?[" 'factor-code' "]?" syntax-pack ;
: 'sequence' ( -- parser ) : 'sequence' ( -- parser )
#! A sequence of terminals and non-terminals, including #! A sequence of terminals and non-terminals, including
#! groupings of those. #! groupings of those.
[ [
[ [ ('sequence') , 'action' , ] seq* [ first2 <ebnf-action> ] action ,
('sequence') , [ ('sequence') , 'semantic' , ] seq* [ first2 <ebnf-semantic> ] action ,
'action' ,
] seq* [ first2 <ebnf-action> ] action ,
('sequence') , ('sequence') ,
] choice* repeat1 [ ] choice* repeat1 [
dup length 1 = [ first ] [ <ebnf-sequence> ] if dup length 1 = [ first ] [ <ebnf-sequence> ] if
@ -295,6 +299,10 @@ M: ebnf-action (transform) ( ast -- parser )
[ parser>> (transform) ] keep [ parser>> (transform) ] keep
code>> vars get build-locals string-lines [ parse-lines ] with-compilation-unit action ; code>> vars get build-locals string-lines [ parse-lines ] with-compilation-unit action ;
M: ebnf-semantic (transform) ( ast -- parser )
[ parser>> (transform) ] keep
code>> vars get build-locals string-lines [ parse-lines ] with-compilation-unit semantic ;
M: ebnf-var (transform) ( ast -- parser ) M: ebnf-var (transform) ( ast -- parser )
[ parser>> (transform) ] [ name>> ] bi [ parser>> (transform) ] [ name>> ] bi
dup vars get push [ dupd set ] curry action ; dup vars get push [ dupd set ] curry action ;

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 strings namespaces arrays sequences peg peg.private accessors words ; USING: kernel tools.test strings namespaces arrays sequences peg peg.private accessors words math ;
IN: peg.tests IN: peg.tests
{ f } [ { f } [
@ -182,4 +182,13 @@ IN: peg.tests
[ f , "a" token , ] seq* [ f , "a" token , ] seq*
dup parsers>> dup parsers>>
dupd 0 swap set-nth compile word? dupd 0 swap set-nth compile word?
] unit-test ] unit-test
{ f } [
"A" [ drop t ] satisfy [ 66 >= ] semantic parse
] unit-test
{ CHAR: B } [
"B" [ drop t ] satisfy [ 66 >= ] semantic parse parse-result-ast
] unit-test