帮助转移/减少冲突 - 尝试建模 (XA)* (XB)*

发布于 2024-07-23 01:15:02 字数 988 浏览 9 评论 0原文

我试图对 EBNF 表达式进行建模,

("declare" "namespace" ";")* ("declare" "variable" ";")*

我已经构建了 yacc (我使用 MPPG)语法,它似乎代表了这一点,但它与我的测试表达式不匹配。

我试图匹配的测试用例是

declare variable;

来自词法分析器的令牌流是

KW_Declare
KW_Variable
Separator

语法解析表示存在“Shift/Reduce 冲突,KW_Declare 上的状态 6”。 我尝试用“%left PrologHeaderList PrologBodyList”解决此问题,但这两种解决方案都不起作用。

Program                     : Prolog;
Prolog                      : PrologHeaderList PrologBodyList;

PrologHeaderList            : /*EMPTY*/
                            | PrologHeaderList PrologHeader;
PrologHeader                : KW_Declare KW_Namespace Separator;

PrologBodyList              : /*EMPTY*/
                            | PrologBodyList PrologBody;
PrologBody                  : KW_Declare KW_Variable Separator;

KW_Declare KW_Namespace KW_Variable Separator 都是值为“declare”、“naemsapce”、“variable”、“;”的标记。

Im trying to model the EBNF expression

("declare" "namespace" ";")* ("declare" "variable" ";")*

I have built up the yacc (Im using MPPG) grammar, which seems to represent this, but it fails to match my test expression.

The test case i'm trying to match is

declare variable;

The Token stream from the lexer is

KW_Declare
KW_Variable
Separator

The grammar parse says there is a "Shift/Reduce conflict, state 6 on KW_Declare". I have attempted to solve this with "%left PrologHeaderList PrologBodyList", but neither solution works.

Program                     : Prolog;
Prolog                      : PrologHeaderList PrologBodyList;

PrologHeaderList            : /*EMPTY*/
                            | PrologHeaderList PrologHeader;
PrologHeader                : KW_Declare KW_Namespace Separator;

PrologBodyList              : /*EMPTY*/
                            | PrologBodyList PrologBody;
PrologBody                  : KW_Declare KW_Variable Separator;

KW_Declare KW_Namespace KW_Variable Separator are all tokens with values "declare", "naemsapce", "variable", ";".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

疯了 2024-07-30 01:15:02

我已经很长时间没有使用类似 yacc 的东西了,但这里有一些可能有帮助也可能没有帮助的建议。

在这种情况下,您似乎需要 2 个令牌的前瞻。 解析器到达最后一个 PrologHeader,它必须决定下一个构造是 PrologHeader 还是 PrologBody,但它不能从 KW_Declare 可以看出这一点。 如果在这种情况下有一个增加前瞻的指令,它可能会解决问题。

您还可以在操作中引入上下文:定义 PrologRuleList 并让操作在出现标头时抛出错误,而不是定义 PrologHeaderListPrologBodyList一具尸体之后。 丑陋,但有时你必须这样做:在语法中看似简单的东西在生成的解析器中可能并不简单。

一种黑客方法可能是组合标记:让您的词法分析器识别空格并使用 KW_Declare_Variable,而不是 KW_DeclareKW_Variable。 由于两者都是关键字,因此您不会遇到名称空间冲突问题。

It's been a long time since I've used anything yacc-like, but here are a couple of suggestions that may or may not help.

It seems that you need a 2-token lookahead in this situation. The parser gets to the last PrologHeader, and it has to decide whether the next construct is a PrologHeader or a PrologBody, and it can't tell that from the KW_Declare. If there's a directive to increase lookahead in this situation, it will probably solve the problem.

You could also introduce context into your actions: rather than define PrologHeaderList and PrologBodyList, define PrologRuleList and have the actions throw an error if a header appears after a body. Ugly, but sometimes you have to do it: what appears simple in a grammar may not be simple in the generated parser.

A hackish approach might be to combine the tokens: rather than KW_Declare and KW_Variable, have your lexer recognize the space and use KW_Declare_Variable. Since both are keywords, you're not going to run into namespace collision problems.

如梦初醒的夏天 2024-07-30 01:15:02

顶部的语法是规则的,因此 IIRC 您可以将其绘制为 DFA(或 NDA 并将其转换为 DFA),然后将 DFA 转换为语法。 已经有一段时间了,所以我将把这项工作留给读者作为练习。

The grammar at the top is regular so IIRC you can plot it out as a DFA (or a NDA and convert it to a DFA) and then convert the DFA to a grammar. It's bean a while so I'll leave the work as an exercise for the reader.

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