Строковое значение токена в yacc и lex - PullRequest
0 голосов
/ 22 мая 2018

Я начинаю изучать lex и yacc для анализа ввода оболочки.Сейчас я просто пытаюсь написать парсер для чего-то вроде этой команды |команда |команда.Я с треском проваливаюсь, чтобы попытаться захватить строковое значение для команды, печать, это дает мне ошибку сегментации.Вот код для этого:

файл 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 также возвращает ноль.Буду признателен, если кто-нибудь скажет мне, чего мне не хватает, спасибо!

1 Ответ

0 голосов
/ 22 мая 2018

Если вы используете #define YYSTYPE в своем файле грамматики yacc / bison, вы должны также добавить точно такой же #define в свой файл flex-сканера, и это должно произойти до включения заголовка bison / yacc.В противном случае yylval будет иметь неверный тип в сканере, и присвоение ему будет неопределенным поведением.

Это должно привести к предупреждению компилятора.Пожалуйста, убедитесь, что вы всегда компилируете с включенными предупреждениями.

...