yacc和lex中令牌的字符串值

时间:2018-05-22 19:14:20

标签: compiler-construction flex-lexer yacc lex

我开始学习lex和yacc来解析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为null,这意味着strdup也返回null。如果有人能告诉我我错过了什么,我将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:1)

如果您在yacc / bison语法文件中使用#define YYSTYPE,则还必须在flex扫描程序文件中放置完全相同的#define,并且必须在包含bison / yacc标头之前。否则,yylval将在扫描程序中输入错误的类型,并为其分配将是未定义的行为。

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