我正在尝试使用brag一书中介绍的Beautiful Racket AST生成器,根据以下语法(在grammar.rkt
中构建解析器:
#lang brag
select : /"select" fields /"from" source joins* filters*
fields : @field (/"," @field)*
field : WORD
source : WORD
joins : join*
join : "join" source "on" "(" condition ")"
filters : "where" condition ("and" | "or" condition)*
condition : field | INTEGER "=" field | INTEGER
这是我的阅读器和令牌生成器,位于一个名为reader.rkt
的文件中:
#lang br/quicklang
(require "grammar.rkt")
(define (read-syntax path port)
(define parse-tree (parse path (make-tokenizer port)))
(define module-datum `(module sql-mod "expander.rkt"
,parse-tree))
(datum->syntax #f module-datum))
(provide read-syntax)
; tokenizer
(require brag/support)
(define (make-tokenizer port)
(define (next-token)
(define bf-lexer
(lexer
["select" lexeme]
[whitespace (token lexeme #:skip? #t)]
[any-char (next-token)]))
(bf-lexer port))
next-token)
现在,我只是想让它解析选择内容,但是正如我们将在下面的错误中看到的那样,即使失败了。
我的扩展器应该只返回解析器返回的带引号的AST。这是我的扩展器的代码,在expander.rkt
中:
#lang br/quicklang
(define-macro (bf-module-begin PARSE-TREE)
#'(#%module-begin
PARSE-TREE))
(provide (rename-out [bf-module-begin #%module-begin]))
最后,这是我要标记/解析的代码:
#lang reader "reader.rkt"
select * from table
当我在DrRacket中与上述文件位于同一文件夹中运行此文件时,遇到以下错误:
Encountered parsing error near "select" (token 'select) while parsing #<path:/Users/alex/SeaQuill/basic.rkt> [line=#f, column=#f, offset=#f]
我希望能够生成AST,以便可以开始在扩展器上工作,但是我很迷路!理想情况下,上面的代码将生成以下标记化:
(list "select"
(token 'WORD "*")
"from"
(token 'WORD "table")))
例如,然后我可以将其传递给解析器。但是,不。
更新:
我认为我已经通过将令牌生成器更改为以下方式取得了一些进展:
(require brag/support)
(define (make-tokenizer port)
(define (next-token)
(define bf-lexer
(lexer
[whitespace (token lexeme #:skip? #t)]
["select" lexeme]
[(:seq alphabetic) (token 'WORD lexeme)]))
(bf-lexer port))
next-token)
运行select field from table
时出现错误:
Encountered parsing error near "h" (token 'WORD) while parsing #<path:/Users/alex/SeaQuill/basic.rkt> [line=#f, column=#f, offset=#f]