Lex& yacc解析语句

时间:2015-05-06 20:08:19

标签: yacc lex

我正在尝试使用lex和yacc构建一个非常简单的语言 它可以通过赋值只有一个int变量,如

a = 1

它可以像这样打印变量

print a

只有在变量名称匹配时才必须打印该值,否则必须打印错误消息
我的lex文件是

%{
    #include "y.tab.h"
    #include <stdlib.h>
    void yyerror(char *);
%}
letter      [A-z]
digit       [0-9]
%%
"print"         {return PRINT;}
{letter}+      { yylval.id = yytext;return IDENTIFIER;}
{digit}+      { yylval.num = atoi(yytext);return NUMBER; }

[=\n]      return *yytext;

[ \t]       ; /* skip whitespace */

.           yyerror("invalid character");

%%

int yywrap(void) {
    return 1;
}

我的yacc文件是

%{
    #include <stdio.h>
    #include <string.h>
    int yylex(void);
    void yyerror(char *);
    int value;
    char *key;
    void print_var(char *s);
%}
%union {char *id;int num;}
%start exp
%token <id>   IDENTIFIER
%token <num>   NUMBER
%token PRINT

%%

exp: IDENTIFIER '=' NUMBER '\n' {key = $1;value = $3;}
    |PRINT IDENTIFIER '\n'      {print_var($2);}
    |exp IDENTIFIER '=' NUMBER '\n' {key = $2;value = $4;}
    |exp PRINT IDENTIFIER '\n'      {print_var($3);}
    ;
%%
void yyerror(char *s) {
    fprintf(stderr, "%s\n", s);
}

void print_var(char *s){
    if(strcmp(s,key) == 0){
        printf("%s:%d\n",key,value);
    }else{
        printf("%s not found\n",s);
    }
}

int main(void) {
    yyparse();
    return 0;
}

但是当我输入类似这样的内容时

a = 1
print a

我收到以下错误 一个  找不到

1 个答案:

答案 0 :(得分:0)

一旦你的lex程序返回到yacc(或基本上,在规则之外的任何地方),yytext值不一定是不受影响的。您应该使用id或其他内容在yytext中对字符串进行复制,而不是将strdup指向yytext。< / p>

21.3 A Note About yytext And Memory 中的flex手册中提到了这一点。

在你的语法中,这是唯一显示的规则:

exp: IDENTIFIER '=' NUMBER '\n' {key = $1;value = $3;}
    |PRINT IDENTIFIER '\n'      {print_var($2);}
    |exp IDENTIFIER '=' NUMBER '\n' {key = $2;value = $4;}
    |exp PRINT IDENTIFIER '\n'      {print_var($3);}
    ;

它将指针复制到全局变量key(再次,这会遇到内存损坏问题)并打印$2标识符。如果您在lex程序中分配了yytext的副本,则可以在print_var中安全地释放该副本。 key的两个赋值应该替换为设置key的函数的调用,同时检查它是否已设置,例如,

void set_key(const char *value)
{
    if (key != 0)
        free(key);
    key = strdup(value);
}

这样,一次只能分配一份yytext - 一份微不足道的记忆。