0

我正在尝试使用Irony来解析 C99,我在网上找到了一个语法来指导我

我在声明与声明的冲突中遇到困难。以下规则未能检测到带有初始化程序的指针声明。

blockItemList.Rule = MakePlusRule(blockItemList, blockItem);
blockItem.Rule = declaration | statement;

它失败的线路类型是:

MyType *x = foo();

当我从语句的规则中删除labeledStatement 和expressionStatement 时(两者都可能以标识符开头),这种类型的声明被正确识别。

在尝试声明之前强制 Irony 用尽声明规则的最佳方法是什么?或者,我可以在 Irony 解析时添加到语法中,以便它可以将 MyType 注册为终端而不是标识符?

4

1 回答 1

1

我记得函数调用和标识符有类似的问题。不要认为你做错了什么,这只是语法的工作方式。您需要针对 Irony 对其进行“微调”。据我所知,Irony 是 LALR(1) 解析器,例如在做决定时只向前看一个符号。这可能意味着您需要做的工作不仅仅是定义给定的语法。

我遇到过语法冲突的情况,我通过降低语法的“精确度”来解决它。实际精度后来通过 AST 节点恢复。

ps,你还可以:

使用 Irony GrammarExplorer 看看你的语法有什么冲突。您有时可以使用 PreferSHiftHere() 或 ReduceHere() 解决冲突

还有一些我认为有趣的链接:

http://irony.codeplex.com/discussions/400830

http://irony.codeplex.com/discussions/80134

https://irony.codeplex.com/discussions/551074

上下文无关的语法理解是不够的 - 你必须了解 LR、LALR(1)、LL 等解析方法。讽刺的是 LALR(1),而 Antlr 是 LL。语法规则应针对特定方法进行微调。具有讽刺意味的“坚持”某事“错误”意味着它采用了由其报告的模棱两可(冲突!)导致的两种同样可能的选择之一。因此,在解决冲突之前尝试解析 smth 毫无意义。要做到这一点 - 阅读更多关于 LALR 语法的信息。

于 2014-08-23T14:22:45.460 回答