如何解决将我的yacc和lex文件放在一起时,yacc无法识别我的令牌为什么?
我正在尝试将yacc,lex和语义文件放在一起,以便能够识别以下格式的输入文件:
x = 55;
y = 45.5;
z = - ( x + y );
我感觉好像一切都井井有条,并且在编译时没有出现任何错误,但是yacc和lex似乎什么都没识别。
这是我的lex文件:
%{
#include "IOMngr.h"
#include "y.tab.h"
#define YY_INPUT(buf,result,max_size) \
{ int c = getNextSourceChar(); \
result = (c == EOF) ? YY_NULL : (buf[0] = c,1); \
}
%}
letter [A-Za-z]
digit [0-9]
%%
({digit}+).({digit}+) {return FLOAT;}
{letter}({letter}|{digit})* {return Ident;}
{digit}{digit}* {return INT;}
"+" {return '+';}
"-" {return '-';}
"=" {return '=';}
"*" {return '*';}
")" {return ')';}
"(" {return '(';}
[ ] {}
\t {}
\r {}
\n {}
. {
writeIndicator(getCurrentColumnNum());
writeMessage("Illegal Character in lex");
}
%%
int yywrap() {
return 1;
}
这是我的yacc文件:
%{
#include "SymTab.h"
#include "semantics.h"
#include "IOMngr.h"
#include <string.h>
#include <stdio.h>
extern int yylex();
extern char *yytext;
extern int yyleng;
extern int yyerror(char *);
extern SymTab *table;
extern SymEntry *entry;
%}
%union {
struct number *value;
int integer;
float floatnum;
char * string;
}
%type <string> Id
%type <value> Expr
%type <value> Term
%type <value> Factor
%type <integer> INT
%type <floatnum> FLOAT
%token Ident
%token FLOAT
%token INT
%%
Prog : StmtSeq {printSymTab();};
StmtSeq : Stmt StmtSeq {};
StmtSeq : {};
Stmt : Id '=' Expr ';' {storeVar($1,$3);};
Expr : Expr '+' Term {$$ = doADD($1,$3);};
Expr : Term {$$ = $1;};
Term : Term '*' Factor {$$ = doMULTIPLY($1,$3);};
Term : Factor {$$ = $1;};
Factor : '-' Factor {$$ = doNEGATE($2);};
Factor : '(' Expr ')' {$$ = $2;};
Factor : Id {$$ = getVal($1);};
Factor : INT {$$ = getInt($1);};
Factor : FLOAT {$$ = getFloat($1);};
Id : Ident {$$ = strdup(yytext);};
%%
int yyerror(char *s) {
printf("YYERROR STRING: %s\n",s);
writeIndicator(getCurrentColumnNum());
writeMessage("Illegal Character in YACC");
return 1;
}
这是我的语义。h:
#include <stdlib.h>
#include <string.h>
struct number {
int ival;
float fval;
char type;
};
void printSymTab();
void storeVar(char * name,struct number *v);
struct number *doADD(struct number * n1,struct number * n2);
struct number *doMULTIPLY(struct number *n1,struct number *n2);
struct number *doNEGATE(struct number *n1);
struct number *getVal(char * name);
struct number *getInt(int num);
struct number *getFloat(float num);
最后是我的IOMngr.h(如果相关):
#include <stdlib.h>
#include <stdio.h>
#define MAXLINE 1024
int openFiles(char * sourceName,char * listingName);
void closeFiles();
char getNextSourceChar();
void writeIndicator(int column);
void writeMessage(char * message);
int getCurrentLineNum();
int getCurrentColumnNum();
问题出在yacc或lex文件中。
任何帮助将不胜感激。
解决方法
问题可能出在令牌解码和^-50
的使用上。您不会在.l文件中提取INT / FLOAT / Ident令牌的值;您可以在其他位置访问yytext
(在操作yytext
中,我们可以在您的getInt / getFloat函数中进行假设。)
问题在于这并不安全-yytext指向最后提取的令牌,它可能是您实际想要的令牌的 之后的一个,因为bison使用了一个令牌前瞻。通常,从yacc动作(或从yacc动作调用的函数)访问yytext永远都不安全,因为您不知道要获得哪个令牌。
相反,您需要解码.l文件中的关联令牌值并将其分配给yylval:
Id : Ident {$$ = strdup(yytext);};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。