我正在为verilog语言设计一个解析器,其中一个规则有25个组件,我需要一个大的boost :: variant来保存它:
typedef boost::variant<
shared_ptr<T_module_item__port_declaration>
, shared_ptr<T_module_item__generate_region>
, shared_ptr<T_module_item__specify_block>
, shared_ptr<T_module_item__parameter_declaration>
, shared_ptr<T_module_item__specparam_declaration>
, shared_ptr<T_module_item__net_declaration>
, shared_ptr<T_module_item__reg_declaration>
, shared_ptr<T_module_item__integer_declaration>
, shared_ptr<T_module_item__real_declaration>
, shared_ptr<T_module_item__time_declaration>
, shared_ptr<T_module_item__realtime_declaration>
, shared_ptr<T_module_item__event_declaration>
, shared_ptr<T_module_item__genvar_declaration>
, shared_ptr<T_module_item__task_declaration>
, shared_ptr<T_module_item__function_declaration>
, shared_ptr<T_module_item__local_parameter_declaration>
, shared_ptr<T_module_item__parameter_override>
, shared_ptr<T_module_item__continuous_assign>
, shared_ptr<T_module_item__gate_instantiation>
, shared_ptr<T_module_item__udp_instantiation>
, shared_ptr<T_module_item__module_instantiation>
, shared_ptr<T_module_item__initial_construct>
, shared_ptr<T_module_item__always_construct>
, shared_ptr<T_module_item__loop_generate_construct>
, shared_ptr<T_module_item__conditional_generate_construct>
> module_item ;
Run Code Online (Sandbox Code Playgroud)
但是g ++抱怨boost :: variant只能容纳不超过20种类型.
verilogast.h|1129 col 2| error: wrong number of template arguments (25, should be 20)
|| > module_item ;
|| ^ …Run Code Online (Sandbox Code Playgroud) 我编写了一个带有bison的verilog解析器,并使用boost :: variant存储每个规则的每个变体的所有差异情况.我使用一个小例子,BNF表达式来显示我的数据结构:
expression :
primary
| expression + expression
primary :
(expression)
| number
Run Code Online (Sandbox Code Playgroud)
存储它的数据结构是:
typedef boost::variant<
std::shared_ptr<exp1>,
std::shared_ptr<exp2>,
> expression
typedef boost::variant<
std::shared_ptr<prim1>,
std::shared_ptr<prim2>,
> primary
Run Code Online (Sandbox Code Playgroud)
class exp1/2和prim1/2用于存储表达式和primary中的两个不同的case:
class exp1 : public BaseClass {
public :
std::shared_ptr<primary> mem1;
exp1(std::shared_ptr<primary> i1):
mem1(i1)
{}
}
Run Code Online (Sandbox Code Playgroud)
为简化起见,我只显示exp1,而exp2和prim1/2是相似的.在野牛文件中,规则及其操作如下所示:
expression :
primary {
$$= std::make_shared<expression>(std::make_shared<exp1>($1));
}
Run Code Online (Sandbox Code Playgroud)
这样的解决方案导致两个问题:
1编译是veeeeeeeeeeeery慢,用g ++ 4.8.4花费差不多1分钟
2运行时间不是很快
我有一个用ocaml和ocamlyacc编写的类似解析器,它支持非常优化的变量规范,并且用1秒编译,并且运行速度与上面提到的g ++版本非常相似.
我使用boost :: variant的风格有什么问题吗?
我使用构造函数接受shared_ptrs将所有变量更改为类:
class ComponentBase {
};
Class VariantBase{
};
class prim1;
class prim2;
class exp1;
class exp2; …Run Code Online (Sandbox Code Playgroud) 我正在为支持嵌套注释的语言编写一个 flex 扫描器,如下所示:
/*
/**/
*/
Run Code Online (Sandbox Code Playgroud)
我曾经在支持递归调用 lex 扫描器的 ocaml/ocamllex 上工作,非常优雅。但是我现在切换到c++/flex,如何处理这样的嵌套注释?