Включить структуру в% union def с помощью Bison / Yacc - PullRequest
18 голосов
/ 16 сентября 2009

Я пытаюсь включить struct как часть объединения с Bison, но я получаю сообщение об ошибке «аргументы struct node» в% 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

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

Ответы [ 3 ]

25 голосов
/ 09 февраля 2011

Еще лучше, используйте директиву% code с опцией «require», то есть ::1001*

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

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

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

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

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

Все сводится к полученному неудачному выводу y.tab.h.

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

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

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

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

Либо надо работать.

1 голос
/ 23 января 2016

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

%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...

...