c - Yacc/Flex 中的移位/减少冲突

标签 c yacc flex-lexer lr

我在 yacc 中有这个语法:

%{
    #include <stdio.h>
%}

%token texto SEP ERRO word

%start Ini

%%

Ini: Directivas SEP SEP Conceitos '$'
            { printf("Terminou bem...\n"); return 0; };

Directivas: Directiva
          | Directivas SEP Directiva
          ;

Conceitos: Conceito
         | Conceitos SEP SEP Conceito
         ;

Conceito: word SEP Atributos;

Atributos: Atributo
         | Atributos SEP Atributo
         ;

Directiva: texto;
Atributo: '-' texto;

%%

int main(){
    yyparse();
}

int yyerror(char *s){
    fprintf(stderr, "%s\n", s);
}

在 flex 中:

%{
    #include "y.tab.h"
%}

%%

[a-zA-Z]+           return word;

[a-zA-Z ]+          return texto;

\-                  return '-';

\n                  return SEP;

[ \t]               ;

.                   return ERRO;

<<EOF>>             return '$';

我想做一个有效的解析:

text line
text line
text line

word
-text line
-text line
-text line

word
-text line

第一行是“Directivas”,然后是一个空行,然后是“Conceitos”,其中一个 Conceito 是一个单词,后跟几行开头为“-”的文本行。那些'自负由一个空行分隔

但它发现了一个转移/减少冲突..我是新手,我不知道为什么

对不起我的英语

谢谢

最佳答案

使用 yacc(或 bison)的 -v 选项在 y.output 文件中获取生成的解析器和语法冲突的完整列表。当你用你的语法这样做时,你会得到类似(来自野牛)的东西:

State 16 conflicts: 1 shift/reduce
        :
state 16

    6 Conceito: word SEP Atributos .
    8 Atributos: Atributos . SEP Atributo

    SEP  shift, and go to state 20

    SEP       [reduce using rule 6 (Conceito)]
    $default  reduce using rule 6 (Conceito)

这会告诉您冲突的确切位置——在减少 Attributos 并查看 SEP 前瞻之后,解析器不知道是否应该将 SEP 解析其后的另一个 Atributo,或者减少 Conceito,这只有在有另一个 SEP 时才有效在 SEP 之后(需要两个 token 先行)。

避免这种情况的一种方法是让您的词法分析器将多个 SEP(空行)作为单个标记返回:

\n      return SEP;
\n\n    return SEP_SEP;

您可能希望在空白行或多个空白行上允许空格:

\n([ \t]*\n)+  return SEP_SEP;

关于c - Yacc/Flex 中的移位/减少冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16703338/

相关文章:

c - sql 解析器的 Makefile...编写依赖项

shell - 使用 Flex 和 Bison 将别名功能添加到 shell

compiler-errors - 检查 Flex 中错误的标识符模式

c++ - 验证乘法溢出测试

c - 运行生成的 YACC 解析器产生意外的语法错误

c++ - 词法和语法分析器软件

gcc - 编译 gcc - 找不到 flex 的输出;放弃

clang-format 与数组初始化

c - 以垂直格式显示数字

c++ - git clone 修改eclipse C/C++项目包含路径