我写了一个 C 的子集,关于指针数组的声明有一点模棱两可的语法。事实上,像
这样的声明int *A[10];
可以被看作是一个指针数组和一个指向数组的指针,使用下面的语法:
vardesc:
| id = ID { (dummy_type,id) }
| "(" v = vardesc ")" { v }
| "*" v = vardesc { let (typv,id) = v in (TypP(typv), id) }
| v = vardesc "[" i = option(INT_VALUE) "]"
{ let (typv,id) = v in (TypA(typv, i), id) }
我运行了 menhir 的解释器模式,我发现虽然令牌“*”的优先级低于令牌“[”(在完整层次结构之下),但它使用指针规则。 如果我添加一个虚拟令牌以对该规则施加更高的优先级,即
vardesc:
| id = ID { (dummy_type,id) }
| "(" v = vardesc ")" { v }
| "*" v = vardesc %prec PTR { let (typv,id) = v in (TypP(typv), id) }
| v = vardesc "[" i = option(INT_VALUE) "]"
{ let (typv,id) = v in (TypA(typv, i), id) }
而是使用数组规则。 这对我来说毫无意义,我预计会发生相反的情况。 谁能解释一下为什么会这样?谢谢!
代币优先等级:
%right "=" /* lowest precedence */
%left "||"
%left "&&"
%left "==" "!="
%nonassoc ">" "<" ">=" "<="
%left "+" "-"
%left "*" "/" "%"
%nonassoc "!" "&"
%nonassoc "[" /* highest precedence */
/* impose a precedence for choosing between pointer of array and array of pointers */
%nonassoc PTR
首先,这里的方括号充当圆括号,而不是运算符。因此,优先考虑它们没有多大意义。
现在让我们看看为什么会得到这个不需要的结果:
这里,唯一匹配表达式的规则
int *A[10];
是
v = vardesc "[" i = option(INT_VALUE) "]"
因为它不是 id 并且它不是以 (
或 *
开头
因此,这将是第一个选择的规则,这不是您想要的。问题来自您对
*
的规则:在 C 语言中,*
应用于 before 类型,此处为 int
。但是在你的解析器中,你会看到在之后是什么。