(module parsing mzscheme
(provide parse)
(require (lib "yacc.ss" "parser-tools")
(only (lib "lex.ss" "parser-tools")
token-name
position-token-token
position-line
position-col)
"structs.ss"
"lexing.ss")
(define template-parser
(parser (error (lambda (token-ok token-name token-value start-pos end-pos)
(error 'parser "Error at ~s ~s (~a:~a)"
token-name token-value
(position-line start-pos)
(position-col start-pos))))
(tokens template-tokens)
(src-pos)
(start document)
(end eof)
(grammar [document
((element-list)
(make-document $1))]
[element-list
((element-list/rev)
(reverse $1))
(() '())]
[element-list/rev
((element-list/rev element)
(cons $2 $1))
((element)
(list $1))]
[element
((non-delimiter)
(make-normal-text $1))
((delimiter expression delimiter)
$2)]
[expression
((string) (make-normal-text $1))
((identifier)
(make-variable-reference $1))
((identifier semicolon identifier equals expression)
(cond
[(string=? $3 "separator")
(make-variable-reference/separator $1 $5)]
[else
(error 'template-parser
"Unsupported option ~s"
$3)]))])))
(define (parse inp)
(define in-expression? #f)
(define (choose-lexer)
(cond
[in-expression? expression-lexer]
[else toplevel-lexer]))
(define (get-token)
(let ([next-token ((choose-lexer) inp)])
(when (eq? (token-name (position-token-token next-token))
'delimiter)
(set! in-expression? (not in-expression?)))
next-token))
(template-parser get-token)))