首页 > 解决方案 > yacc 和 lex 中令牌的字符串值

问题描述

我开始学习 lex 和 yacc 来解析 aa shell 的输入。现在我只是想为这样的命令编写解析器 | 命令 | 命令。我在尝试捕获命令的字符串值时失败了,打印它会给我一个分段错误。这是它的代码:

.lex 文件:

    %{

#include <stdio.h>
#include "y.tab.h"
#include <string.h>
%}

%%

grep|vim|ls|who     {yylval = strdup(yytext); return COMMAND;}
"|"                 return PIPE;

%%

yacc 文件:

%{

#include <stdio.h>
#include <string.h>
#define YYSTYPE char*
void yyerror(const char* str)
{
    fprintf(stderr, "error: %s\n", str);
}

int yywrap()
{
    return 1;
}

main()
{
    yyparse();
}


%}

%token PIPE COMMAND

%%


statement:
        command
        |
        statement PIPE command
        ;


command:
        COMMAND
        {
            printf("command: %s encountered\n", $1);
        }
        ;

我相信由于某种原因,命令块中的 $1 为空,这意味着 strdup 也返回空。如果有人能告诉我我缺少什么,我将不胜感激,谢谢!

标签: compiler-constructionflex-lexeryacclex

解决方案


如果你#define YYSTYPE在你的 yacc/bison 语法文件中使用,你也必须在你的 flex 扫描器文件中使用完全相同的#define内容,并且它必须在包含 bison/yacc 头文件之前。否则,yylval扫描仪中的类型将错误,分配给它的将是未定义的行为。

这应该会产生编译器警告。请确保您始终在启用警告的情况下进行编译。


推荐阅读