我在 yacc (bison) 中有一个简单的语法:
表达式.y:
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../C_routines/SyntaxTree.h"
extern int yylineno;
int yylex();
void yyerror(const char *s);
int i=0;
typedef struct Exp {
char *code;
char *addr;
} Exp;
%}
%union {
char *lexeme;
char *value;
double dvalue;
struct SyntaxTree *Sy;
int ivalue;
}
%type <Sy> E S
%token <lexeme> id ID
%token <value> LITERAL
%token <dvalue> FLOAT
%token <ivalue> INT
%left '+' '-'
%left UMINUS
%%
S : id "=" E { $$ = newST('=',newid($1), $3); printSyntaxTree($$); }
;
E : E "+" E { $$ = newST('+', $1, $3); }
| E "-" E { $$ = newST('-', $1, $3); }
| "(" E ")" { $$ = $2; }
| "-" E %prec UMINUS { $$ = newST(UMINUS, NULL, $2); }
| id { $$ = newid($1); }
| INT { $$ = newint($1); }
| FLOAT { $$ = newdouble($1); }
;
%%
void yyerror(const char *s) {
fprintf(stderr, "Parser error at %d: %s\n", yylineno, s);
}
int main() {
yyparse();
return 0;
}
莱克斯:
%option yylineno
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../yacc/expressions.tab.h"
#include "../C_routines/SymbolTable.h"
%}
id [a-zA-Z_][a-zA-Z_0-9]*
INT [-]?[0-9]+
FLOAT [-]?[0-9]+([.][0-9]+)?([Ee][+-]?[0-9]+)?
bool "True" | "False"
str (\"([^\"\\\\]|\\\\.)*\")|('([^'\\\\]|\\\\.)*')
assign [+-/%*]?=
arith [+-/%*]
%%
{id} {
printf("\nIdentifier : %s ", yytext);
int a = installID(yytext, "ID");
yylval.lexeme = strdup(yytext);
return id;
}
{INT} {printf("\nInteger : %s ",yytext);
int a = installLit(yytext,"INT");
yylval.value = strdup(yytext);
return INT;}
{str} {printf("String ");
int a = installLit(yytext,"STR");
yylval.value = strdup(yytext);
return LITERAL;}
{FLOAT} {printf("Float ");
int a = installLit(yytext,"FLOAT");
yylval.value = strdup(yytext);
return FLOAT;}
{assign} {printf("Assignment Operator\n");}
{arith} {printf("Arithmetic Operator\n");}
%%
int yywrap(){
return 1;
}
当我运行这些时:
输出1
a=0
Identifier : a Assignment Operator
Integer : 0 Parser error at 1: syntax error
输出2
a=b
Identifier : a Assignment Operator
Identifier : b Parser error at 1: syntax error
输出3
a=-4
Identifier : a Assignment Operator
Integer : -4 Parser error at 1: syntax error
输出4:
a=5+6
Identifier : a Assignment Operator
Integer : 5 Parser error at 1: syntax error
我已经为操作符和终端定义了足够的优先级和关联性。 我无法弄清楚是什么导致了第 1 行中的语法错误。请帮忙。我使用 flex 作为 lex,使用 bison 作为 yacc
编辑:在声明部分添加
#define YYERROR_VERBOSE 1
给出,
输出1:
a=0
Identifier : a Assignment Operator
Integer : 0 Parser error at 1: syntax error, unexpected INT, expecting =
输出2:
a=a+b
Identifier : a Assignment Operator
Identifier : a Parser error at 1: syntax error, unexpected id, expecting =
输出3:
a = b
Identifier : a Assignment Operator
Identifier : b Parser error at 1: syntax error, unexpected id, expecting =
我在输入中给出了
=
,但它再次要求=符号
Bison 说它没有按预期收到“=”,而且它没有撒谎。 查看词法分析器。该规则打印“赋值运算符”,从不返回任何内容。从解析器的角度来看,那里什么也没有。
由于这些原因,使用printf
进行调试是不可靠的。您应该使用正确的方法来调试您的词法分析器和解析器。