我在分析我的项目时遇到了麻烦。至少我找到了问题出现的最小代码示例。因此,现在尝试解析字符串。
bool func1;const bool func2;
下面是最小示例代码:
namespace qi = boost::spirit::qi;
using qi::lexeme;
using qi::string;
typedef boost::spirit::ascii::space_type TSkipper;
struct MyField
{
bool isConst;
std::string mtype;
std::string name;
};
BOOST_FUSION_ADAPT_STRUCT
(
MyField,
(bool, isConst)
(std::string, mtype)
(std::string, name)
)
void SpiritTestSimple()
{
qi::rule<std::string::const_iterator, std::string(), TSkipper> valid_symbols;
qi::rule<std::string::const_iterator, MyField(), TSkipper> field;
valid_symbols %= lexeme[*qi::char_("a-zA-Z")];
field %= qi::matches[string("const")] >> valid_symbols >> valid_symbols;
std::string data = "aaa aaaa; const bbb bbbb;";
//-----------------------------------------------------------------
std::string::const_iterator first = data.begin(), last = data.end();
std::list<MyField> parsed_vals;
bool is_parsed;
try
{
is_parsed = qi::phrase_parse( first, last,
+(field > ';'),
boost::spirit::ascii::space, parsed_vals);
}
catch(const qi::expectation_failure<std::string::const_iterator>& e)
{
std::string frag(e.first, e.last);
std::cout << e.what() << "'" << frag << "'" << std::endl;
}
BOOST_ASSERT(is_parsed && "the example not parsed");
}我写
+(field > ';')因为在我的项目中,这个块可能不存在。每个函数声明都必须以“;”结尾。当上面的代码示例运行时,我看到了引发的异常,并在控制台中出现了记录:
boost::spirit::qi::expectation_failure''正如我所理解的,在最后一个分号之后,解析器尝试解析下一个字段规则,并解析“匹配”(因为它在任何情况下都返回值),但是valid_symbols的下一个解析失败了,因为在最后一个分号之后没有数据。所以解析失败了。
如何避免在我的情况下解析失败?
发布于 2014-08-31 20:52:17
最大的问题是
valid_symbols = qi::lexeme[*qi::char_("a-zA-Z")];这里的问题是它可以匹配空字符串。因此,“字段”的整个生产过程可以是一个空字符串。如果将其更改为(使用qi::alpha作为速记):
valid_symbols = qi::lexeme[+qi::alpha];您会发现它确实正确地解析了输入。
进一步说明:
+(field > ';')是因为在我的项目中这个块可能不存在”时,这在我看来是自相矛盾的。如果您想使整个块可选,您可以编写
*(字段> ';')
或者如果你想重复;;,我想
*(-field > ';')
(或者可能是+(-field > ';'))。BOOST_SPIRIT_DEBUG来找出你自己的问题有关如何使用精神内置调试功能的演示,请参阅完整的工作示例:住在Coliru
#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
typedef boost::spirit::ascii::space_type TSkipper;
struct MyField
{
bool isConst;
std::string mtype;
std::string name;
};
BOOST_FUSION_ADAPT_STRUCT
(
MyField,
(bool, isConst)
(std::string, mtype)
(std::string, name)
)
template <typename It, typename TSkipper = boost::spirit::ascii::space_type>
struct MyGrammar : qi::grammar<It, std::list<MyField>(), TSkipper>
{
MyGrammar() : MyGrammar::base_type(start) {
valid_symbols = qi::lexeme[+qi::alpha];
field = qi::matches[qi::string("const")] >> valid_symbols >> valid_symbols;
start = +(field > ";");
BOOST_SPIRIT_DEBUG_NODES((valid_symbols)(field)(start))
}
private:
qi::rule<std::string::const_iterator, std::string(), TSkipper> valid_symbols;
qi::rule<std::string::const_iterator, MyField(), TSkipper> field;
qi::rule<std::string::const_iterator, std::list<MyField>(), TSkipper> start;
};
int main()
{
std::string const data = "aaa aaaa; const bbb bbbb;";
//-----------------------------------------------------------------
std::string::const_iterator first = data.begin(), last = data.end();
std::list<MyField> parsed_vals;
bool is_parsed = false;
try
{
MyGrammar<std::string::const_iterator> grammar;
is_parsed = qi::phrase_parse( first, last,
grammar,
boost::spirit::ascii::space,
parsed_vals);
}
catch(const qi::expectation_failure<std::string::const_iterator>& e)
{
std::string frag(e.first, e.last);
std::cout << "Expectation failure: " << e.what() << " at '" << frag << "'" << std::endl;
}
BOOST_ASSERT(is_parsed && "the example not parsed");
}其中的指纹:
<start>
<try>aaa aaaa; const bbb </try>
<field>
<try>aaa aaaa; const bbb </try>
<valid_symbols>
<try>aaa aaaa; const bbb </try>
<success> aaaa; const bbb bbb</success>
<attributes>[[a, a, a]]</attributes>
</valid_symbols>
<valid_symbols>
<try> aaaa; const bbb bbb</try>
<success>; const bbb bbbb;</success>
<attributes>[[a, a, a, a]]</attributes>
</valid_symbols>
<success>; const bbb bbbb;</success>
<attributes>[[0, [a, a, a], [a, a, a, a]]]</attributes>
</field>
<field>
<try> const bbb bbbb;</try>
<valid_symbols>
<try> bbb bbbb;</try>
<success> bbbb;</success>
<attributes>[[b, b, b]]</attributes>
</valid_symbols>
<valid_symbols>
<try> bbbb;</try>
<success>;</success>
<attributes>[[b, b, b, b]]</attributes>
</valid_symbols>
<success>;</success>
<attributes>[[1, [b, b, b], [b, b, b, b]]]</attributes>
</field>
<field>
<try></try>
<valid_symbols>
<try></try>
<fail/>
</valid_symbols>
<fail/>
</field>
<success></success>
<attributes>[[[0, [a, a, a], [a, a, a, a]], [1, [b, b, b], [b, b, b, b]]]]</attributes>
</start>https://stackoverflow.com/questions/25593410
复制相似问题