Macros 球拍中的嵌套宏

Macros 球拍中的嵌套宏,macros,nested,scheme,lisp,racket,Macros,Nested,Scheme,Lisp,Racket,我希望能够编写如下嵌套表达式: (AND/OR expr1 op1 expr2 AND/OR expr3 op2 expr4 and so on) 其中和/或本质上是和或。但我想写无限多的。我正在使用define语法尝试实现这一点,但我不确定如何接受无限量的嵌套表达式 不要介意我的例子中的expr和op,那部分我可以自己处理。我只想知道如何接受无限嵌套 例如: (SELECT somecolumns FROM sometable WHERE something AND/OR something

我希望能够编写如下嵌套表达式:

(AND/OR expr1 op1 expr2 AND/OR expr3 op2 expr4 and so on)
其中和/或本质上是和或。但我想写无限多的。我正在使用define语法尝试实现这一点,但我不确定如何接受无限量的嵌套表达式

不要介意我的例子中的expr和op,那部分我可以自己处理。我只想知道如何接受无限嵌套

例如:

(SELECT somecolumns
FROM sometable
WHERE something
AND/OR something
AND/OR (something AND/OR something)
AND/OR ...)

正如Asumu所说,一般来说,处理s表达式比较简单,至少是为了确保正确的运算符优先级,但对于一些简单的情况,语法规则的模式匹配以及语法解析和协同使用rest参数和递归匹配使这变得容易:

#lang racket
(define-syntax parse-args
  (syntax-rules (AND) ; treat AND as a literal
    [(_)
     ; no more argument, return value:
     '()]

    [(_ (arg1 AND in-rst ...))
     ; Composed argument found, call parse-args recursively:
     (parse-args arg1 AND in-rst ...)]

    [(_ arg1 AND rst ...)
     ; AND operator found, parse left side and rest
     (list 'and
           ; parse the argument (may be composed or not):
           (parse-args arg1)
           ; then parse the rest of the arguments:
           (parse-args rst ...))]

    [(_ arg)
     ; in case the argument is not composed or does not contain AND, don't parse it
     arg]))

;; TESTS:
(parse-args 'a AND ('b AND 'bb) AND 'c AND 'f)
; -> '(and a (and (and b bb) (and c f)))

(parse-args 'a AND ('b AND 'bb))
; -> '(and a (and b bb))
但是,请注意,在添加其他运算符时,上述代码可能变得不切实际

编辑: 与选择宏一起:

(define-syntax SELECT
  (syntax-rules (FROM WHERE)
    [(_ select FROM from WHERE where ...)
     (list 'Select select 'From from 'Where (parse-args where ...))]))

; TEST:
(SELECT 'somecolumns
FROM 'sometable
WHERE 'something1
AND 'something2
AND ('something3 AND 'something4)
AND 'blop)
; -> 
#;'(Select
    somecolumns
    From
    sometable
    Where
    (and something1
         (and something2
              (and (and something3 something4) blop))))

同样,模式匹配允许在正确的点切割列表以获得其余参数

您有一些示例输入和示例预期输出吗?我用一个示例编辑了这篇文章,这可能会让事情更清楚。似乎您可以从编写和/或expr1 op2 expr2和/或expr3 op2….这样的表达式中获益。。。。然后您的宏将自然合成。否则,您将使用s-expression语法,这将使事情变得困难。我完全明白为什么这是一种可行的方法,但是否可以将其与上述语句语法结合起来,从何处选择?对不起,如果我在这里有点迟钝,但球拍对我来说仍然是困惑的,因为我是新手。我已经编辑了我的答案,添加了选择宏,但如果你不清楚,那么这可能不是最好的练习开始。我怀疑您还不习惯递归。如果是这样的话,您现在可能应该避免使用宏,继续学习递归函数和rest参数。非常感谢。只是我还不太习惯使用Rackets中的宏,我非常熟悉其他函数式语言的递归。再次感谢!