这很长,有很多代码,所以我希望Stack Overflow能够应对它.:P
我正在尝试用Boost Spirit编写一个SVG解析器.我有一个语法,用"Contours"填充一个矢量,它是"BezierPoints"的矢量,可以用bezier控件表示常规点或点.
到目前为止我有这个(还没有处理相对绘图命令):
#ifndef SVG_PARSER_HPP
#define SVG_PARSER_HPP
#include <vector>
#include "boost/spirit/include/qi.hpp"
#include "boost/spirit/include/phoenix.hpp"
#include "boost/fusion/include/adapt_struct.hpp"
#include "boost/fusion/include/std_pair.hpp"
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
namespace ascii = boost::spirit::ascii;
struct Point
{
Point(const double nx = 0.0, const double ny = 0.0) : x(nx), y(ny)
{}
double x;
double y;
};
BOOST_FUSION_ADAPT_STRUCT(
Point,
(double, x)
(double, y)
)
struct BezierPoint
{
BezierPoint(const double x = 0.0, const double y = 0.0) :
point(x, y), control1(0.0, 0.0), control2(0.0, 0.0) …Run Code Online (Sandbox Code Playgroud) 我需要解析包含键/值对和键/子表达式对的1行表达式,如:
123=a 456=b 789=(a b c) 111=((1=a 2=b 3=c) (1=x 2=y 3=z) (123=(x y z))) 666=evil
Run Code Online (Sandbox Code Playgroud)
为了使解析器更简单,我愿意在几个步骤中进行解析,分离第一级标记(这里是123,456,789,111和666,然后在另一步中解析它们的内容.这里789的值将是"a b c",111的价值将是(1=a 2=b 3=c) (1=x 2=y 3=z) (123=(x y z)).
但是语法在这一点上打败了我,所以我可以找到一种方法来获得匹配括号之间的表达式.所有我得到的111是(1=a 2=b 3=c,它在第一个右括号结束.
我找到了这个方便的例子并尝试使用它,但没有成功:
#include <map>
#include <string>
#include <boost/spirit/include/classic.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>
namespace qi = boost::spirit::qi;
void main()
{
auto value = +qi::char_("a-zA-Z_0-9");
auto key = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9");
qi::rule<std::string::iterator, std::pair<std::string, std::string>()> pair = key >> -('=' >> value);
qi::rule<std::string::iterator, std::map<std::string, std::string>()> query = pair …Run Code Online (Sandbox Code Playgroud) 我必须解析下面的一段文字
Camera {
position 0 0 0
direction 0 -1 0
up 0 1 0
FOVy 45
}
Run Code Online (Sandbox Code Playgroud)
我的选择继续提升:精神,因为我没有处理弹性或野牛.
我终于有了这个语法
struct camera_grammar : qi::grammar<Iterator, camera(), ascii::space_type>
{
qi::rule<Iterator, camera(), ascii::space_type> start;
camera_grammar() : camera_grammar::base_type(start)
{
start %=
lit("Camera")
>> '{'
>> (lit("position") >> float_ >> float_ >> float_)
>> (lit("direction") >> float_ >> float_ >> float_)
>> (lit("up") >> float_ >> float_ >> float_)
>> (lit("FOVy") >> int_)
>> '}'
;
}
};
Run Code Online (Sandbox Code Playgroud)
问题是花括号内的部分甚至可以交换; 我已经阅读了关于置换运算符^但是当至少有一个操作数以任何顺序匹配时,我读到匹配.我需要我的语法才能匹配只有当所有这些都按任何顺序而且只有一次时.
有人能帮助我吗?
我可以编译此页面上的员工示例代码.
如果我用8个字符串扩展结构,如下所示:
struct employee
{
int age;
std::string surname;
std::string forename;
std::string a1;
std::string a2;
std::string a3;
std::string a4;
std::string a5;
std::string a6;
std::string a7;
std::string a8;
double salary;
};
Run Code Online (Sandbox Code Playgroud)
(当然我也扩展了BOOST_FUSION_ADAPT_STRUCT和语法),当我尝试编译时,我得到以下错误:
../include/boost/fusion/container/vector/convert.hpp:26:13: error: invalid use of incomplete type ‘struct boost::fusion::detail::as_vector<12>’
../include/boost/fusion/container/vector/detail/as_vector.hpp:26:12: error: declaration of ‘struct boost::fusion::detail::as_vector<12>’
Run Code Online (Sandbox Code Playgroud)
我发现如果我的struct有> 10个项目会发生这种情况.两个问题:
欢迎任何输入.
我写了这个代码示例并期望它打印OPERATION( OPERATOR(aaa) ID(bbb) )但我只是OPERATION ( OPERATOR(aaa) )改为.这两个result2和it1 == it2是真实的.为什么操作数不被解析?
#include "stdafx.h"
#include <boost/serialization/strong_typedef.hpp>
#include <boost/bind.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix1.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <iostream>
#include <string>
namespace NsSemSDK
{
struct STreeConstructionRuleRegexp {
std::string m_strEntity;
};
struct STreeConstructionRuleString {
std::string m_strEntity;
};
struct STreeConstructionRuleIdentifier {
std::string m_strEntity;
};
typedef int STreeConstructionRuleNumber;
typedef std::string STreeConstructionRuleOperation;
typedef boost::variant<STreeConstructionRuleRegexp, STreeConstructionRuleNumber, STreeConstructionRuleString, STreeConstructionRuleIdentifier> STreeConstructionRuleOperand; …Run Code Online (Sandbox Code Playgroud) 我正在使用boost::spirit::qi解析看起来像这样的"模板"格式:
/path/to/:somewhere:/nifty.json
Run Code Online (Sandbox Code Playgroud)
where :somewhere:表示由名称标识的任何字符串somewhere(名称可以是两个:字符之间的任何字符串).我有一个有效的解析器,但我想做一个额外的改进.
我想知道:somewhere:占位符后面的字符(在本例中为a /).但我的解析器的其余部分仍然需要知道这一点/并将其作为下一部分的一部分使用.
如何/在:somewhere:不实际使用它的情况下"读取" 后面的内容,以便解析器的其余部分可以看到它并使用它.
我想用boost精神来解析像这样的表达式
function1(arg1,arg2,function2(arg1,arg2,arg3),function3(arg1,arg2))
并调用相应的c ++函数.什么应该是语法解析上面的表达式并通过phoneix :: bind()调用相应的c ++函数?
我有两种类型的函数可以调用
1)字符串函数;
wstring GetSubString(wstring stringToCut,int position,int length); wstring GetStringToken(wstring stringToTokenize,wstring seperators,int tokenNumber);
2)返回整数的函数;
int GetCount();
int GetId(wstring srcId,wstring srcType);
当我将输入解析为std :: string时,我得到了字符串,但是当我将其解析为double_时,fusion struct包含一些非常小的数字而不是预期的数字.
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <string>
// http://www.boost.org/doc/libs/1_57_0/libs/spirit/example/qi/employee.cpp
namespace FormatConverter {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
// TODO: should this have an initializer?
struct asc {
double timestamp;
};
}
BOOST_FUSION_ADAPT_STRUCT(
FormatConverter::asc,
(double, timestamp)
)
namespace FormatConverter {
template <typename Iterator>
struct asc_parser : qi::grammar< Iterator, asc(), ascii::space_type >
{
asc_parser()
: asc_parser::base_type(start) {
timestamp %= qi::double_ ;
start %= timestamp ;
;
}
qi::rule< Iterator, double, ascii::space_type > timestamp;
qi::rule< Iterator, asc(), …Run Code Online (Sandbox Code Playgroud) 是否有某个文档描述了各种spirit :: x3规则定义操作如何影响属性兼容性?
我很惊讶:
x3::lexeme[ x3::alpha > *(x3::alnum | x3::char_('_')) ]
Run Code Online (Sandbox Code Playgroud)
无法移动到融合适应的结构中:
struct Name {
std::string value;
};
Run Code Online (Sandbox Code Playgroud)
目前,我摆脱了第一个强制字母字符,但我仍然想表达一个规则,该规则定义名称字符串必须以字母开头.这是其中一种情况,我需要尝试添加eps,直到它工作,或有一个明确的原因,为什么上述不起作用?
如果在某处写下来,我道歉,我找不到它.
(从Spirit-general邮件列表中解除的问题)
你好,
我正在使用精神气的解析器.语法运行良好,但是我有一些问题用Semantic Actions填充我的struct实例.
使用直接结构属性,如"Request.id"和"Request.url",代码正常工作.但我不知道如何填充嵌套结构"Info"中的属性,也不知道如何在"Request.list"中推送值.
这是我的代码(要解析的字符串可以包含任何顺序的值):
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iostream>
#include <vector>
#include <string>
struct Request
{
std::string id;
std::string url;
std::vector<std::string> list;
struct Info
{
std::string id;
std::string desc;
};
Info info;
};
BOOST_FUSION_ADAPT_STRUCT(
Request,
(std::string, id)
)
template <typename Iterator>
struct request_parser : boost::spirit::qi::grammar<Iterator, Request(), boost::spirit::ascii::space_type>
{
request_parser() : request_parser::base_type(start)
{
using namespace boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start …Run Code Online (Sandbox Code Playgroud)