factor/unmaintained/peg-lexer/peg-lexer.factor

65 lines
1.8 KiB
Factor
Raw Normal View History

2009-03-09 21:36:35 -04:00
USING: hashtables assocs sequences locals math accessors multiline delegate strings
2009-04-25 00:23:02 -04:00
delegate.protocols kernel peg peg.ebnf peg.private 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 +
] ;
2009-03-11 19:36:55 -04:00
: 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-09 21:36:35 -04:00
2012-04-25 16:18:21 -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 {
2009-03-09 21:36:35 -04:00
{ input [ drop lexer get text>> "\n" join t ] }
{ pos [ drop lexer get [ text>> ] [ line>> 1 - ] [ column>> 1 + ] tri at-pos t ] }
[ swap hash>> at* ]
} case ;
2009-03-09 21:36:35 -04:00
: 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>
2009-03-09 21:36:35 -04:00
swap bind ; inline
: parse* ( parser -- ast )
compile
2009-04-25 00:23:02 -04:00
[ execute [ error-stack get first throw ] unless* ] with-global-lexer
2009-04-26 19:56:24 -04:00
ast>> ; inline
2009-03-09 21:36:35 -04:00
: create-bnf ( name parser -- )
2009-04-25 00:23:02 -04:00
reset-tokenizer [ lexer get skip-blank parse* dup ignore? [ drop ] [ parsed ] if ] curry
2009-04-26 19:56:24 -04:00
define-syntax word make-inline ;
2009-03-10 17:14:39 -04:00
SYNTAX: ON-BNF:
scan-new-word reset-tokenizer ";ON-BNF" parse-multiline-string parse-ebnf
main swap at create-bnf ;
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