implement parser
This commit is contained in:
parent
e035dcd1fd
commit
1b7b13d16e
|
@ -1,12 +1,12 @@
|
|||
#lang racket/base
|
||||
|
||||
(require racket/function racket/match racket/set
|
||||
(require racket/function racket/list racket/match racket/set
|
||||
parser-tools/lex
|
||||
(prefix-in : parser-tools/lex-sre)
|
||||
parser-tools/yacc)
|
||||
|
||||
(define-tokens kaitai-expr [boolean number string identifier])
|
||||
(define-empty-tokens kaitai-empty [eof + - * / % < <= > >= == != << >> & pipe ^ not and or ? :
|
||||
(define-empty-tokens kaitai-sym [eof + - * / % < <= > >= == != << >> & pipe ^ not and or ? :
|
||||
lparen rparen lbracket comma dot rbracket])
|
||||
|
||||
(define (kaitai-numstr->number str)
|
||||
|
@ -18,7 +18,6 @@
|
|||
|
||||
(define (kaitai-subst-string str)
|
||||
;; racket's built in string translation works fine
|
||||
(printf "uwu ~s\n" str)
|
||||
(read (open-input-string
|
||||
(string-append "\"" (substring str 1 (sub1 (string-length str))) "\""))))
|
||||
|
||||
|
@ -66,11 +65,61 @@
|
|||
["]" (token-rbracket)]
|
||||
[(:: (:+ (:or alphabetic "_"))
|
||||
(:* (:or alphabetic numeric "_" "::")))
|
||||
(token-identifier lexeme)]
|
||||
(token-identifier (string->symbol lexeme))]
|
||||
[(eof) (token-eof)]))
|
||||
|
||||
(let ([input (open-input-string "_root._io.size.to_i & 0x08000000 != 'abc\\'c' 0 + code == block_type::int32 ? 4 : 8")])
|
||||
(let loop ()
|
||||
(match (kaitai-lexer input)
|
||||
[(? (curry equal? (token-eof))) (void)]
|
||||
[x (printf "~v\n" x) (loop)])))
|
||||
(define kaitai-parser
|
||||
(parser
|
||||
[start exp]
|
||||
[end eof]
|
||||
[error (lambda (tok-ok? tok-name tok-value)
|
||||
(error "parser error" tok-ok? tok-name tok-value))]
|
||||
[tokens kaitai-expr kaitai-sym]
|
||||
[precs (left comma)
|
||||
(right ? :)
|
||||
(left and or)
|
||||
(left & pipe ^)
|
||||
(left < <= > >= != ==)
|
||||
(left << >>)
|
||||
(left + -)
|
||||
(left * / %)
|
||||
(right not)
|
||||
(left dot lparen rparen lbracket rbracket)]
|
||||
[grammar
|
||||
(exp [(number) $1]
|
||||
[(string) $1]
|
||||
[(boolean) $1]
|
||||
[(identifier) $1]
|
||||
[(lbracket apply-args rbracket) (cons 'array $2)]
|
||||
[(exp dot identifier) (list 'get $1 $3)]
|
||||
[(exp lparen apply-args rparen) `(apply ,$1 ,@$3)]
|
||||
[(exp * exp) (list '* $1 $3)]
|
||||
[(exp / exp) (list '/ $1 $3)]
|
||||
[(exp % exp) (list '% $1 $3)]
|
||||
[(exp + exp) (list '+ $1 $3)]
|
||||
[(exp - exp) (list '- $1 $3)]
|
||||
[(exp < exp) (list '< $1 $3)]
|
||||
[(exp <= exp) (list '<= $1 $3)]
|
||||
[(exp > exp) (list '> $1 $3)]
|
||||
[(exp >= exp) (list '>= $1 $3)]
|
||||
[(exp != exp) (list '!= $1 $3)]
|
||||
[(exp == exp) (list '== $1 $3)]
|
||||
[(exp >> exp) (list '>> $1 $3)]
|
||||
[(exp << exp) (list '<< $1 $3)]
|
||||
[(exp & exp) (list '& $1 $3)]
|
||||
[(exp pipe exp) (list 'pipe $1 $3)]
|
||||
[(exp ^ exp) (list '^ $1 $3)]
|
||||
[(exp and exp) (list 'and $1 $3)]
|
||||
[(exp or exp) (list 'or $1 $3)]
|
||||
[(not exp) (list 'not $2)]
|
||||
[(exp ? exp : exp) (list 'if $1 $3 $5)]
|
||||
[(lparen exp rparen) $2])
|
||||
(apply-args
|
||||
[(exp) (list $1)]
|
||||
[(exp comma apply-args) (cons $1 $3)])
|
||||
]))
|
||||
|
||||
(define test2 "true and 'a' != 'b' ? 1 : ('hello' + 'world').substring(2, 3)")
|
||||
|
||||
(let ([input (open-input-string test2)])
|
||||
(kaitai-parser (lambda () (kaitai-lexer input))))
|
||||
|
|
Loading…
Reference in New Issue