Как переопределить `YYSTYPE` в` bison / yacc`? - PullRequest
0 голосов
/ 01 мая 2020

Я определяю пользовательский класс для хранения всего объекта. Но yacc собирается создать заголовочный файл, тип yylval которого должен быть YYSTYPE. Если я не использую %union, он будет содержать его как int. Но если я использую %union, это будет союз. и union уродлив - он не может содержать класс или shared_ptr (может, но не очень хорошая идея), он только хочет, чтобы я использовал указатель.

Я просто хочу, чтобы YYSTYPE имел тип в качестве пользователя тип класса. Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 01 мая 2020

Не используйте YYSTYPE.

С бизоном - это то, что вы фактически используете в качестве реализации ya cc - правильный способ определить тип значения semanti c

%define api.value.type { MyType }

Если требуется, чтобы один или несколько файлов заголовков были включены в объявление, чтобы оно было действительным, поместите их в блок %code requires:

%code requires {
   #include "MyType.h"
}

Код, сгенерированный этими две директивы копируются в файл заголовка, который создает bison, поэтому другие файлы должны включать только сгенерированный файл заголовка.

Предупреждение: Обратите внимание, что если вы не используете интерфейс Cison Bison, semanti c тип значения должен быть легко копируемым, что исключит большинство стандартных типов библиотек C ++. Несоблюдение этого правила приведет к неопределенному поведению, которое может go быть незамеченным, пока вы не попытаетесь проанализировать достаточно сложный ввод. Другими словами, тесты с простыми входными данными могут не выявить ошибку.

0 голосов
/ 01 мая 2020

Как видите, исходный файл, созданный с помощью lex и yacc, нуждается в заголовочном файле, который сделан с помощью yacc.

заголовка, поэтому мы можем найти какое-то решение в нем .

часть, определяющая тип yylval, выглядит следующим образом:

/* Value type.  */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif


extern YYSTYPE yylval;

, поэтому мы можем определить YYSTYPE до включения заголовочного файла yacc, выглядит так :

#include "your-header-file-that-define-the-class.h"
#define YYSTYPE your-class-type
#include "the-header-file-that-made-by-yacc.h"
...