BISEN C++变量与Flex可重入C++ 14示例?

BISEN C++变量与Flex可重入C++ 14示例?,c++,parsing,bison,flex-lexer,bisonc++,C++,Parsing,Bison,Flex Lexer,Bisonc++,我正试图用c++14中的flex/bison工具链编写我的玩具语言 当使用BISE+ C++变体和Flex可重入时,我感到困惑,YYEX找不到参数yLyVal.< /P> 我的开发环境是带有最新操作系统和XCode的macbook,安装了最新flex 2.6.4和bison 3.7.1的自制软件 为方便起见,您可以在此处下载有错误的项目: 现在让我介绍一下这个不那么简单的树项目: 首先让我们看看makefile 应用程序是一个tree.out,它依赖于3个组件:树标记和解析器 树组件 h定义了一

我正试图用c++14中的flex/bison工具链编写我的玩具语言

当使用BISE+ C++变体和Flex可重入时,我感到困惑,YYEX找不到参数yLyVal.< /P> 我的开发环境是带有最新操作系统和XCode的macbook,安装了最新flex 2.6.4和bison 3.7.1的自制软件

为方便起见,您可以在此处下载有错误的项目:

现在让我介绍一下这个不那么简单的树项目:

首先让我们看看makefile 应用程序是一个tree.out,它依赖于3个组件:树标记和解析器

树组件 h定义了一个简单的抽象语法树类,因为我没有实现它,所以它只有一个虚拟析构函数:

#pragma once

struct Tree {
  virtual ~Tree() = default;
};

tree.cpp是主函数,它从stdin读取文件名,初始化lexer和parser,并进行解析:

#include "parser.tab.hh"
#include "token.yy.hh"
#include <cstdio>
#include <cstdlib>

struct Scanner {
  yyscan_t yyscanner;
  FILE *fp;
  YY_BUFFER_STATE yyBufferState;

  Scanner(const char *fileName) {
    yylex_init_extra(this, &yyscanner);
    fp = std::fopen(fileName, "r");
    if (!fp) {
      printf("file %s cannot open!\n", fileName);
      exit(-1);
    }
    yyBufferState = yy_create_buffer(fp, YY_BUF_SIZE, yyscanner);
    yy_switch_to_buffer(yyBufferState, yyscanner);
    yyset_lineno(1, yyscanner);
  }

  virtual ~Scanner() {
    if (yyBufferState) {
      yy_delete_buffer(yyBufferState, yyscanner);
    }
    if (yyscanner) {
      yylex_destroy(yyscanner);
    }
    if (fp) {
      std::fclose(fp);
    }
  }
};

int main(int argc, char **argv) {
  if (argc != 2) {
    printf("missing file name!\n");
    return -1;
  }

  Scanner scanner(argv[1]);
  yy::parser parser(scanner.yyscanner);
  if (parser.parse() != 0) {
    printf("parsing failed!\n");
    return -1;
  }
  return 0;
}
在这里我注意到:这里我们得到了编译错误,我还尝试了make_XXX api,这也给了我错误

它生成token.yy.cc token.yy.hh,希望编译一个token.yy.o对象

解析组件 parser.y:


你能帮我解决这些问题吗?

嗯,我又读了《野牛手册》,自己解决了这个问题

在这里,我们可以看到yylex声明被重新定义:

// Give Flex the prototype of yylex we want ...
# define YY_DECL \
  yy::parser::symbol_type yylex (driver& drv)
// ... and declare it for the parser's sake.
YY_DECL;
这就是为什么我们可以在flex规则中编写如下内容:

return yy::parser::make_MINUS  (loc);

嗯,我又读了野牛手册,自己解决了这个问题

在这里,我们可以看到yylex声明被重新定义:

// Give Flex the prototype of yylex we want ...
# define YY_DECL \
  yy::parser::symbol_type yylex (driver& drv)
// ... and declare it for the parser's sake.
YY_DECL;
这就是为什么我们可以在flex规则中编写如下内容:

return yy::parser::make_MINUS  (loc);
// Give Flex the prototype of yylex we want ...
# define YY_DECL \
  yy::parser::symbol_type yylex (driver& drv)
// ... and declare it for the parser's sake.
YY_DECL;
return yy::parser::make_MINUS  (loc);