我对Yacc和Lex编程相当新,但我正在训练自己使用C程序分析器。
但是,我面临一个我无法解决的小问题。
当有例如int a,b;
的声明时,我想将a和b保存在一个简单的数组中。我确实设法做到了,但它节省了一点想要的东西。
它实际上是在保存“a”或“b;”而不是“a”和“b”。
它应该有效$1
应该只返回tID
这是一个只识别字符串链的正则表达式。我不明白它为什么会昏迷,即使它被定义为一个标记。有谁知道如何解决这个问题?
以下是相应的yacc声明:
Declaration :
tINT Decl1 DeclN
{printf("Declaration %s\n", $2);}
| tCONST Decl1 DeclN
{printf("Declaration %s\n", $2);}
;
Decl1 :
tID
{$$ = $1;
tabvar[compteur].id=$1; tabvar[compteur].adresse=compteur;
printf("Added %s at adress %d\n", $1, compteur);
compteur++;}
| tID tEQ E
{$$ = $1;
tabvar[compteur].id=$1; tabvar[compteur].adresse=compteur;
printf("Added %s at adress %d\n", $1, compteur);
pile[compteur]=$3;
compteur++;}
;
DeclN :
/*epsilon*/
| tVIR Decl1 DeclN
Lex文件的摘录:
separateur [ \t\n\r]
id [A-Za-z][A-Za-z0-9_]*
nb [0-9]+
nbdec [0-9]+\.[0-9]+
nbexp [0-9]+e[0-9]+
"," { return tVIR; }
";" { return tPV; }
"=" { return tEQ; }
{separateur} ;
{id} { yylval.str = yytext; return tID; }
{nb}|{nbdec}|{nbexp} { yylval.nb = atoi(yytext); return tNB; }
%%
int yywrap() {return 1;}
答案 0 :(得分:1)
问题是yytext
是对lex的令牌扫描缓冲区的引用,因此它仅在解析器下次调用yylex
时才有效。如果要返回,则需要在yytext
中对字符串进行复制。类似的东西:
{id} { yylval.str = strdup(yytext); return tID; }
会做到这一点,但它也会让你暴露出内存泄漏的可能性。
此外,通常在编写涉及单个字符标记的lex / yacc解析器时,将它们直接用作字符常量(例如','
,';'
,很多更清楚,和'='
)而不是在代码中定义命名标记(tVIR
,tPV
和tEQ
。)