flex和bison:C++;用户定义类 < >我无法理解如何将C++用户定义的类嵌入到 BISO/语法分析器中。这里是我所拥有的(只是一些必要的部分;如果您需要,我可以发布所有代码)

flex和bison:C++;用户定义类 < >我无法理解如何将C++用户定义的类嵌入到 BISO/语法分析器中。这里是我所拥有的(只是一些必要的部分;如果您需要,我可以发布所有代码),c++,class,compiler-construction,bison,flex-lexer,C++,Class,Compiler Construction,Bison,Flex Lexer,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); } /* ex

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 */
types.h

#include <iostream>

class none_type {
  public:
    none_type(void);
    ~none_type();
}; /* none_type */

提前谢谢

当我使用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中做这个注释,但这并没有什么帮助,因为在这种情况下它不会自动调用Cto/Dor,所以它不会被正确地构造或破坏。< /P> < P>当我用BISO/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中做这个注释,但这并没有什么帮助,因为在这种情况下它不会自动调用Cto/Dor,所以它不会被正确地构造或破坏。

< P>如果你想玩真正的对象在你的栈上,那么请看一下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);
  }
}
%令牌文本;
%令牌号;
%_文件0的令牌结束_;
%类型项目;
%类型列表;

%打印机{yyoutput如果您想在堆栈上放置真正的对象,请查看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);
  }
}
%令牌文本;
%令牌号;
%_文件0的令牌结束_;
%类型项目;
%类型列表;

%印刷机{yyoutput您不能在
%union
中有类类型。但是您可以有指针。我不明白您为什么想要一个空类型,或者这只是一个示例?您可以只让任何类型都没有int类型,并且永远不引用它的值。@rici:这只是一个示例。我想要类似
Python
NONE
类型“我不确定它是否像
C/C++
中的
void
那样
C
中的
void
那样没有价值,所以它不是真正像
None
。总之,flex/bison不像Python那样是强类型的。没有运行时类型;你需要知道每个值的类型才能使用它。因此,在这个特定的例子中,你是p使用默认值为0的
int
可能更好。在
%union
中不能有类类型。但是可以有指针。我不明白为什么你想要一个空类型,或者这只是一个例子?你可以不让任何人有int类型,也不能引用它的值。@rici:这只是一个例子。我想这样做类似于
Python
None
类型,我不确定它是否像
C/C++
中的
void
一样
C
中的
void
没有任何值,所以它不是真正像
None
那样。无论如何,flex/bison不像Python那样是强类型的。没有运行时类型;你需要知道每个va的类型因此,在这种特殊情况下,您最好只使用默认值为0的
int
。谢谢!因为这是唯一的答案,也是正确的,所以我将其标记为已接受。我只有一个问题:您将如何解决此问题?@rici建议的方法如何?您是否有更好的方法解决方案?谢谢!因为这是唯一的答案,也是正确的,所以我将其标记为已接受。我只有一个问题:您将以什么方式解决此问题?@rici建议的方式如何?您是否有更好的解决方案?