1

我一直在避免移位/减少错误。现在终于我想我遇到了我的对手。

Int[] a
a[0] = 1

问题是 int[] 被定义为

Type OptSquareBrackets

而 a[0] 被定义为

Var | Var '[' expr ']'

Var 和 Type 都被定义为 VAR ,它是任何有效的变量[a-zA-Z][a-zA-Z0-9_]。除了添加一个虚拟令牌(例如**Decl** Type OptSquareBrackets代替)之外,还有没有办法写这个没有冲突?从这条规则中,我得到 1 个 shift/reduce 和 1 个 reduce/reduce 警告。

4

3 回答 3

1

你能定义一个新的令牌吗

VarLBracket [a-zA-Z][a-zA-Z0-9_]*\[

因此定义声明

Type | VarLBracket ']';

并将分配目标定义为

Var | VarLBracket expr ']';
于 2009-12-01T01:04:19.033 回答
1

从技术上讲,这个问题源于试图将语法与实际上在语法上没有区别的语义含义联系起来。

ISTM,您只需要一个描述类型和表达式的语法结构。区分代码而不是语法,尤其是在实际上没有语法差异的情况下。Yacc 被称为编译器生成器,但它一点也不真实。它只是制作解析器。

话虽如此,识别[]为终端符号可能是解决问题并继续处理的更简单方法。Yacc 不太擅长模棱两可的语法,它需要及早决定走哪条路。

于 2009-12-01T21:01:39.143 回答
1

使用 [] 创建 Lex 规则,因为 [] 仅在声明中使用,其他任何地方都将使用 [var]

于 2009-12-02T00:48:28.020 回答