Lex & yacc 解析语句

Lex & yacc parsing statements

我正在尝试使用 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 = ;value = ;}
    |PRINT IDENTIFIER '\n'      {print_var();}
    |exp IDENTIFIER '=' NUMBER '\n' {key = ;value = ;}
    |exp PRINT IDENTIFIER '\n'      {print_var();}
    ;
%%
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

我收到以下错误 一种 未找到

一旦你的 lex 程序 returns 到 yacc(或者基本上,在规则之外的任何地方),yytext 值不一定保持不变。与其让 id 成为指向 yytext 的指针,不如使用 strdup 或其他东西来对 [=12= 中的字符串进行 复制 ].

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

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

exp: IDENTIFIER '=' NUMBER '\n' {key = ;value = ;}
    |PRINT IDENTIFIER '\n'      {print_var();}
    |exp IDENTIFIER '=' NUMBER '\n' {key = ;value = ;}
    |exp PRINT IDENTIFIER '\n'      {print_var();}
    ;

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

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

一次分配的 yytext 副本不会超过一个 — 内存量微不足道。