C 无法找到';语法错误';野牛信息
我正在尝试创建一个简单的解析器/编译器,主要是为了家庭作业,但最终也是为了学习和娱乐。我已经编写了lexer和解析器文件(用于命令的初始子集),我想输出一个AST。然而,即使在我试图解析一个简单的“1+1”时,我仍然被“语法错误”消息所困扰。以下是lexer文件:C 无法找到';语法错误';野牛信息,c,compiler-construction,bison,yacc,lex,C,Compiler Construction,Bison,Yacc,Lex,我正在尝试创建一个简单的解析器/编译器,主要是为了家庭作业,但最终也是为了学习和娱乐。我已经编写了lexer和解析器文件(用于命令的初始子集),我想输出一个AST。然而,即使在我试图解析一个简单的“1+1”时,我仍然被“语法错误”消息所困扰。以下是lexer文件: %{ #include "parser.tab.h" %} DIGIT [0-9] LETTER [a-zA-Z] %% [ \t\n] ; {DIGIT}+ {yylval
%{
#include "parser.tab.h"
%}
DIGIT [0-9]
LETTER [a-zA-Z]
%%
[ \t\n] ;
{DIGIT}+ {yylval = atoi(yytext); return NUMBER;}
{LETTER}* { if (strlen(yytext) <= 8){
printf( "<ID, %s> ", yytext );
} else {
yytext[8] = '\0';
printf("WARNING! Long identifier. Truncating to 8 chars\n");
printf( "<ID, %s> ", yytext );
}
}
"+" {printf("Found '+' symbol\n");return(PLUS);}
"-" return(MINUS);
"*" return(TIMES);
"/" return(DIVIDE);
"(" return(LEFT_PARENTHESIS);
")" return(RIGHT_PARENTHESIS);
<<EOF>> return(END_OF_FILE);
%%
int yywrap (void) {return 1;}
%{
#包括“parser.tab.h”
%}
数字[0-9]
字母[a-zA-Z]
%%
[\t\n];
{DIGIT}+{yylval=atoi(yytext);返回编号;}
{LETTER}*{if(strlen(yytext)代码有一些问题
首先,你的lexer应该包括以下内容:
%{
#include "parser.tab.h"
extern int yylval; // this line was missing
%}
第二,假设您希望代码在语句末尾进行求值,则必须在语句末尾包含一个规则。也就是说,假设它是面向行的,则应使用以下内容替换当前的空白规则:
[ \t] {}
[\n] { return 0; }
第三,你的一句台词被蒙上了。而不是这个:
printf("WARNING! Long identifier. Truncating to 8 chars\n"$
应该是这样的:
printf("WARNING! Long identifier. Truncating to 8 chars\n");
代码有一些问题
首先,你的lexer应该包括以下内容:
%{
#include "parser.tab.h"
extern int yylval; // this line was missing
%}
第二,假设您希望代码在语句末尾进行求值,则必须在语句末尾包含一个规则。也就是说,假设它是面向行的,则应使用以下内容替换当前的空白规则:
[ \t] {}
[\n] { return 0; }
第三,你的一句台词被蒙上了。而不是这个:
printf("WARNING! Long identifier. Truncating to 8 chars\n"$
应该是这样的:
printf("WARNING! Long identifier. Truncating to 8 chars\n");
您的语法接受一个表达式或文件结尾。因此,如果您给它一个表达式,后跟一个文件结尾,您会得到一个错误
另一个问题是,您在输入端返回标记END\u OF_FILE
,而不是0
——bison期望EOF标记出现0
,如果在输入端没有看到,则会给出语法错误
对于这两种方法,最简单的修复方法是去掉文件结尾标记,并让
规则返回0。然后语法变为:
program: /* empty */ { printf("Empty input\n"); }
| exp { printf("Result: %d\n", $1); }
;
...rest of the grammar
现在您有一个(潜在的)问题,语法只接受一个表达式。您可能希望支持多个用换行符或其他分隔符分隔的表达式(;
),这可以通过多种方式完成。您的语法接受表达式或文件结尾。因此,如果您给它一个表达式,后跟文件结尾,则会出现错误
另一个问题是,您在输入端返回标记END\u OF_FILE
,而不是0
——bison期望EOF标记出现0
,如果在输入端没有看到,则会给出语法错误
对于这两种方法,最简单的修复方法是去掉文件结尾标记,并让
规则返回0。然后语法变为:
program: /* empty */ { printf("Empty input\n"); }
| exp { printf("Result: %d\n", $1); }
;
...rest of the grammar
现在您有一个(潜在的)问题,语法只接受一个表达式。您可能希望支持多个由换行符或其他分隔符分隔的表达式,这可以通过多种方式实现。在解析器中,('exp')
:replace(and)使用左括号
和右括号
。添加标记除法
,并为其和减法添加规则。我看不到其他eror。-使用调试器逐步查看eror抛出的位置。谢谢,我已经更正了,但没有成功。尝试其他方法。在解析器中,('exp'))“
:替换(和)使用左括号
和右括号
。添加标记除法
并为其和减法添加规则。我看不到其他eror。-使用调试器逐步查看eror抛出的位置。谢谢,我已更正,但没有成功。尝试其他方法。我已更正所有这些错误,但没有成功成功(除蒙格线外,这是因为复制粘贴错误).现在我已经找到了一个非常简单的示例,我将尝试使用它作为基础,一步一步地重新构建我的文件。如果我最终得到一个解决方案,我会让您知道解决方案。extern int yylval;
是多余的,它将出现在bison生成的parser.tab.h文件中。我已经纠正了所有这些问题,但没有成功(除蒙格线外,这是因为复制粘贴错误).现在我已经找到了一个非常简单的示例,我将尝试使用它作为基础,一步一步地重新构建我的文件。如果我最终得到了一个解决方案,我会让您知道解决方案。extern int yylval;
是多余的——它将出现在bison生成的parser.tab.h文件中。