野牛语法错误简单文件

Bison Syntax Error easy file

我正在尝试 运行 这个 .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;
}

这是一个简单的bison程序,语法在我看来是正确的,但总是遇到语法错误问题... 感谢您的帮助。

词法分析器函数yylex需要return0表示输入结束。但是,您的实现只是通过 getchar 编辑的值 return,这将是 EOF(通常为 -1)。

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

由于解析器既不识别 \n 也不识别 EOF,当它接收到其中之一时会产生错误。

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

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

但是您仍然需要处理换行符,或者在您的词法分析器中处理它们(可能忽略它们或者可能 return 结束输入指示),或者在您的语法中处理它们。

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

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