野牛语法错误简易文件

时间:2017-02-15 10:34:30

标签: syntax-error bison

我正在尝试运行此.y文件

%{
#include <stdlib.h>
#include <stdio.h>
int yylex();
int yyerror();

%}

%start BEGIN

%%

BEGIN: 'a' | BEGIN 'a'


%%

int yylex(){
  return getchar();
}

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

int main(int argn, char **argv){
  yyparse();
  return 0;
}

这是一个简单的野牛程序,语法在我看来是正确的,但总是得到语法错误问题... 谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

词法分析器函数yylex需要返回0以指示输入的结束。但是,您的实现只会传递getchar返回的值,该值将为EOF(通常为-1)。

此外,您的输入几乎肯定会包含换行符,也会传递给解析器。

由于解析器既不识别\n也不识别EOF,因此在收到其中一个时会产生错误。

至少,您需要修改yylex以正确响应输入结束:

int yylex(void) {
    int ch = getchar();
    return (ch == EOF) ? 0 : ch;
}

但你仍然需要处理换行符,要么通过在词法分析器中处理它们(可能忽略它们或者可能返回输入imdication的结尾),要么用你的语法处理它们。

请注意,bison / yacc生成的解析器始终解析整个输入流,而不仅仅是解析满足语法的最长序列。这可以通过一些工作来调整 - 请参阅YYACCEPT特殊操作的文档 - 但标准行为通常是解析时所需的。

顺便说一句,请在您的bison / yacc语法中使用标准样式约定,以避免出现问题并避免让读者感到困惑。通常我们为终端符号保留UPPER_CASE,因为它们也在词法分析器中用作编译时常量。非终端通常用lower_case编写,但有些人更喜欢使用CamelCase。对于终端,您需要避免使用标准库保留的名称(例如EOF)或(f)lex(BEGIN)或bison / yacc(END) 。手册中有保留名称列表。