为什么 Bison 只打印输入?

Why Bison just prints the input?

Bison 总是打印输入而不是 运行 动作。

我从 Bison 开始,我尝试让它使用尽可能简单的规则。

词法分析器


%{
    #include <stdio.h>
    #include "wip.tab.h"
%}

%%

[\t\n ]+         ;
[a−z]+  { yylval.sval = strdup(yytext); return IDENTIFIER;}

%%

解析器


%{
    #include <stdio.h>
    #include <stdlib.h>
    int yylex(void);
    void yyerror(char const *);
    FILE *yyin;
%}

%union{
    char *sval;
}

%token IDENTIFIER

%%
input:
    %empty
    | input line
    ;

line:
    '\n'
    | IDENTIFIER {printf("OK\n");}
    ;
%%

int main(void) {
    FILE *myfile = fopen("example.wip", "r");
    if (!myfile) {
        printf("File can't be opened\n");
        return -1;    
    }
    yyin = myfile;
    yyparse();   
}

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

"example.wip" 输入文件

hello

我希望在我的终端中输出 "OK",但解析器只打印文件的内容。 提前致谢。

Bison always prints the input instead of running the action.

Bison-generated 永远不会打印输入,除非那是动作所说的。由于 none 你的操作打印了 "OK" 以外的任何内容,所以这不可能是这里发生的事情。

但是,默认情况下,flex 生成的词法分析器 do 会在看到不认识的字符时打印输入。为了验证这是怎么回事,我们可以在词法分析器文件的末尾添加一条规则,为无法识别的字符打印正确的错误消息:

.      { fprintf(stderr, "Unrecognized character: '%c'\n", yytext[0]); }

果然,这会告诉我们 "hello" 中的所有字符都无法识别。

那么 [a−z]+ 模式有什么问题呢?为什么不匹配"hello"? 出了问题。它不是常规的 ASCII 破折号,而是没有特殊意义的 Unicode 破折号。因此 flex 将 [a−z] 解释为可以匹配以下三个字符之一的字符 class:a、Unicode 破折号或 z - 不是 a 的范围至 z.

要解决此问题,只需将其替换为常规破折号即可。