我正在尝试从yylex返回符号对象,如本文档http://www.gnu.org/software/bison/manual/html_node/Complete-Symbols.html所示

但是,当我进行编译时,我发现return yy::parser::make_PLUS();被放入int yyFlexLexer::yylex(),所以我收到了此错误消息(许多其他类似的错误消息来自其他规则):

lexer.ll:22:10: error: no viable conversion from 'parser::symbol_type' (aka 'basic_symbol<yy::parser::by_type>') to 'int'
{ return yy::parser::make_PLUS(); }

解决此问题的正确方法是什么?

lexer.ll
%{
#include "ASTNode.hpp"

// why isn't this in parser.tab.hh?
# ifndef YY_NULLPTR
#  if defined __cplusplus && 201103L <= __cplusplus
#   define YY_NULLPTR nullptr
#  else
#   define YY_NULLPTR 0
#  endif
# endif

#include "parser.tab.hh"

#define yyterminate() return yy::parser::make_END()
%}

%option nodefault c++ noyywrap

%%
"+"            { return yy::parser::make_PLUS(); }
"-"            { return yy::parser::make_MINUS(); }
... more rules ...
%%

解析器
%{
#include "AstNode.hpp"
#include ...

static int yylex(yy::parser::semantic_type *arg);
%}

%skeleton "lalr1.cc"

%define api.token.constructor
%define api.value.type variant
%define parse.assert

%token          END 0
%token          PLUS
%token          MINUS
%token ... many tokens ...
%type   <ASTNode *> S statement_list ...

%%

S:      statement_list
        { $$ = g_ast = (StatementList *)$1; }
    ;

... more rules ...

%%

static int yylex(yy::parser::semantic_type *arg) {
    (void)arg;
    static FlexLexer *flexLexer = new yyFlexLexer();
    return flexLexer->yylex();
}

void yy::parser::error(const std::string &msg) {
    std::cout << msg << std::endl;
    exit(1);
}

最佳答案

您必须在生成的扫描器和生成的解析器中使用正确的签名声明yylex。显然,返回int不是您想要的。

在bison发行版中包含的calc++示例(并在bison manual中进行了描述),您可以看到如何执行此操作:


// Tell Flex the lexer's prototype ...
# define YY_DECL \
  yy::calcxx_parser::symbol_type yylex (calcxx_driver& driver)
// ... and declare it for the parser's sake.
YY_DECL;

这只是更改yylex声明的正常方法。尽管bison手册没有提到这一点,并且.ll后缀可以说是令人误解的,但它没有使用C++ flex骨架。它使用C骨架来生成可以用C++编译的文件。据我所知,它甚至没有生成可重入的词法分析器。

calc++.yy file中还有一个重要选项:


// The parsing context.
%param { calcxx_driver& driver }

这表明calcxx_driver& driver是解析器和扫描器的参数。也就是说,将其提供给解析器,解析器会自动将其传递给扫描仪。这与用yylex生成的YY_DECL原型(prototype)匹配。

您可能实际上在扫描程序操作中不需要该对象。我不认为它的使用是强制性的,但是我几乎没有在野牛或flex中使用过C++ API,所以我很可能是错的。

关于c++ - 使yylex返回symbol_type而不是int,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34570823/

10-11 22:43