警告:由于冲突,规则在解析器中无用

时间:2017-04-05 14:04:45

标签: yacc

这里CR就是创造 SP是空间 RE被替换 我正确地获取输出以进行创建或替换,但不仅仅是创建。任何人都可以告诉代码有什么问题 但我仍然得到这个警告,因此没有工作 p.y:10.5-6:警告:由于冲突,规则在解析器中无效

    %token CR TRI SP RE OR BEF AFT IOF INS UPD DEL ON OF 
    %%
    s:e '\n' { printf("valid variable\n");f=1; };
    e:TPR SP TRI;
    TPR:CR
    |CR SP OR SP RE;

1 个答案:

答案 0 :(得分:0)

将空格传递给解析器几乎不是一个好主意。它只会使语法复杂化,几乎不提供额外的价值。

对终端和非终端的名称采用单一约定也是一个好主意。如果要对终端使用ALL CAPS(这是正常惯例),则不要将它也用于非终端,例如TPR。此外,使用有意义的名称和文字字符串将使您的语法更具可读性。

“由于冲突而在解析器中无用的规则”警告始终伴随着一个或多个shift / reduce或reduce / reduce冲突。通常,解决方案是解决冲突。在这种情况下,您可以通过简单地不将空格传递给解析器来实现。

这是你的语法,我想:(我猜你的缩写是什么意思)

%token CR "create" OR "or" RE "replace"
%token TABLE_IDENTIFIER
%%
statement: expr '\n'  { /* Some action */ }
expr: table_producer TABLE_IDENTIFIER
table_producer
    : "create"
    | "create" "or" "replace"

这样编写,没有空格,语法没有任何冲突。如果我们重新引入空格:

%token CR "create" OR "or" RE "replace"
%token TABLE_IDENTIFIER SPACE
%%
statement: expr '\n'  { /* Some action */ }
expr: table_producer SPACE TABLE_IDENTIFIER
table_producer
    : "create"
    | "create" SPACE "or" SPACE "replace"

然后在识别create后发生转移/减少冲突。前瞻将是SPACE,但解析器无法知道SPACE是否属于第二个table_producer制作(create or...)或expr制作的一部分(create table_name)。

两个单词之间必须有一些标点符号,否则词法分析器会将它们识别为单个单词。所以这些单词被空格分隔的事实没有意义;如果词法分析器只是简单地将空白保留给自己,那么冲突就会消失。