implement parser

This commit is contained in:
xenia 2020-09-09 22:47:57 -04:00
parent e035dcd1fd
commit 1b7b13d16e
1 changed files with 58 additions and 9 deletions

View File

@ -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))))