Почему хвастовство Ракет дает мне ошибку разбора, когда я пытаюсь токенизировать? - PullRequest
1 голос
/ 23 сентября 2019

Я пытаюсь использовать генератор brag AST, как описано в книге Beautiful Racket , построить парсер из следующей грамматики (в 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]
...