diff --git a/kaitai/expr.rkt b/kaitai/expr.rkt index 0b1eac6..67a05a3 100644 --- a/kaitai/expr.rkt +++ b/kaitai/expr.rkt @@ -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))))