通过在球拍中设计解释器来重写此脚本

Han*_*Sun 3 lisp scheme racket

原始脚本是这样的:

#lang racket
(for ([i (in-range 3)])
    (for ([j (in-range 9)])
      (display "X"))
     (display "\n"))

(for ([i (in-range 6)])
  (for ([j (in-range 3)])
    (display " "))
  (for ([j (in-range 3)])
    (display "X"))
  (for ([j (in-range 3)])
    (display " "))
  (display "\n"))

(for ([i (in-range 3)])
    (for ([j (in-range 9)])
      (display "X"))
     (display "\n"))
Run Code Online (Sandbox Code Playgroud)

输出是:

XXXXXXXXX
XXXXXXXXX
XXXXXXXXX
   XXX   
   XXX   
   XXX   
   XXX   
   XXX   
   XXX   
XXXXXXXXX
XXXXXXXXX
XXXXXXXXX
Run Code Online (Sandbox Code Playgroud)

我想知道我是否可以使用这样的DSL重写它:

(define a
  "3 9 X
6 3 b 3 X 3 b
3 9 X")
Run Code Online (Sandbox Code Playgroud)

然后:

(interpret a)
Run Code Online (Sandbox Code Playgroud)

绘制此图表.

有谁知道最好的方法是什么?

dyo*_*yoo 8

要解决这类问题,首先要描述一种数据类型,它可以捕获您在DSL中所需的操作,而不是专注于表面语法.一旦掌握了数据类型,就应该可以更轻松地解决问题.

乍一看,我们可以用您的语言设计3种基本形式:

  1. 字符串
  2. 重复
  3. 测序

我们可以用原始字符串和结构来表示这个不相交的类.让我们将这个类称为"pexpr",作为"可打印的expr".在代码中:

;; An pexpr is one of the following:
;;   * a primitive string,
;;   * a seq, or
;;   * a repeat
(struct seq (bodies) #:transparent)    ;; bodies is a list of pexpr
(struct repeat (n body) #:transparent) ;; n is a number, body is a pexpr
Run Code Online (Sandbox Code Playgroud)

它可能有助于将一些辅助函数作为缩写,因为"seq"和"repeat"本身有点啰嗦.

;; For convenience, we define some abbreviations s and r for seq and repeat,
;; respectively.
(define (s . bodies)
  (seq bodies))
(define (r n . bodies)
  (repeat n (seq bodies)))
Run Code Online (Sandbox Code Playgroud)

您的示例"I"字符串可以写成:

(define an-example
  (s
   (r 3 (r 9 "X") "\n")
   (r 6 (r 3 " ") (r 3 "X") "\n")
   (r 3 (r 9 "X") "\n")))
Run Code Online (Sandbox Code Playgroud)

请注意,此编码具有新行的显式表示,仅从表面语法中隐含.然后它成为解析器的工作,在表面语法中取代线并将它们变成pexprs,但这不应该太困难.希望.:)

无论如何,解释函数变成了填充模板的细节,如下所示:

(define (interpret pexpr)
  (match pexpr
    [(? string?)
     ...]
    [(struct seq (bodies))
     ...]
    [(struct repeat (n body))
     ...]))
Run Code Online (Sandbox Code Playgroud)

哪个'...'应该很容易填写.

这种问题的解决方法是如何设计程序编程语言:应用和解释.我建议看看它们:它们是好东西.