扩展backus-naur-forms的racket语法

时间:2012-11-21 16:48:15

标签: racket bnf

我在球拍中实现了一组派生规则。我们可以假设没有任何可选项,这意味着没有包含管道的规则(在BNF中)::: = |

在球拍中,我有类似的东西:

(define *rules*
  '((S . ("b" "a"))
    (B . ("a"))
    (C . (S B))))

请注意,终端符号以球拍弦的形式实现,非终结符号以球拍符号的形式实现。现在,我想从另一个包含backus naur语法规则的racket文件中导入此规则:

S ::= ba
B ::= a
C ::= SB

(大写字母=非终端)

因此,我需要扩展racket语法。我不知道如何处理。你能帮助我吗?它应该不是那么多代码......

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找解析使用BNF语法编写的文件,并生成一个s-expression版本;是吗?

如果是这样,那应该不难。特别是,您的问题隐含的格式是每行都是

形式
<NT> :: = [<NT>|<T>]*

......你可以像这样分开:

#lang racket

;; COPYRIGHT 2012 John B. Clements (clements@brinckerhoff.org)
;; Licensed under the Apache License, version 2.
;; (You're free to use it, but your source code has to include
;; my authorship.)

(require rackunit)

(define example
  (list "S ::= ba"
        "B ::= a"
        "C ::= SB"))

;; parse a single line:
;; string -> (list/c symbol? (listof (or/c string? symbol?)))
(define (parse-line l)
  (match (regexp-match #px"^([A-Z]) ::= ([A-Za-z]*)$")
    [(list _ lhs rhses)
     (list lhs (map parse-char (string->list rhses)))]))

;; parse a single char:
;; char -> (or/c symbol? string?)
(define (parse-char ch)
  .. oops! out of time. You'll have to write this part yourself... )

(check-expect (map parse-line example)
              '((S ("b" "a"))
                (B ("a"))
                (C (S B))))

糟糕!我看到那里有一个bug。没问题,你会搞清楚的。要跑......