Использование варианта в Bison и Flex - PullRequest
2 голосов
/ 12 июня 2019

Я переписываю парсер с c на c ++ и поэтому пытаюсь использовать вариант с моим кодом.Тем не менее, я не уверен, как интегрировать его с flex, и я продолжаю получать сообщения об эзотерических ошибках.

Мой файл бизонов выглядит как

%require "3"
%language "c++"

%{
    // declarations
%}

%define api.value.type {std::variant<double, std::string>}

%token COMMENT
%token <double> DOUBLE
%token <std::string> STRING

// grammar

, а мой лексер выглядит как

%{
#include "y.tab.h"
%}
%option noyywrap

ID [a-zA-Z][a-zA-Z0-9_]*


%%
[ \t\n ]+ ;

\-?[0-9]+ |
\-?[0-9]+\. |
\-?[0-9]+\.[0-9]+ |
\-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
// other tokens
zA-Z][\.a-zA-Z0-9_]* { yylval.emplace<std::string>(yytext); return STRING;}
%%

Я не уверен в своем использовании yylval, я пытаюсь получить доступ квариант, как у меня с %union.

Я получаю следующую ошибку:

y.tab.h:125:18: error: ‘variant’ in namespace ‘std’ does not name a template type
     typedef std::variant<double, std::string> semantic_type;
                  ^~~~~~~
y.tab.h:197:27: error: ‘semantic_type’ does not name a type
                     const semantic_type& v);
                           ^~~~~~~~~~~~~
y.tab.h:212:7: error: ‘semantic_type’ does not name a type
       semantic_type value;
       ^~~~~~~~~~~~~
my_mdl.l: In function ‘int yylex()’:
my_mdl.l:16:3: error: ‘yylval’ was not declared in this scope
 \-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
   ^~~~~~
my_mdl.l:16:3: note: suggested alternative: ‘yylex’
 \-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
   ^~~~~~
   yylex
my_mdl.l:16:18: error: expected primary-expression before ‘double’
 \-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
                  ^~~~~~
my_mdl.l:16:53: error: ‘DOUBLE’ was not declared in this scope
 \-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
                                                     ^~~~~~
my_mdl.l:18:10: error: ‘COMMENT’ was not declared in this scope
 "//".* { return COMMENT;}
          ^~~~~~~
my_mdl.l:37:29: error: expected primary-expression before ‘>’ token
 [a-zA-Z][\.a-zA-Z0-9_]* { yylval.emplace<std::string>(yytext); return STRING;}
                             ^
my_mdl.l:37:47: error: ‘STRING’ was not declared in this scope
 [a-zA-Z][\.a-zA-Z0-9_]* { yylval.emplace<std::string>(yytext); return STRING;}
                                               ^~~~~~

Я также получаю несколько сотен строк ошибок из моего файла .y, такого как

my_mdl.y:88:79: error: no matching function for call to ‘MOVE::MOVE(<brace-enclosed initializer list>)’
     p.add_command(Command{in_place_index<5>, MOVE( {{$2, $3, $4}}, $5)});
                                                                               ^
In file included from parsing/symt.h:7:0,
                 from my_mdl.y:10:
parsing/cmd.h:44:5: note: candidate: MOVE::MOVE(const Scalable<double, 3>&, const string&)
     MOVE(const Scalable<double, 3> &params, const std::string &scaleFactorName);
     ^~~~

MOVE - это структура, определенная как

struct MOVE {
    MOVE(const Scalable<double, 3> &params, const std::string &scaleFactorName);

    Scalable<double, 3> params; // todo equationify
    std::string scale_factor_name;
};

, и это один из типов в варианте (std::variant<MOVE, etc...> Command).Странно то, что это нормально работает в моем коде, если я пишу p.add_command(Command{in_place_index<5>, MOVE{{{x, y, z}}, "asdfads"}});

1 Ответ

1 голос
/ 12 июня 2019

Вы не включили достаточно своей программы, чтобы дать точный ответ. Пожалуйста, смотрите страницу помощи SO по подготовке [mcse]. Но похоже, что вы получаете ошибку

y.tab.h:125:18: error: ‘variant’ in namespace ‘std’ does not name a template type

потому что вы не договорились о том, чтобы #include <variant> был в вашем гибком файле.

Сама typedef взята из сгенерированного кода в заголовочном файле, созданного bison, но bison не может угадать, какие директивы #include могут ему понадобиться, поэтому он оставляет их на ваше усмотрение, чтобы вставить их. Вы должны убедиться, что все типы, необходимые для вашего семантического типа, были определены до того, как вы #include создадите бизон-заголовок. Вы можете вставить соответствующие директивы #include в блок пролога вашего гибкого файла, или вы можете использовать блок %code requires в вашем файле зубров. (Поскольку вы используете бизона 3, последнее, вероятно, является лучшим решением.)

Понятия не имею, что означает SAVE в ошибках из вашего файла бизонов. Я предполагаю, что это макрос, который вы имеете (или не определили), поэтому ошибка будет результатом расширения макроса.

...