【问题标题】:Scheme/Racket: How to do repeating in defining syntax方案/球拍:如何在定义语法时重复
【发布时间】:2020-02-17 00:10:46
【问题描述】:

我可以在 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))

Racket 中的语法在这里:https://docs.racket-lang.org/syntax/stxparse-patterns.html 带有 ~between 但没有 ~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))

【问题讨论】:

    标签: parsing syntax scheme racket definition


    【解决方案1】:

    您想要的是~seq...+ 的组合。

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

    ~seq 匹配一系列事物而不要求它们像您的解决方法那样用括号分组。

    ...+ 是一种重复模式,用于匹配一个或多个事物,而不是零个或多个事物。这可以确保(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 ...)])
    

    【讨论】:

      猜你喜欢
      • 2019-10-27
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 2017-09-28
      • 1970-01-01
      相关资源
      最近更新 更多