我被迫使用 %glr-parser 吗?

发布于 2024-08-13 04:35:58 字数 419 浏览 2 评论 0原文

我一直在避免移位/归约错误。现在我终于认为我遇到了对手。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怎会甘心 2024-08-20 04:35:58

您可以定义一个新的令牌

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

并因此定义声明

Type | VarLBracket ']';

并将分配目标定义为

Var | VarLBracket expr ']';

Could you define a new Token

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

And therefore define declaration

Type | VarLBracket ']';

and define assignment target as

Var | VarLBracket expr ']';
祁梦 2024-08-20 04:35:58

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

Create a Lex rule with [] since [] is only used in declaration and everywhere else would use [var]

浅语花开 2024-08-20 04:35:58

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文