我一直在保持转移/减少错误。现在终于我想我遇到了我的比赛。
Int[] a
a[0] = 1
问题是int []被定义为
Type OptSquareBrackets
,而[0]定义为
Var | Var '[' expr ']'
Var和Type都被定义为VAR,它是任何有效的变量[a-zA-Z][a-zA-Z0-9_]
。除了添加虚拟令牌(例如**Decl** Type OptSquareBrackets
)之外,有没有办法写这个没有冲突?根据这一条规则,我得到1班/减1和1减少/减少警告。
答案 0 :(得分:1)
你能定义一个新的令牌
吗?VarLBracket [a-zA-Z][a-zA-Z0-9_]*\[
因此定义声明
Type | VarLBracket ']';
并将分配目标定义为
Var | VarLBracket expr ']';
答案 1 :(得分:1)
从技术上讲,这个问题源于试图将语法与语法实际上没有区别的语义联系起来。
ISTM,您只需要一个描述类型和表达式的单一语法结构。在代码中区分,而不是在语法中区分,特别是如果实际上没有语法差异。 Yacc被称为编译器生成器,但它并不是真的。它只是制作解析器。
话虽如此,将[]
识别为终端符号可能是解决问题并继续处理问题的更简单方法。 Yacc不太擅长模糊语法,需要尽早决定要遵循哪条路径。
答案 2 :(得分:1)
使用[]创建Lex规则,因为[]仅用于声明,其他地方都会使用[var]