我正在尝试创建宏,从输入列表生成一些代码。但我在语法案例中无法与之匹配。
示例代码:
#lang racket/base
(require (for-syntax racket/base))
(define test-data '(root
()
(branch ((name "left")) (leaf ((name "green0"))) (leaf ((name "yellow"))) (leaf ((name "pink"))))
(branch ((name "right")) (leaf ((name "name2"))))
(branch ((name "broken")))))
(define-syntax (parse-xml stx)
(syntax-case stx (root branch)
[(_ (root () branches ...))
#'branches...
]
[(_ rest) #'rest]))
(parse-xml (datum->syntax #'() test-data))
我觉得我遗漏了一些非常基本的东西,但我无法找到如何扩展"输入参数到stx是可匹配的。你能帮帮我吗? 提前谢谢。
答案 0 :(得分:1)
你不需要parse-xml
成为一个宏,它只是一个正常的功能。这意味着两个变化。
将define-syntax
更改回define
将函数更改为仅接收xml内容的帐户,而不是整个"宏"表达
改变这两个结果
(define (parse-xml xml)
(syntax-case xml (root branch)
[(root () branches ...) ; notice how the pattern changed for (2)
#'branches...
]
[rest #'rest]))
身体未完成,我想你可以从这里拿走它。
根据您的评论,用户会像这样使用它:
(parse-xml/file "path/to/data.xml")
然后宏不应该采用像test-data
这样的变量,它应该采用文件路径。
(require (for-syntax racket/base))
(define-syntax parse-xml/file
(lambda (stx)
(syntax-case stx ()
[(_ file-path)
....
])))
接下来要做的是找到要读取的文件。我找到的解析宏路径的最佳方式是来自resolve-path-spec
的{{1}}。
syntax/path-spec
下一步是从中读取,可能使用(require (for-syntax racket/base
syntax/path-spec))
(define-syntax parse-xml/file
(lambda (stx)
(syntax-case stx ()
[(_ file-path)
(.... (resolve-path-spec #'file-path #'file-path stx) ....)])))
中的open-input-file
和syntax:read-xml
。
xml
此时,您有一个由(require (for-syntax racket/base
syntax/path-spec
xml))
(define-syntax parse-xml/file
(lambda (stx)
(syntax-case stx ()
[(_ file-path)
(....
(syntax:read-xml
(open-input-file (resolve-path-spec #'file-path #'file-path stx)))
....)])))
生成的包含数据的语法对象。
现在我们可以使用 中的函数返回,如果你想在运行时解析它 部分。要在编译时使用它,只需将定义放在syntax:read-xml
。
begin-for-syntax
剩下的就是完成(require (for-syntax racket/base
syntax/path-spec
xml))
(begin-for-syntax
(define (parse-xml xml)
(syntax-case (xml->xexpr
((eliminate-whitespace '(root branch name leaf))
(document-element xml))) (root branch)
[(root () branches ...)
#''(branches ...)
]
[rest #'rest])))
(define-syntax parse-xml/file
(lambda (stx)
(syntax-case stx ()
[(_ file-path)
(parse-xml
(read-xml
(open-input-file (resolve-path-spec #'file-path #'file-path stx))))
])))
的功能版本来解析它并生成代码。