语法条件 `!`(标记为 "except")的作用是什么?

What does the syntax condition `!` (labelled "except") do?

Rascal 语法包含未记录的语法规则产生式:

| except: Sym symbol "!" NonterminalLabel

它在语法上的作用类似于跟随条件,并且在注释为 "conditional" 的部分中。我看到它在 Rascal 语法本身中使用。 NonterminalLabel 用于单独的产生式规则(不是具有所有替代项的产生式)。那么这个条件有什么作用呢?

如果‘E! add' 出现在规则中,那么它只表示 E,但是 E 的标记为 "add" 的规则就好像不存在一样。 此限制仅深入一层,因此递归 E 将再次具有 "add" 规则。

例如:

syntax E 
  = id: Id
  | app: E "(" {E!comma ","}* ")"
  > left mul: E "*" E
  > left add: E "+" E
  > right comma: E "," E
  ;

函数应用规则{E ","}*中的E限制不能是逗号表达式,以避免句法歧义。

  • 这里的好处是您不必引入另一个在逻辑上也表示表达式的非终结符。
  • 陷阱在于!运算符是一个硬性限制,因此可能使可接受的语言实际上更小:使用!如果不小心使用,可能会导致意外的解析错误。

旁注:!运算符也是用于对优先级 (>) 和关联(左、右)语义建模的原始约束类型,但它们是可传递的并检查安全性等。另一方面,这是对定义的残酷删除,因此可能会改变您的语言接受的句子。