所以,只是为了向你展示我的意思,我已经清理了语法。
在 Coliru 上看到它
Parser() : Parser::base_type(root)
{
using namespace qi::iso8859_1;
braces =
'{' >> qi::eps >> '}'
;
str = qi::lexeme [
'"'
>> *~char_('"')
>> '"'
]
;
tolleaf = qi::lexeme [
+(~char_("\"{}= \t\r\n"))
]
;
leaf = qi::lexeme [
+(alnum | char_("-._:"))
]
;
taglist =
'{'
>> -str % tolleaf
>> '}'
;
object =
'{'
>> *root
>> '}'
;
objlist =
'{'
>> *object
>> '}'
;
assign =
(leaf | str)
>> '='
>> (leaf | str | taglist | objlist | object)
;
root =
+(assign | braces)
;
BOOST_SPIRIT_DEBUG_NODES((root)(braces)(str)(tolleaf)(leaf)(taglist)(objlist)(object)(assign));
}
它包含了很多令人惊讶的东西
注意我没有看过实际的语法。看起来这也可以改进,但我没有时间尝试理解预期的语法。但是,如您所见,它会解析您在问题中显示的代码段:
完整代码
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
template <typename It, typename Skipper = qi::iso8859_1::space_type>
struct Parser : qi::grammar<It, Skipper>
{
Parser() : Parser::base_type(root)
{
using namespace qi::iso8859_1;
braces =
'{' >> qi::eps >> '}'
;
str = qi::lexeme [
'"'
>> *~char_('"')
>> '"'
]
;
tolleaf = qi::lexeme [
+(~char_("\"{}= \t\r\n"))
]
;
leaf = qi::lexeme [
+(alnum | char_("-._:"))
]
;
taglist =
'{'
>> -str % tolleaf
>> '}'
;
object =
'{'
>> *root
>> '}'
;
objlist =
'{'
>> *object
>> '}'
;
assign =
(leaf | str)
>> '='
>> (leaf | str | taglist | objlist | object)
;
root =
+(assign | braces)
;
BOOST_SPIRIT_DEBUG_NODES((root)(braces)(str)(tolleaf)(leaf)(taglist)(objlist)(object)(assign));
}
private:
qi::rule<It, Skipper> root, braces, str, tolleaf, leaf, taglist, objlist, object, assign;
};
int main()
{
typedef boost::spirit::istream_iterator It;
std::cin.unsetf(std::ios::skipws);
It f(std::cin), l;
namespace iso8859_1 = qi::iso8859_1;
Parser<It, iso8859_1::space_type> p;
try
{
bool ok = qi::phrase_parse(f,l,p,iso8859_1::space);
if (ok) std::cout << "parse success\n";
else std::cerr << "parse failed: '" << std::string(f,l) << "'\n";
if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
return ok;
} catch(const qi::expectation_failure<It>& e)
{
std::string frag(e.first, e.last);
std::cerr << e.what() << "'" << frag << "'\n";
}
return false;
}
输出
这是 BOOST_SPIRIT_DEBUG 打印的内容:
<root>
<try>employees=\n{\n{\n p</try>
<assign>
<try>employees=\n{\n{\n p</try>
<leaf>
<try>employees=\n{\n{\n p</try>
<success>=\n{\n{\n province_p</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>\n{\n{\n province_po</try>
<fail/>
</leaf>
<str>
<try>{\n{\n province_pop</try>
<fail/>
</str>
<taglist>
<try>{\n{\n province_pop</try>
<str>
<try>\n{\n province_pop_</try>
<fail/>
</str>
<tolleaf>
<try>{\n province_pop_i</try>
<fail/>
</tolleaf>
<fail/>
</taglist>
<objlist>
<try>{\n{\n province_pop</try>
<object>
<try>\n{\n province_pop_</try>
<root>
<try>\n province_pop_id</try>
<assign>
<try>\n province_pop_id</try>
<leaf>
<try>\n province_pop_id</try>
<success>=\n {\n province</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>\n {\n province_</try>
<fail/>
</leaf>
<str>
<try>{\n province_id=1\n</try>
<fail/>
</str>
<taglist>
<try>{\n province_id=1\n</try>
<str>
<try>\n province_id=1\n </try>
<fail/>
</str>
<tolleaf>
<try>province_id=1\n in</try>
<success>=1\n index=0\n t</success>
<attributes>[]</attributes>
</tolleaf>
<str>
<try>=1\n index=0\n t</try>
<fail/>
</str>
<tolleaf>
<try>=1\n index=0\n t</try>
<fail/>
</tolleaf>
<fail/>
</taglist>
<objlist>
<try>{\n province_id=1\n</try>
<object>
<try>\n province_id=1\n </try>
<fail/>
</object>
<fail/>
</objlist>
<object>
<try>{\n province_id=1\n</try>
<root>
<try>\n province_id=1\n </try>
<assign>
<try>\n province_id=1\n </try>
<leaf>
<try>\n province_id=1\n </try>
<success>=1\n index=0\n t</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>1\n index=0\n ty</try>
<success>\n index=0\n typ</success>
<attributes>[]</attributes>
</leaf>
<success>\n index=0\n typ</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n index=0\n typ</try>
<leaf>
<try>\n index=0\n typ</try>
<success>=0\n type=9\n }\n</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>0\n type=9\n }\n </try>
<success>\n type=9\n }\n </success>
<attributes>[]</attributes>
</leaf>
<success>\n type=9\n }\n </success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n type=9\n }\n </try>
<leaf>
<try>\n type=9\n }\n </try>
<success>=9\n }\n count=1</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>9\n }\n count=17</try>
<success>\n }\n count=175</success>
<attributes>[]</attributes>
</leaf>
<success>\n }\n count=175</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n }\n count=175</try>
<leaf>
<try>\n }\n count=175</try>
<fail/>
</leaf>
<str>
<try>}\n count=1750\n}\n\n</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>\n }\n count=175</try>
<fail/>
</braces>
<success>\n }\n count=175</success>
<attributes>[]</attributes>
</root>
<root>
<try>\n }\n count=175</try>
<assign>
<try>\n }\n count=175</try>
<leaf>
<try>\n }\n count=175</try>
<fail/>
</leaf>
<str>
<try>}\n count=1750\n}\n\n</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>\n }\n count=175</try>
<fail/>
</braces>
<fail/>
</root>
<success>\n count=1750\n}\n\n{</success>
<attributes>[]</attributes>
</object>
<success>\n count=1750\n}\n\n{</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n count=1750\n}\n\n{</try>
<leaf>
<try>\n count=1750\n}\n\n{</try>
<success>=1750\n}\n\n{\n provi</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>1750\n}\n\n{\n provin</try>
<success>\n}\n\n{\n province_p</success>
<attributes>[]</attributes>
</leaf>
<success>\n}\n\n{\n province_p</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n}\n\n{\n province_p</try>
<leaf>
<try>\n}\n\n{\n province_p</try>
<fail/>
</leaf>
<str>
<try>}\n\n{\n province_po</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>\n}\n\n{\n province_p</try>
<fail/>
</braces>
<success>\n}\n\n{\n province_p</success>
<attributes>[]</attributes>
</root>
<root>
<try>\n}\n\n{\n province_p</try>
<assign>
<try>\n}\n\n{\n province_p</try>
<leaf>
<try>\n}\n\n{\n province_p</try>
<fail/>
</leaf>
<str>
<try>}\n\n{\n province_po</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>\n}\n\n{\n province_p</try>
<fail/>
</braces>
<fail/>
</root>
<success>\n\n{\n province_pop</success>
<attributes>[]</attributes>
</object>
<object>
<try>\n\n{\n province_pop</try>
<root>
<try>\n province_pop_id</try>
<assign>
<try>\n province_pop_id</try>
<leaf>
<try>\n province_pop_id</try>
<success>=\n {\n province</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>\n {\n province_</try>
<fail/>
</leaf>
<str>
<try>{\n province_id=1\n</try>
<fail/>
</str>
<taglist>
<try>{\n province_id=1\n</try>
<str>
<try>\n province_id=1\n </try>
<fail/>
</str>
<tolleaf>
<try>province_id=1\n in</try>
<success>=1\n index=1\n t</success>
<attributes>[]</attributes>
</tolleaf>
<str>
<try>=1\n index=1\n t</try>
<fail/>
</str>
<tolleaf>
<try>=1\n index=1\n t</try>
<fail/>
</tolleaf>
<fail/>
</taglist>
<objlist>
<try>{\n province_id=1\n</try>
<object>
<try>\n province_id=1\n </try>
<fail/>
</object>
<fail/>
</objlist>
<object>
<try>{\n province_id=1\n</try>
<root>
<try>\n province_id=1\n </try>
<assign>
<try>\n province_id=1\n </try>
<leaf>
<try>\n province_id=1\n </try>
<success>=1\n index=1\n t</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>1\n index=1\n ty</try>
<success>\n index=1\n typ</success>
<attributes>[]</attributes>
</leaf>
<success>\n index=1\n typ</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n index=1\n typ</try>
<leaf>
<try>\n index=1\n typ</try>
<success>=1\n type=9\n }\n</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>1\n type=9\n }\n </try>
<success>\n type=9\n }\n </success>
<attributes>[]</attributes>
</leaf>
<success>\n type=9\n }\n </success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n type=9\n }\n </try>
<leaf>
<try>\n type=9\n }\n </try>
<success>=9\n }\n count=3</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>9\n }\n count=34</try>
<success>\n }\n count=34\n</success>
<attributes>[]</attributes>
</leaf>
<success>\n }\n count=34\n</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n }\n count=34\n</try>
<leaf>
<try>\n }\n count=34\n</try>
<fail/>
</leaf>
<str>
<try>}\n count=34\n}\n}\n</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>\n }\n count=34\n</try>
<fail/>
</braces>
<success>\n }\n count=34\n</success>
<attributes>[]</attributes>
</root>
<root>
<try>\n }\n count=34\n</try>
<assign>
<try>\n }\n count=34\n</try>
<leaf>
<try>\n }\n count=34\n</try>
<fail/>
</leaf>
<str>
<try>}\n count=34\n}\n}\n</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>\n }\n count=34\n</try>
<fail/>
</braces>
<fail/>
</root>
<success>\n count=34\n}\n}\n</success>
<attributes>[]</attributes>
</object>
<success>\n count=34\n}\n}\n</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n count=34\n}\n}\n</try>
<leaf>
<try>\n count=34\n}\n}\n</try>
<success>=34\n}\n}\n</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>34\n}\n}\n</try>
<success>\n}\n}\n</success>
<attributes>[]</attributes>
</leaf>
<success>\n}\n}\n</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n}\n}\n</try>
<leaf>
<try>\n}\n}\n</try>
<fail/>
</leaf>
<str>
<try>}\n}\n</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>\n}\n}\n</try>
<fail/>
</braces>
<success>\n}\n}\n</success>
<attributes>[]</attributes>
</root>
<root>
<try>\n}\n}\n</try>
<assign>
<try>\n}\n}\n</try>
<leaf>
<try>\n}\n}\n</try>
<fail/>
</leaf>
<str>
<try>}\n}\n</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>\n}\n}\n</try>
<fail/>
</braces>
<fail/>
</root>
<success>\n}\n</success>
<attributes>[]</attributes>
</object>
<object>
<try>\n}\n</try>
<fail/>
</object>
<success>\n</success>
<attributes>[]</attributes>
</objlist>
<success>\n</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>\n</try>
<leaf>
<try>\n</try>
<fail/>
</leaf>
<str>
<try></try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>\n</try>
<fail/>
</braces>
<success>\n</success>
<attributes>[]</attributes>
</root>
parse success