词汇&使用Yacc和Lex进行语法分析

时间:2017-02-18 17:08:04

标签: c yacc lex

我对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;}

1 个答案:

答案 0 :(得分:1)

问题是yytext是对lex的令牌扫描缓冲区的引用,因此它仅在解析器下次调用yylex时才有效。如果要返回,则需要在yytext中对字符串进行复制。类似的东西:

{id}                   { yylval.str = strdup(yytext); return tID; }

会做到这一点,但它也会让你暴露出内存泄漏的可能性。

此外,通常在编写涉及单个字符标记的lex / yacc解析器时,将它们直接用作字符常量(例如','';'很多更清楚,和'=')而不是在代码中定义命名标记(tVIRtPVtEQ。)