c++ - 在 Bison 和 Flex 中使用变体
问题描述
我一直在将解析器从 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> ¶ms, const std::string &scaleFactorName);
^~~~
MOVE
是一个定义为的结构
struct MOVE {
MOVE(const Scalable<double, 3> ¶ms, 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"}});
解决方案
您没有包含足够的程序来提供精确的答案。请参阅有关准备 [mcse] 的 SO 帮助页面。但是您似乎很可能会收到错误消息
y.tab.h:125:18: error: ‘variant’ in namespace ‘std’ does not name a template type
因为你还没有安排#include <variant>
在你的弹性文件中。
typedef 本身来自 bison 生成的头文件中的生成代码,但 bison 无法猜测#include
它可能需要哪些指令,因此由您来插入它们。您必须确保您的语义类型所需的所有类型都已#include
在野牛生成的标头之前定义。#include
你可以在你的 flex 文件的序言块中插入适当的指令,或者你可以%code requires
在你的野牛文件中使用一个块。(由于您使用的是 bison 3,后者可能是最好的解决方案。)
我不知道SAVE
你的野牛文件中的错误是什么意思。我假设它是您拥有(或尚未定义)的宏,因此错误将是宏扩展的结果。
推荐阅读
- react-native - TextInput 在一次击键后停止输入 - 禁止连续输入
- javascript - Google Apps 脚本中的附件问题
- flutter - 如何在 Flutter 中使用 Riverpod 中的异步值?
- vue-formulate - 我可以通过 Vue Formulate 的模式 API 传递元数据而不影响输入属性吗?
- apache-spark - PySpark 在嵌套字段中添加新对象(如果不存在)
- node.js - 如何在独立的离线服务器上安装 npm 包?
- ios - AVAudioEngine 在 macOS/iOS 上协调/同步输入/输出时间戳
- python - 具有多级菜单的 Telegram Bot,无需发送消息
- java - 需要一个 java 处理类来将鼠标移动到窗口中心
- javascript - 如何在javascript中将字符串列表转换为数组