我被迫使用 %glr-parser 吗?
我一直在避免移位/归约错误。现在我终于认为我遇到了对手。
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 次转移/减少和 1 次减少/减少警告。
I have been keeping the shift/reduce errors away. Now finally i think i met my match.
Int[] a
a[0] = 1
The problem is int[] is defined as
Type OptSquareBrackets
while a[0] is defined as
Var | Var '[' expr ']'
Var and Type both are defined as VAR which is any valid variable [a-zA-Z][a-zA-Z0-9_]
. Apart from adding a dummy token (such as **Decl** Type OptSquareBrackets
instead) is there a way to write this to not have a conflict? From this one rule i get 1 shift/reduce and 1 reduce/reduce warning.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以定义一个新的令牌
并因此定义声明
并将分配目标定义为
Could you define a new Token
And therefore define declaration
and define assignment target as
使用 [] 创建 Lex 规则,因为 [] 仅在声明中使用,其他地方将使用 [var]
Create a Lex rule with [] since [] is only used in declaration and everywhere else would use [var]
从技术上讲,这个问题源于试图将语法与实际上在语法上没有区别的语义联系起来。
ISTM 认为您只需要一个描述类型和表达式的语法结构。在代码中而不是在语法中进行区分,尤其是在实际上没有语法差异的情况下。 Yacc 被称为编译器生成器,但事实并非如此。它只是制作解析器。
话虽如此,将
[]
识别为终端符号可能是解决问题并继续处理问题的更简单方法。 Yacc 不太擅长二义性语法,它需要尽早决定要遵循的路径。Technically, this problem stems from trying to tie the grammar to a semantic meaning that doesn't actually differ in syntax.
ISTM that you just need a single grammar construct that describes both types and expressions. Make the distinction in code and not in the grammar, especially if there is not actually a syntactic difference. Yacc is called a compiler generator but it is not the least bit true. It just makes parsers.
Having said that, recognizing
[]
as a terminal symbol might be an easier way to fix the problem and get on with things. Yacc isn't very good at ambiguous grammars and it needs to make early decisions on which path to follow.