问题描述
我有以下代码要修改,但是我对Boost-spirit完全陌生.我知道RE是精打细算的,但不知道该怎么做.
I've got the following piece of code I want to modify fix, but I am totally new to boost-spirit.I know RE's but not how to exactly do them in spirit.
这是解析器.
Parser() : Parser::base_type(root)
{
braces = lit('{') >> *(iso8859_1::space) >> lit('}');
str = lexeme[lit('"') >> raw[*(~iso8859_1::char_('"'))] >> lit('"')];
tolleaf = raw[+(~iso8859_1::char_("\"{}= \t\r\n"))];
leaf = raw[+(iso8859_1::alnum | iso8859_1::char_("-._:"))];
taglist = lit('{') >> omit[*(iso8859_1::space)] >> lexeme[( ( str | skip[tolleaf] ) % *(iso8859_1::space) )] >> omit[*(iso8859_1::space)] >> lit('}');
object = raw[lit('{') >> *(root) >> *(iso8859_1::space) >> lit('}')];
objlist = raw[lit('{') >> *( *(iso8859_1::space) >> object[&pushObj] ) >> *(iso8859_1::space) >> lit('}')];
assign = raw[(*(iso8859_1::space) >> ( leaf[&setLHS] | str[&setLHS]) >> *(iso8859_1::space) >> lit('=')
>> *(iso8859_1::space)
>> ( leaf[&setRHSleaf] | str[&setRHSleaf] | taglist[&setRHStaglist] | objlist[&setRHSobjlist] | object[&setRHSobject] )
>> *(iso8859_1::space))];
root = +(assign | braces);
str.name("str");
leaf.name("leaf");
taglist.name("taglist");
object.name("object");
objlist.name("objlist");
assign.name("assign");
braces.name("braces");
root.name("root");
}
这是我尝试解析的格式:
And this is the format I'm trying to parse:
employees=
{
{
province_pop_id=
{
province_id=1
index=0
type=9
}
count=1750
}
{
province_pop_id=
{
province_id=1
index=1
type=9
}
count=34
}
}
问题是双重{{.如果我只有
The problem is the double {{. If I just have a
blahblah=
{
value=
{
2
}
}
它工作正常.
我知道这个
objlist = raw[lit('{') >> *( *(iso8859_1::space) >> object[&pushObj] ) >> *(iso8859_1::space) >> lit('}')];
需要更改,但是我不确定如何更改.
has to be changed, but I'm not sure how.
推荐答案
所以,为了向您展示我的意思,我已经清理了语法.
So, just to show you what I meant, I've cleaned up the grammar.
查看 在Coliru上直播
See it Live on 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));
}
它包含了很多令人惊讶的东西
It contained quite a few surprising things
- 冗余空白检查,而船长已经执行了此操作
-
skip[]
和lexeme[]
的存在清楚地表明该规则已使用Skipper声明(如果未声明,则所有规则都隐式地为"lexemes") -
格式化!
- Redundant whitespace checking, while a skipper already does this
- The presence of
skip[]
andlexeme[]
clearly suggests that the rules have been declared using a Skipper (if not, all rules are implicitely "lexemes") Formatting!
- 当然,使用名称空间会有所帮助.
- qi :: lit仅在存在歧义或需要重载解决方案时才需要
- 许多多余()
- 单行中的所有内容都会产生难以理解的规则.
建议的布局还使通过注释某些行来选择性地调试编译问题变得更加容易
BOOST_SPIRIT_DEBUG *宏用于调试.请参阅完整工作示例下方的输出
BOOST_SPIRIT_DEBUG* macros for debugging. See the output below the fully working sample
注意:我不查看了实际的语法.看起来这也可以改进,但是我没有时间尝试去理解预期的语法.但是,您可以看到它解析了您在问题中显示的代码段:
Note I've NOT looked at the actual grammar. It looks like this could be improved, too, but I don't have the time to try and understand the intended grammar. However, as you can see it parses the snippet you showed in the question:
#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打印的内容:
Output
This is what BOOST_SPIRIT_DEBUG prints:
<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
这篇关于Boost Spirit像语法一样解析XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!