Add tests for left recusion in pegs

db4
Chris Double 2008-03-27 23:54:34 +13:00
parent 4e29081e93
commit f6b7f8197e
4 changed files with 53 additions and 5 deletions

View File

@ -142,4 +142,32 @@ IN: peg.ebnf.tests
{ f } [ { f } [
"Z" [EBNF foo=[^A-Z] EBNF] call "Z" [EBNF foo=[^A-Z] EBNF] call
] unit-test ] unit-test
[
#! Test direct left recursion. Currently left recursion should cause a
#! failure of that parser.
#! Not using packrat, so recursion causes data stack overflow
"1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] call
] must-fail
{ V{ 49 } } [
#! Test direct left recursion. Currently left recursion should cause a
#! failure of that parser.
#! Using packrat, so first part of expr fails, causing 2nd choice to be used
"1+1" [ [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] call ] with-packrat parse-result-ast
] unit-test
[
#! Test indirect left recursion. Currently left recursion should cause a
#! failure of that parser.
#! Not using packrat, so recursion causes data stack overflow
"1+1" [EBNF num=([0-9])+ x=expr expr=x "+" num | num EBNF] call
] must-fail
{ V{ 49 } } [
#! Test indirect left recursion. Currently left recursion should cause a
#! failure of that parser.
#! Using packrat, so first part of expr fails, causing 2nd choice to be used
"1+1" [ [EBNF num=([0-9])+ x=expr expr=x "+" num | num EBNF] call ] with-packrat parse-result-ast
] unit-test

View File

@ -266,7 +266,7 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
] [ ] make delay sp ; ] [ ] make delay sp ;
: transform-ebnf ( string -- object ) : transform-ebnf ( string -- object )
'ebnf' parse parse-result-ast transform ; 'ebnf' [ parse ] packrat-parse parse-result-ast transform ;
: check-parse-result ( result -- result ) : check-parse-result ( result -- result )
dup [ dup [
@ -281,7 +281,7 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
] if ; ] if ;
: ebnf>quot ( string -- hashtable quot ) : ebnf>quot ( string -- hashtable quot )
'ebnf' parse check-parse-result 'ebnf' [ parse ] with-packrat check-parse-result
parse-result-ast transform dup main swap at compile 1quotation ; parse-result-ast transform dup main swap at compile 1quotation ;
: [EBNF "EBNF]" parse-multiline-string ebnf>quot nip parsed ; parsing : [EBNF "EBNF]" parse-multiline-string ebnf>quot nip parsed ; parsing

View File

@ -179,4 +179,20 @@ IN: peg.tests
[ [
"1+1" swap parse parse-result-ast "1+1" swap parse parse-result-ast
] with-packrat ] with-packrat
] unit-test ] unit-test
: expr ( -- parser )
#! Test direct left recursion. Currently left recursion should cause a
#! failure of that parser.
[ expr ] delay "+" token "1" token 3seq "1" token 2choice ;
[
#! Not using packrat, so recursion causes data stack overflow
"1+1" expr parse parse-result-ast
] must-fail
{ "1" } [
#! Using packrat, so expr fails, causing the 2nd choice to be used.
"1+1" expr [ parse ] with-packrat parse-result-ast
] unit-test

View File

@ -39,7 +39,11 @@ GENERIC: (compile) ( parser -- quot )
#! from the input cache. If the item is not in the cache, #! from the input cache. If the item is not in the cache,
#! call 'quot' with 'input' on the stack to get the result #! call 'quot' with 'input' on the stack to get the result
#! and store that in the cache and return it. #! and store that in the cache and return it.
n input-cache [ drop input quot call ] cache ; inline n input-cache [
drop
f n input-cache set-at
input quot call
] cache ; inline
:: run-packrat-parser ( input quot c -- result ) :: run-packrat-parser ( input quot c -- result )
input input-from input input-from