Я не могу понять, как встроить пользовательский класс C ++ в bison
синтаксический анализатор. Вот что у меня есть (только некоторые необходимые кусочки; если вам нужно, я могу опубликовать весь код).
scanner.l
%{
#include "parser.tab.h"#include "types.h"#include <iostream>
#include <string>
#define YY_DECL extern "C" int yylex()
using namespace std;
int chars = 0;
int words = 0;
int lines = 0;
extern "C" {
int yylex(void);
} /* extern "C" */
%}
%%
"none" {
yylval.none_value = none_type();
return NONE;
} /* none type */
{DIGIT_BIN}|{DIGIT_OCT}|{DIGIT_DEC}|{DIGIT_HEX} {
yylval.int_value = atoi(yytext);
return INT;
} /* int type */
parser.y
%{
#include "types.h"#include <iostream>
using namespace std;
void yyerror(const char *error) {
cerr << error << endl;
} /* error handler */
extern "C" {
int yylex(void);
int yyparse(void);
int yywrap() { return 1; }
} /* extern "C" */
%}
%union {
none_type none_value; /* HERE IS WHAT I WANT */
int int_value;
} /* union */
%token <none_value> NONE
%token <int_value> INT
types.h
#include <iostream>
class none_type {
public:
none_type(void);
~none_type();
}; /* none_type */
Как видите, код здесь не полный, но этого должно быть достаточно, чтобы описать то, что я хочу. Все, что я делаю с типами C ++ по умолчанию, работает хорошо; я могу реализовать свои собственные классы?
Компилятор возвращает такие ошибки:
parser.y:20:3: error: 'none_value' does not name a type
In file included from scanner.l:3:0:
parser.y:20:3: error: 'none_value' does not name a type
scanner.l: In function 'int yylex()':
scanner.l:54:32: error: cannot convert 'none_type' to 'int' in assignment
make: *** [caesar] Error 1
Заранее спасибо!
Когда я компилирую ваш код с помощью bison / g ++, я получаю ошибки:
parser.y:16:15: error: member ‘none_type YYSTYPE::none_value’ with constructor not allowed in union
parser.y:16:15: error: member ‘none_type YYSTYPE::none_value’ with destructor not allowed in union
parser.y:16:15: note: unrestricted unions only available with -std=c++0x or -std=gnu++0x
которая точно говорит вам, в чем проблема — вы не можете поместить в объединение не-POD-тип, потому что компилятор не может сказать, какой ctor / dtor вызывать для этого. Обратите внимание на комментарий о том, что вы МОЖЕТЕ сделать это в C ++ 11, но это не очень помогает, так как в этом случае он не будет автоматически вызывать ctor / dtor, поэтому вещи просто не будут созданы или уничтожены должным образом.
Если вы хотите поиграть с помещением подлинных объектов в свой стек, пожалуйста, взгляните на текущую основную ветку Bison, где вы можете запустить примеры, такие как
%token <::std::string> TEXT;
%token <int> NUMBER;
%token END_OF_FILE 0;
%type <::std::string> item;
%type <::std::list<std::string>> list;
%printer { yyoutput << $$; } <int> <::std::string> <::std::list<std::string>>;
%%
result:
list { std::cout << $1 << std::endl; }
;
list:
/* nothing */ { /* Generates an empty string list */ }
| list item { std::swap ($$, $1); $$.push_back ($2); }
;
item:
TEXT { std::swap ($$, $1); }
| NUMBER { $$ = string_cast ($1); }
;
%%
// The yylex function providing subsequent tokens:
// TEXT "I have three numbers for you:"// NUMBER 1
// NUMBER 2
// NUMBER 3
// TEXT " and that's all!"// END_OF_FILE
static
yy::parser::symbol_type
yylex ()
{
static int stage = -1;
++stage;
yy::parser::location_type loc(0, stage + 1, stage + 1);
switch (stage)
{
case 0:
return yy::parser::make_TEXT ("I have three numbers for you.", loc);
case 1:
case 2:
case 3:
return yy::parser::make_NUMBER (stage, loc);
case 4:
return yy::parser::make_TEXT ("And that's all!", loc);
default:
return yy::parser::make_END_OF_FILE (loc);
}
}
Наличие мнения от возможных пользователей этой функции было бы наиболее полезным. Например, о помощи зубров на gnu.org. Увидеть https://savannah.gnu.org/git/?group=bison для Git доступ к хранилищу.