代码之家  ›  专栏  ›  技术社区  ›  Dan D.

Scheme/Racket:如何在定义语法时重复

  •  0
  • Dan D.  · 技术社区  · 4 年前

    我可以在Racket中定义中缀“+”如下:

    (require syntax/parse/define (only-in racket (#%app racket:#%app)))
    (define-syntax-parser #%app
      [(_ Value1 {~datum +} Value2)
      #'(+ Value1 Value2)]
    
      [(_ Xs ...) 
      #'(racket:#%app Xs ...)]
    )
    (displayln (1 + 2))
    

    我想添加多个中缀“+”使用 ~between 但它不起作用:

    (require syntax/parse/define (only-in racket (#%app racket:#%app)))
    (define-syntax-parser #%app
      [(_ {~between {Value1 {~datum +}} 1 100} Value2)
      #'(+ Value1 Value2)]
    
      [(_ Xs ...) 
      #'(racket:#%app Xs ...)]
    )
    (displayln (1 + 2))
    

    https://docs.racket-lang.org/syntax/stxparse-patterns.html 具有 ~介于 但是没有 ~repeat

    如何使用~between属性在语法中重复项?

    我有一个解决办法,但它看起来不是纯粹的多重中缀 + ,需要将每个左项括在括号中:

    (require syntax/parse/define (only-in racket (#%app racket:#%app)))
    (define-syntax-parser #%app
      [(_ {Value1 {~datum +}} ... Value2)
      #'(+ Value1 ... Value2)]
    
      [(_ Xs ...) 
      #'(racket:#%app Xs ...)]
    )
    (displayln ({1 +} {2 +} 3))
    
    0 回复  |  直到 4 年前
        1
  •  3
  •   Alex Knauth    4 年前

    你想要的是 ~seq ...+

    (define-syntax-parser #%app
      [(_ {~seq Value1 {~datum +}} ...+ Value2)
       #'(+ Value1 ... Value2)]
      [(_ Xs ...) 
       #'(racket:#%app Xs ...)])
    

    ~序号 没有 要求他们按括号分组,就像你的解决方法一样。

    ...+ 是一种重复模式来匹配一个或多个事物,而不是零个或多个。这样可以确保 (f) 不会被意外地解释为 (+ f) .

    #%app 直接地说,与在不同名称下定义然后重命名导出不同,您需要对隐式递归使用格外小心。例如 (+ + x) racket:#%app 在两个输出中,比如 #'(racket:#%app + Value1 ... Value2)

    (define-syntax-parser #%app
      [(_ {~seq Value1 {~datum +}} ...+ Value2)
       #'(racket:#%app + Value1 ... Value2)]
      [(_ Xs ...) 
       #'(racket:#%app Xs ...)])