Boost Spirit解析类似XML的语法
Boost Spirit parsing XML like grammar
我有下面一段代码想修改修复程序,但我对提升精神是全新的。我知道RE,但不知道如何在精神上做到这一点。
这就是解析器。
Parser() : Parser::base_type(root)
{
braces = lit('{') >> *(iso8859_1::space) >> lit('}');
str = lexeme[lit('"') >> raw[*(~iso8859_1::char_('"'))] >> lit('"')];
tolleaf = raw[+(~iso8859_1::char_(""{}= trn"))];
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");
}
这就是我试图解析的格式:
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
}
}
问题是双{{。如果我只有一个
blahblah=
{
value=
{
2
}
}
它运行良好。
我知道这个
objlist = raw[lit('{') >> *( *(iso8859_1::space) >> object[&pushObj] ) >> *(iso8859_1::space) >> lit('}')];
必须改变,但我不确定如何改变。
所以,为了向您展示我的意思,我已经清理了语法。
查看Coliru直播
Parser() : Parser::base_type(root)
{
using namespace qi::iso8859_1;
braces =
'{' >> qi::eps >> '}'
;
str = qi::lexeme [
'"'
>> *~char_('"')
>> '"'
]
;
tolleaf = qi::lexeme [
+(~char_(""{}= trn"))
]
;
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));
}
它包含了相当多令人惊讶的东西
- 冗余的空白检查,而队长已经这样做了
skip[]
和lexeme[]
的存在清楚地表明规则是使用Skipper声明的(如果不是,则所有规则都是隐含的"lexemes")格式化!
- 当然,使用名称空间会有所帮助
- qi::只有当存在歧义或过载解决方案需要时,才需要点亮
- 许多冗余()
- 一条线上的每件事都会产生令人费解的规则
建议的布局还使选择性地调试编译问题变得更容易,只需注释一些行
用于调试的BOOstrongPIRIT_DEBUG*宏。见完整工作样品下方的输出
注意我没有查看实际语法。这看起来也可以改进,但我没有时间尝试和理解预期的语法。然而,正如您所看到的,它解析了您在问题中显示的片段:
完整代码
#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_(""{}= trn"))
]
;
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 successn";
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;
}
输出
这是BOOstrongPIRIT_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=1n</try>
<fail/>
</str>
<taglist>
<try>{n province_id=1n</try>
<str>
<try>n province_id=1n </try>
<fail/>
</str>
<tolleaf>
<try>province_id=1n in</try>
<success>=1n index=0n t</success>
<attributes>[]</attributes>
</tolleaf>
<str>
<try>=1n index=0n t</try>
<fail/>
</str>
<tolleaf>
<try>=1n index=0n t</try>
<fail/>
</tolleaf>
<fail/>
</taglist>
<objlist>
<try>{n province_id=1n</try>
<object>
<try>n province_id=1n </try>
<fail/>
</object>
<fail/>
</objlist>
<object>
<try>{n province_id=1n</try>
<root>
<try>n province_id=1n </try>
<assign>
<try>n province_id=1n </try>
<leaf>
<try>n province_id=1n </try>
<success>=1n index=0n t</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>1n index=0n ty</try>
<success>n index=0n typ</success>
<attributes>[]</attributes>
</leaf>
<success>n index=0n typ</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>n index=0n typ</try>
<leaf>
<try>n index=0n typ</try>
<success>=0n type=9n }n</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>0n type=9n }n </try>
<success>n type=9n }n </success>
<attributes>[]</attributes>
</leaf>
<success>n type=9n }n </success>
<attributes>[]</attributes>
</assign>
<assign>
<try>n type=9n }n </try>
<leaf>
<try>n type=9n }n </try>
<success>=9n }n count=1</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>9n }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=1750n}nn</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=1750n}nn</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>n }n count=175</try>
<fail/>
</braces>
<fail/>
</root>
<success>n count=1750n}nn{</success>
<attributes>[]</attributes>
</object>
<success>n count=1750n}nn{</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>n count=1750n}nn{</try>
<leaf>
<try>n count=1750n}nn{</try>
<success>=1750n}nn{n provi</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>1750n}nn{n provin</try>
<success>n}nn{n province_p</success>
<attributes>[]</attributes>
</leaf>
<success>n}nn{n province_p</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>n}nn{n province_p</try>
<leaf>
<try>n}nn{n province_p</try>
<fail/>
</leaf>
<str>
<try>}nn{n province_po</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>n}nn{n province_p</try>
<fail/>
</braces>
<success>n}nn{n province_p</success>
<attributes>[]</attributes>
</root>
<root>
<try>n}nn{n province_p</try>
<assign>
<try>n}nn{n province_p</try>
<leaf>
<try>n}nn{n province_p</try>
<fail/>
</leaf>
<str>
<try>}nn{n province_po</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>n}nn{n province_p</try>
<fail/>
</braces>
<fail/>
</root>
<success>nn{n province_pop</success>
<attributes>[]</attributes>
</object>
<object>
<try>nn{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=1n</try>
<fail/>
</str>
<taglist>
<try>{n province_id=1n</try>
<str>
<try>n province_id=1n </try>
<fail/>
</str>
<tolleaf>
<try>province_id=1n in</try>
<success>=1n index=1n t</success>
<attributes>[]</attributes>
</tolleaf>
<str>
<try>=1n index=1n t</try>
<fail/>
</str>
<tolleaf>
<try>=1n index=1n t</try>
<fail/>
</tolleaf>
<fail/>
</taglist>
<objlist>
<try>{n province_id=1n</try>
<object>
<try>n province_id=1n </try>
<fail/>
</object>
<fail/>
</objlist>
<object>
<try>{n province_id=1n</try>
<root>
<try>n province_id=1n </try>
<assign>
<try>n province_id=1n </try>
<leaf>
<try>n province_id=1n </try>
<success>=1n index=1n t</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>1n index=1n ty</try>
<success>n index=1n typ</success>
<attributes>[]</attributes>
</leaf>
<success>n index=1n typ</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>n index=1n typ</try>
<leaf>
<try>n index=1n typ</try>
<success>=1n type=9n }n</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>1n type=9n }n </try>
<success>n type=9n }n </success>
<attributes>[]</attributes>
</leaf>
<success>n type=9n }n </success>
<attributes>[]</attributes>
</assign>
<assign>
<try>n type=9n }n </try>
<leaf>
<try>n type=9n }n </try>
<success>=9n }n count=3</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>9n }n count=34</try>
<success>n }n count=34n</success>
<attributes>[]</attributes>
</leaf>
<success>n }n count=34n</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>n }n count=34n</try>
<leaf>
<try>n }n count=34n</try>
<fail/>
</leaf>
<str>
<try>}n count=34n}n}n</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>n }n count=34n</try>
<fail/>
</braces>
<success>n }n count=34n</success>
<attributes>[]</attributes>
</root>
<root>
<try>n }n count=34n</try>
<assign>
<try>n }n count=34n</try>
<leaf>
<try>n }n count=34n</try>
<fail/>
</leaf>
<str>
<try>}n count=34n}n}n</try>
<fail/>
</str>
<fail/>
</assign>
<braces>
<try>n }n count=34n</try>
<fail/>
</braces>
<fail/>
</root>
<success>n count=34n}n}n</success>
<attributes>[]</attributes>
</object>
<success>n count=34n}n}n</success>
<attributes>[]</attributes>
</assign>
<assign>
<try>n count=34n}n}n</try>
<leaf>
<try>n count=34n}n}n</try>
<success>=34n}n}n</success>
<attributes>[]</attributes>
</leaf>
<leaf>
<try>34n}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
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 助记符和指向成员语法的指针
- 有人能分解一下这个c++模板的语法吗
- C++避免重复声明的语法是什么
- Cppcheck生成xml转储文件
- QMetaObject invokeMethod的基于函数指针的语法
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 如何在pugixml中获取节点的内部XML
- 如何使用tinyxml2从XML加载父实体和子实体
- boost xml parsingl将xml的路径作为变量发送
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 使用 Tinyxml 在 xml 中添加一个子子项
- 单独定义模板化嵌套类方法的正确语法
- 增强基于 XML class_id的反序列化
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 将xml字符串嵌套到xml元素中的语法
- Boost Spirit解析类似XML的语法
- 如何获得xml属性与此语法使用Qt DOM