C++ 提高精神分裂规则到不同的标题
我想解析以下结构(为了简单起见,我将只显示其中的一半,但结构的其余部分与所示的相同): 每个部分(以*)将被解析为一个结构。主截面点将包含子截面序号、材料和输出。它还将具有属性名称、任务和继承点C++ 提高精神分裂规则到不同的标题,c++,boost-spirit,boost-spirit-qi,C++,Boost Spirit,Boost Spirit Qi,我想解析以下结构(为了简单起见,我将只显示其中的一半,但结构的其余部分与所示的相同): 每个部分(以*)将被解析为一个结构。主截面点将包含子截面序号、材料和输出。它还将具有属性名称、任务和继承点 Sn部分将被解析为 struct序列号{ std::字符串名称/“Sn” 地图数据; } 材料进入 struct材质{ std::字符串名称//“材质” std::矢量数据; } Kt struct Kt{ std::字符串名称;//“kt” int值; } 输出 struct输出{ std::字符串
- Sn部分将被解析为
struct序列号{ std::字符串名称/“Sn” 地图数据; }
- 材料进入
struct材质{ std::字符串名称//“材质” std::矢量数据; }
- Kt
struct Kt{ std::字符串名称;//“kt” int值; }
- 输出
struct输出{ std::字符串名称;//“输出” std::矢量数据; }
每个
子规则
将被解析为其相应的结构。
为此,我需要能够将lexer传递给每个“子规则”,但我不知道该怎么做 这是我迄今为止所做的 从语法定义中可以看到,规则assignment_Rule2是在一个单独的文件中定义的,但我不知道如何将lexer传递给这个规则。而且它不编译
#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi_real.hpp>
#include <boost/spirit/include/qi_eol.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include "example.hpp"
using namespace boost::spirit;
using boost::phoenix::val;
///////////////////////////////////////////////////////////////////////////////
// class definition
///////////////////////////////////////////////////////////////////////////////
namespace client {
namespace qi = boost::spirit::qi;
struct point
{
std::string name;
std::string name2;
std::string mission;
std::string parent_point;
};
}
BOOST_FUSION_ADAPT_STRUCT(client::point,
(std::string, name),
(std::string, name2),
(std::string, mission),
(std::string, parent_point)
)
namespace client {
///////////////////////////////////////////////////////////////////////////////
// Token id definitions
///////////////////////////////////////////////////////////////////////////////
enum token_ids
{
ID_CONSTANT = 1000,
ID_START_POINT,
ID_END_POINT,
ID_SN,
ID_MATERIAL,
ID_IDENTIFIER,
ID_INTEGER,
ID_FLOAT
};
///////////////////////////////////////////////////////////////////////////////
// Token definitions
///////////////////////////////////////////////////////////////////////////////
template <typename Lexer>
struct example6_tokens : lex::lexer<Lexer>
{
example6_tokens()
{
// define the tokens to match
identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
constant = "[0-9]+";
float_value = "-?\\d+(\\.\\d+)?";
this->self = lex::token_def<>('(') | ')' | '=' | ',' | '*';
this->self.add
(constant, ID_CONSTANT)
("Point", ID_START_POINT)
("End Point", ID_END_POINT)
("Sn", ID_SN)
("Material", ID_MATERIAL)
(identifier, ID_IDENTIFIER)
(float_value, ID_FLOAT)
;
this->self("WS")
= lex::token_def<>("[ \\t\\n]+")
| "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"
;
}
lex::token_def<std::string> identifier;
lex::token_def<unsigned int> constant;
lex::token_def<double> float_value;
};
}
///////////////////////////////////////////////////////////////////////////////
// Grammar definition
///////////////////////////////////////////////////////////////////////////////
namespace client {
template <typename Iterator, typename Lexer>
struct example6_grammar
: qi::grammar<Iterator, point(), qi::in_state_skipper<Lexer> >
{
template <typename TokenDef>
example6_grammar(TokenDef const& tok)
: example6_grammar::base_type(start)
{
using boost::spirit::_val;
using boost::spirit::qi::eol;
using qi::on_error;
using qi::fail;
using qi::debug;
start
= '*'
>> token(ID_START_POINT)
>> ','
>> assignment2
>> ','
>> assignment2
>> ','
>> assignment2
>> *statement
>> '*'
>> token(ID_END_POINT)
;
statement
= sn_stmt
| material_stmt
;
assignment
= tok.identifier >> '=' >> expression
;
sn_stmt = ('*' >> token(ID_SN) >> +pair)
[
std::cout << val("sn statement to: ")
<< _1 << "\n"
]
;
material_stmt = ('*' >> token(ID_MATERIAL) >> +list)
[
std::cout << val("material statement to: ")
<< _1 << "\n"
]
;
list = token(ID_FLOAT) % ',';
pair
= token(ID_CONSTANT) >> ',' >> token(ID_FLOAT)
;
expression
= tok.identifier[_val = _1]
| tok.constant[_val = _1]
;
sn_stmt.name("sn_stmt");
material_stmt.name("material_stmt");
debug(sn_stmt);
debug(material_stmt);
}
typedef boost::variant<unsigned int, std::string> expression_type;
qi::rule<Iterator, point(), qi::in_state_skipper<Lexer> > start;
qi::rule<Iterator, qi::in_state_skipper<Lexer> > statement, material_stmt, pair, list, assignment;
qi::rule<Iterator, qi::in_state_skipper<Lexer>> sn_stmt;
qi::rule<Iterator, expression_type(), qi::in_state_skipper<Lexer> > expression;
Assigment_Rule2<Iterator> assignment2;
};
}
///////////////////////////////////////////////////////////////////////////////
int main()
{
typedef std::string::iterator base_iterator_type;
typedef lex::lexertl::token<
base_iterator_type, boost::mpl::vector<unsigned int, std::string, double>
> token_type;
typedef lex::lexertl::lexer<token_type> lexer_type;
typedef client::example6_tokens<lexer_type> example6_tokens;
typedef example6_tokens::iterator_type iterator_type;
typedef client::example6_grammar<iterator_type, example6_tokens::lexer_def> example6_grammar;
example6_tokens tokens; // Our lexer
example6_grammar calc(tokens); // Our parser
std::string str(read_from_file("ReadMe.txt"));
std::string::iterator it = str.begin();
iterator_type iter = tokens.begin(it, str.end());
iterator_type end = tokens.end();
std::string ws("WS");
client::point my_point;
bool r = qi::phrase_parse(iter, end, calc, qi::in_state(ws)[tokens.self], my_point);
if (r && iter == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << "-------------------------\n";
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
std::cout << "Bye... :-) \n\n";
return 0;
}
\define BOOST\u VARIANT\u USE\u RELAXED\u GET\u默认
#定义BOOST_SPIRIT_调试
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“example.hpp”
使用名称空间boost::spirit;
使用boost::phoenix::val;
///////////////////////////////////////////////////////////////////////////////
//类定义
///////////////////////////////////////////////////////////////////////////////
命名空间客户端{
名称空间qi=boost::spirit::qi;
结构点
{
std::字符串名;
std::字符串名称2;
字符串任务;
std::字符串父节点;
};
}
BOOST_FUSION_ADAPT_STRUCT(客户端::点,
(std::string,name),
(标准::字符串,名称2),
(标准:字符串,任务),
(标准::字符串,父点)
)
命名空间客户端{
///////////////////////////////////////////////////////////////////////////////
//令牌id定义
///////////////////////////////////////////////////////////////////////////////
枚举令牌标识
{
ID_常数=1000,
ID\u起点,
ID\u END\u POINT,
身份证号码,
ID_材料,
ID_标识符,
ID_整数,
浮点数
};
///////////////////////////////////////////////////////////////////////////////
//令牌定义
///////////////////////////////////////////////////////////////////////////////
模板
结构示例6_标记:lex::lexer
{
示例6_代币()
{
//定义要匹配的标记
identifier=“[a-zA-Z][a-zA-Z0-9\]*”;
常量=“[0-9]+”;
浮点值=“-?\\d+(\.\\d+)”;
this->self=lex::token_def(“(”)|“)”|“=”|“,”|“*”;
此->self.add
(常数,ID_常数)
(“点”,ID\u起点)
(“终点”,ID\U End\U Point)
(“序号”,识别号)
(“材料”,ID_材料)
(标识符,ID\U标识符)
(浮动\u值,ID\u浮动)
;
这个->自我(“WS”)
=lex::token_def(“[\\t\\n]+”)
| "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"
;
}
lex::token_def标识符;
lex::token_def常量;
lex::token_def float_值;
};
}
///////////////////////////////////////////////////////////////////////////////
//语法定义
///////////////////////////////////////////////////////////////////////////////
命名空间客户端{
模板
结构示例6_语法
:qi::语法
{
模板
示例6_语法(TokenDef const&tok)
:示例6语法::基本类型(开始)
{
使用boost::spirit::\u val;
使用boost::spirit::qi::eol;
使用qi::on_错误;
使用qi::失败;
使用qi::调试;
开始
= '*'
>>令牌(ID\u起点\u点)
>> ','
>>转让2
>> ','
>>转让2
>> ','
>>转让2
>>*声明
>> '*'
>>令牌(ID\U结束点)
;
陈述
=sn_stmt
|材料试验
;
分配
=tok.identifier>>'='>>表达式
;
序列号stmt=('*'>>令牌(ID\u序列号)>>+对)
[
标准::cout>+列表)
[
标准::cout>token(ID\u FLOAT)
;
表达
=tok.identifier[\u val=\u 1]
|托克常数[_val=_1]
;
序号名称(“序号”);
材料名称(“材料”);
调试(序列号stmt);
调试(材料测试);
}
typedef boost::变量表达式类型;
qi::规则开始;
qi::规则语句、材质、配对、列表、赋值;
qi::规则序列号;
qi:规则表达;
分配规则2转让2;
};
}
///////////////////////////////////////////////////////////////////////////////
int main()
{
typedef std::string::迭代器
#define BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi_real.hpp>
#include <boost/spirit/include/qi_eol.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include "example.hpp"
using namespace boost::spirit;
using boost::phoenix::val;
///////////////////////////////////////////////////////////////////////////////
// class definition
///////////////////////////////////////////////////////////////////////////////
namespace client {
namespace qi = boost::spirit::qi;
struct point
{
std::string name;
std::string name2;
std::string mission;
std::string parent_point;
};
}
BOOST_FUSION_ADAPT_STRUCT(client::point,
(std::string, name),
(std::string, name2),
(std::string, mission),
(std::string, parent_point)
)
namespace client {
///////////////////////////////////////////////////////////////////////////////
// Token id definitions
///////////////////////////////////////////////////////////////////////////////
enum token_ids
{
ID_CONSTANT = 1000,
ID_START_POINT,
ID_END_POINT,
ID_SN,
ID_MATERIAL,
ID_IDENTIFIER,
ID_INTEGER,
ID_FLOAT
};
///////////////////////////////////////////////////////////////////////////////
// Token definitions
///////////////////////////////////////////////////////////////////////////////
template <typename Lexer>
struct example6_tokens : lex::lexer<Lexer>
{
example6_tokens()
{
// define the tokens to match
identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
constant = "[0-9]+";
float_value = "-?\\d+(\\.\\d+)?";
this->self = lex::token_def<>('(') | ')' | '=' | ',' | '*';
this->self.add
(constant, ID_CONSTANT)
("Point", ID_START_POINT)
("End Point", ID_END_POINT)
("Sn", ID_SN)
("Material", ID_MATERIAL)
(identifier, ID_IDENTIFIER)
(float_value, ID_FLOAT)
;
this->self("WS")
= lex::token_def<>("[ \\t\\n]+")
| "\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/"
;
}
lex::token_def<std::string> identifier;
lex::token_def<unsigned int> constant;
lex::token_def<double> float_value;
};
}
///////////////////////////////////////////////////////////////////////////////
// Grammar definition
///////////////////////////////////////////////////////////////////////////////
namespace client {
template <typename Iterator, typename Lexer>
struct example6_grammar
: qi::grammar<Iterator, point(), qi::in_state_skipper<Lexer> >
{
template <typename TokenDef>
example6_grammar(TokenDef const& tok)
: example6_grammar::base_type(start)
{
using boost::spirit::_val;
using boost::spirit::qi::eol;
using qi::on_error;
using qi::fail;
using qi::debug;
start
= '*'
>> token(ID_START_POINT)
>> ','
>> assignment2
>> ','
>> assignment2
>> ','
>> assignment2
>> *statement
>> '*'
>> token(ID_END_POINT)
;
statement
= sn_stmt
| material_stmt
;
assignment
= tok.identifier >> '=' >> expression
;
sn_stmt = ('*' >> token(ID_SN) >> +pair)
[
std::cout << val("sn statement to: ")
<< _1 << "\n"
]
;
material_stmt = ('*' >> token(ID_MATERIAL) >> +list)
[
std::cout << val("material statement to: ")
<< _1 << "\n"
]
;
list = token(ID_FLOAT) % ',';
pair
= token(ID_CONSTANT) >> ',' >> token(ID_FLOAT)
;
expression
= tok.identifier[_val = _1]
| tok.constant[_val = _1]
;
sn_stmt.name("sn_stmt");
material_stmt.name("material_stmt");
debug(sn_stmt);
debug(material_stmt);
}
typedef boost::variant<unsigned int, std::string> expression_type;
qi::rule<Iterator, point(), qi::in_state_skipper<Lexer> > start;
qi::rule<Iterator, qi::in_state_skipper<Lexer> > statement, material_stmt, pair, list, assignment;
qi::rule<Iterator, qi::in_state_skipper<Lexer>> sn_stmt;
qi::rule<Iterator, expression_type(), qi::in_state_skipper<Lexer> > expression;
Assigment_Rule2<Iterator> assignment2;
};
}
///////////////////////////////////////////////////////////////////////////////
int main()
{
typedef std::string::iterator base_iterator_type;
typedef lex::lexertl::token<
base_iterator_type, boost::mpl::vector<unsigned int, std::string, double>
> token_type;
typedef lex::lexertl::lexer<token_type> lexer_type;
typedef client::example6_tokens<lexer_type> example6_tokens;
typedef example6_tokens::iterator_type iterator_type;
typedef client::example6_grammar<iterator_type, example6_tokens::lexer_def> example6_grammar;
example6_tokens tokens; // Our lexer
example6_grammar calc(tokens); // Our parser
std::string str(read_from_file("ReadMe.txt"));
std::string::iterator it = str.begin();
iterator_type iter = tokens.begin(it, str.end());
iterator_type end = tokens.end();
std::string ws("WS");
client::point my_point;
bool r = qi::phrase_parse(iter, end, calc, qi::in_state(ws)[tokens.self], my_point);
if (r && iter == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << "-------------------------\n";
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
std::cout << "Bye... :-) \n\n";
return 0;
}
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/qi_real.hpp>
#include <boost/spirit/include/qi_eol.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi_char_.hpp>
#include <boost/spirit/include/qi_lexeme.hpp>
using namespace boost::spirit;
using boost::phoenix::val;
namespace client {
template <typename Iterator>
struct Assigment_Rule2
: qi::grammar<Iterator, std::string()>
{
Assigment_Rule2()
: Assigment_Rule2::base_type(start)
{
using boost::spirit::double_;
using boost::spirit::lexeme;
using boost::spirit::ascii::char_;
start = ( "2">> '=' >> "2" )
[
_val = _2
]
;
}
qi::rule<Iterator, std::string()> start;
};
}