Включить структуру в% union def с Bison/Yacc

Я пытаюсь включить структуру как часть объединения с Bison, но я получаю сообщение об ошибке "struct node args" в% union:

parser.y:17: error: field ‘args’ has incomplete type

Код:

struct node {
    char * val;
    struct node * next;
};

%}

%union {
    char * string;
    struct node args;
}

%token <string> CD WORD PWD EXIT

%type <args> arg_list

Кто-нибудь знает, что я делаю неправильно?

Ответы

Ответ 1

Это сводится к выходу lame y.tab.h, который вы получаете.

Вам нужно исправить это, убедившись, что "struct node" определено до того, как вы включите y.tab.h в любом месте.

Для этого создайте файл node.h с определением структуры.

Затем включите node.h перед y.tab.h в файл parser.l.l, файл parser.y, а также любые c файлы, которые у вас есть, включая y.tab.h. Это немного раздражает.

В качестве альтернативы вы можете изменить "struct node args" на "struct node * args", поскольку вам не нужно будет знать полный тип, пока вы не начнете его использовать. Не уверен, что это будет соответствовать вашему коду.

Либо один должен работать.

Ответ 2

Еще лучше, используйте директиву% code с параметром "требуется", т.е.:

%code requires {
    struct node {
        char * val;
        struct node * next;
    };
}

%union {
    char * string;
    struct node args;
}

Это будет включать код в блоке "требуется" в файле tab.h, а также исходный файл парсера.

Из документации: http://www.gnu.org/software/bison/manual/html_node/Decl-Summary.html#Decl-Summary

  • требует
    • Цель: это лучшее место для написания кода зависимостей, необходимого для YYSTYPE и YYLTYPE. Другими словами, это лучшее место для определения типов ссылаются в директивах% union и это лучшее место для переопределения Bison default YYSTYPE и YYLTYPE определений.

Ответ 3

Может быть, проще (я думаю) - сам использовал:

%union {
  char   c; 
  struct {
     char name[30];
     int  type;
  } s;
}

Затем в flex вы можете использовать "yylval.s.name" или "yylval.s.type" и т.д., в то время как в бизоне вместо $$=0, $1=bla... теперь вы можете написать $<s.type>$=0 , $<s.type>1=bla...