2009-03-09 21:36:35 -04:00
|
|
|
USING: hashtables assocs sequences locals math accessors multiline delegate strings
|
2009-03-11 19:40:14 -04:00
|
|
|
delegate.protocols kernel peg peg.ebnf lexer namespaces combinators parser words ;
|
2009-03-09 21:36:35 -04:00
|
|
|
IN: peg-lexer
|
|
|
|
|
|
|
|
TUPLE: lex-hash hash ;
|
|
|
|
CONSULT: assoc-protocol lex-hash hash>> ;
|
|
|
|
: <lex-hash> ( a -- lex-hash ) lex-hash boa ;
|
|
|
|
|
|
|
|
: pos-or-0 ( neg? -- pos/0 ) dup 0 < [ drop 0 ] when ;
|
|
|
|
|
2009-03-11 19:36:55 -04:00
|
|
|
:: prepare-pos ( v i -- c l )
|
|
|
|
[let | n [ i v head-slice ] |
|
|
|
|
v CHAR: \n n last-index -1 or 1+ -
|
|
|
|
n [ CHAR: \n = ] count 1+ ] ;
|
|
|
|
|
|
|
|
: store-pos ( v a -- ) input swap at prepare-pos
|
|
|
|
lexer get [ (>>line) ] keep (>>column) ;
|
2009-03-09 21:36:35 -04:00
|
|
|
|
|
|
|
M: lex-hash set-at swap {
|
|
|
|
{ pos [ store-pos ] }
|
|
|
|
[ swap hash>> set-at ] } case ;
|
|
|
|
|
2009-03-11 19:36:55 -04:00
|
|
|
:: at-pos ( t l c -- p ) t l head-slice [ length ] map sum l 1- + c + ;
|
2009-03-09 21:36:35 -04:00
|
|
|
|
|
|
|
M: lex-hash at* swap {
|
|
|
|
{ input [ drop lexer get text>> "\n" join t ] }
|
2009-03-11 19:36:55 -04:00
|
|
|
{ pos [ drop lexer get [ text>> ] [ line>> 1- ] [ column>> 1+ ] tri at-pos t ] }
|
2009-03-09 21:36:35 -04:00
|
|
|
[ swap hash>> at* ] } case ;
|
|
|
|
|
|
|
|
: with-global-lexer ( quot -- result )
|
|
|
|
[ f lrstack set
|
|
|
|
V{ } clone error-stack set H{ } clone \ heads set
|
|
|
|
H{ } clone \ packrat set ] f make-assoc <lex-hash>
|
|
|
|
swap bind ; inline
|
|
|
|
|
|
|
|
: parse* ( parser -- ast ) compile
|
|
|
|
[ execute [ error-stack get first throw ] unless* ] with-global-lexer
|
|
|
|
ast>> ;
|
|
|
|
|
2009-03-10 19:22:31 -04:00
|
|
|
: create-bnf ( name parser -- ) reset-tokenizer [ lexer get skip-blank parse* parsed ] curry
|
2009-03-10 17:14:39 -04:00
|
|
|
define word make-parsing ;
|
|
|
|
|
2009-03-09 21:36:35 -04:00
|
|
|
: ON-BNF: CREATE-WORD reset-tokenizer ";ON-BNF" parse-multiline-string parse-ebnf
|
2009-03-10 17:14:39 -04:00
|
|
|
main swap at create-bnf ; parsing
|
2009-03-09 21:36:35 -04:00
|
|
|
|
|
|
|
! Tokenizer like standard factor lexer
|
|
|
|
EBNF: factor
|
|
|
|
space = " " | "\n" | "\t"
|
|
|
|
spaces = space* => [[ drop ignore ]]
|
|
|
|
chunk = (!(space) .)+ => [[ >string ]]
|
|
|
|
expr = spaces chunk
|
|
|
|
;EBNF
|