C++ 振奋精神:可以';I don’我没能让另一个接线员像我期望的那样工作
我无法让这种精神发挥作用(或者说,做我期望的事情) 这是我的MCVEC++ 振奋精神:可以';I don’我没能让另一个接线员像我期望的那样工作,c++,boost,boost-spirit,C++,Boost,Boost Spirit,我无法让这种精神发挥作用(或者说,做我期望的事情) 这是我的MCVE #include <string> #include <iostream> #include <boost/variant.hpp> #include <boost/spirit/include/qi_parse.hpp> #include <boost/spirit/include/qi.hpp> using namespace boost::spirit; n
#include <string>
#include <iostream>
#include <boost/variant.hpp>
#include <boost/spirit/include/qi_parse.hpp>
#include <boost/spirit/include/qi.hpp>
using namespace boost::spirit;
namespace charset = boost::spirit::qi::standard_wide;
using Expr = boost::variant<std::string, int >;
int main(int argc, char ** argv)
{
std::string intToParse = "{int: 45}";
std::string stringToParse = "{string: \"foo\"}";
using It = std::string::const_iterator;
using Sk = qi::space_type;
qi::rule<It, std::string(), Sk> parseString;
qi::rule<It, int(), Sk> parseInt;
qi::rule<It, std::string(),Sk> string_;
qi::rule<It,Expr(),Sk > orParse;
string_ =
qi::lit('"')
> *(charset::char_ - '"')
> '"';
parseString = qi::omit[ qi::string("string")] > qi::lit(':') > string_;
parseInt = qi::omit[ qi::string("int")] > qi::lit(':') > qi::uint_ ;
orParse = qi::omit[qi::lit('{')] > parseString | parseInt > '}';
orParse.name_ = "alternative parser";
parseString.name_ = "string parser";
parseInt.name_= "int parser";
qi::debug(orParse);
qi::debug(parseString);
qi::debug(parseInt);
Expr res2;
qi::phrase_parse(stringToParse.cbegin(), stringToParse.cend(), orParse, qi::space, res2);
std::cout << res2<< std::endl;
Expr res;
qi::phrase_parse(intToParse.cbegin(), intToParse.cend(), orParse, qi::space, res);
std::cout << res << std::endl;
return 0;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间boost::spirit;
名称空间charset=boost::spirit::qi::standard\u-wide;
使用Expr=boost::variant;
int main(int argc,字符**argv)
{
std::string intToParse=“{int:45}”;
std::string stringToParse=“{string:\“foo\”}”;
使用它=std::string::const_迭代器;
使用Sk=qi::space\u类型;
qi::规则解析字符串;
qi::规则parseInt;
qi::规则字符串;
气:规则还是纵火;
串=
qi::lit(“”)
>*(字符集::字符-'“')
> '"';
parseString=qi::省略[qi::string(“string”)]>qi::lit(“:”)>string;
parseInt=qi::省略[qi::string(“int”)]>qi::lit(':')>qi::uint;
orParse=qi::省略[qi::lit('{')]>parseString | parseInt>'}';
orParse.name=“可选解析器”;
parseString.name=“字符串解析器”;
parseInt.name=“int parser”;
qi::debug(或parse);
qi::debug(解析字符串);
调试(parseInt);
Expr res2;
qi::phrase_parse(stringToParse.cbegin(),stringToParse.cend(),orParse,qi::space,res2);
std::cout运算符>
在表中高于运算符|
,因此需要括号:
orParse = qi::omit[qi::lit('{')] > (parseString | parseInt) > '}';
// here ^ and here ^
结果:
<alternative parser>
<try>{string: "foo"}</try>
<string parser>
<try>string: "foo"}</try>
<success>}</success>
<attributes>[[f, o, o]]</attributes>
</string parser>
<success></success>
<attributes>[[f, o, o]]</attributes>
</alternative parser>
foo
<alternative parser>
<try>{int: 45}</try>
<string parser>
<try>int: 45}</try>
<fail/>
</string parser>
<int parser>
<try>int: 45}</try>
<success>}</success>
<attributes>[45]</attributes>
</int parser>
<success></success>
<attributes>[45]</attributes>
</alternative parser>
45
{string:“foo”}
字符串:“foo”}
}
[f,o,o]]
[f,o,o]]
福
{int:45}
int:45}
int:45}
}
[45]
[45]
45
因此,已经指出了优先级问题。请注意,您可以通过使用编译器的警告捕捉到这一点:
test.cpp|25 col 23| warning: suggest parentheses around comparison in operand of ‘|’ []8;;https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wparentheses-Wparentheses]8;;]
还有许多其他问题。让我从有问题的问题开始:
在需要的地方使用词汇表
不要使用skipper,也不要在skipupper不能操作的地方使用wrap-inqi::lexeme[]
。具体地说,您的string\uu
规则可能不应该跳过空白
另见
其他问题
- 字符集的用法有点不一致。这可能有什么大不了的。我通常使用默认值(
qiL::char\uz,lit,string
)
- 为什么要手动处理调试规则的内部内容
BOOST_SPIRIT_DEBUG_NODES((orParse)(parseString)(parseInt))
- 为什么省略不公开属性的指令上的属性
- 如果要忽略属性,为什么要使用
qi::string
?请改用lit
- 请记住处理错误条件和部分解析
简化固定代码
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace charset = boost::spirit::qi::standard_wide;
using Expr = boost::variant<std::string, int >;
using It = std::string::const_iterator;
using Sk = charset::space_type;
int main()
{
// lexeme!
qi::rule<It, std::string()> string_
= '"' > *~charset::char_('"') > '"';
// with skipper
Sk skip;
qi::rule<It, Expr(), Sk> orParse;
qi::rule<It, std::string(), Sk> parseString;
qi::rule<It, int(), Sk> parseInt;
parseString = qi::lit("string") > ':' > string_;
parseInt = qi::lit("int") > ':' > qi::uint_;
orParse = '{' > (parseString | parseInt) > '}';
BOOST_SPIRIT_DEBUG_NODES((orParse)(parseString)(parseInt))
for (std::string const input: { "{int: 45}", "{string: \"foo\"}" }) {
Expr res;
It f = input.begin(), l = input.end();
if (phrase_parse(f, l, orParse, skip, res)) {
std::cout << "Parsed: " << res << std::endl;
} else {
std::cout << "Failed" << std::endl;
}
if (f != l) {
std::cout << "Remaining: " << std::string(f,l) << "\n";
}
}
}
如果启用了调试:
<orParse>
<try>{int: 45}</try>
<parseString>
<try>int: 45}</try>
<fail/>
</parseString>
<parseInt>
<try>int: 45}</try>
<success>}</success>
<attributes>[45]</attributes>
</parseInt>
<success></success>
<attributes>[45]</attributes>
</orParse>
<orParse>
<try>{string: "foo"}</try>
<parseString>
<try>string: "foo"}</try>
<success>}</success>
<attributes>[[f, o, o]]</attributes>
</parseString>
<success></success>
<attributes>[[f, o, o]]</attributes>
</orParse>
{int:45}
int:45}
int:45}
}
[45]
[45]
{string:“foo”}
字符串:“foo”}
}
[f,o,o]]
[f,o,o]]
哦,是的!太简单了……我的错。注意到了更多的事情,所以发布了一个额外的答案
Parsed: 45
Parsed: foo
<orParse>
<try>{int: 45}</try>
<parseString>
<try>int: 45}</try>
<fail/>
</parseString>
<parseInt>
<try>int: 45}</try>
<success>}</success>
<attributes>[45]</attributes>
</parseInt>
<success></success>
<attributes>[45]</attributes>
</orParse>
<orParse>
<try>{string: "foo"}</try>
<parseString>
<try>string: "foo"}</try>
<success>}</success>
<attributes>[[f, o, o]]</attributes>
</parseString>
<success></success>
<attributes>[[f, o, o]]</attributes>
</orParse>