Boost::Spirit 简单语法示例
我正在阅读 Boost Spirit(和 Boost Fusion)教程(版本 1.48.0)。我一直在玩玩具员工的例子。源链接在这里:
http:// /www.boost.org/doc/libs/1_48_0/libs/spirit/example/qi/employee.cpp
这是示例的语法:
employee_parser() : employee_parser::base_type(start)
{
using qi::int_;
using qi::lit;
using qi::double_;
using qi::lexeme;
using ascii::char_;
quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %=
lit("employee")
>> '{'
>> int_ >> ','
>> quoted_string >> ','
>> quoted_string >> ','
>> double_
>> '}'
;
}
qi::rule<Iterator, std::string(), ascii::space_type> quoted_string;
qi::rule<Iterator, employee(), ascii::space_type> start;
我的修改删除了引号的处理并只解析分隔符之间的任何字符并将其分配给解析器映射到的结构。
//quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %=
lit("employee")
>> '{'
>> int_ >> ','
>> +(char_) >> ','
>> +(char_) >> ','
>> double_
>> '}'
;
我的假设是 char_ 包含所有字符,直到到达逗号。但是,使用以下字符串进行编译和运行会返回解析失败。
./employee
employee{10,my,name,20.0}
-------------------------
Parsing failed
-------------------------
我还尝试编写一个类似的解析器来自动转换为我的结构类型的适当类型。我确信在为上面的输入字符串定义正确的语法方面我错过了一些根本性的错误,因此非常感谢任何帮助!
谢谢!
I'm going through the Boost Spirit (and Boost Fusion) tutorials (version 1.48.0). I've been playing with the toy employee example. The link to the source is here:
http://www.boost.org/doc/libs/1_48_0/libs/spirit/example/qi/employee.cpp
Here is the example's grammar:
employee_parser() : employee_parser::base_type(start)
{
using qi::int_;
using qi::lit;
using qi::double_;
using qi::lexeme;
using ascii::char_;
quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %=
lit("employee")
>> '{'
>> int_ >> ','
>> quoted_string >> ','
>> quoted_string >> ','
>> double_
>> '}'
;
}
qi::rule<Iterator, std::string(), ascii::space_type> quoted_string;
qi::rule<Iterator, employee(), ascii::space_type> start;
And my modifications remove the treatment of the quotes and just parses any character between the delimiter and assigns that to the struct the parser is mapped to.
//quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'];
start %=
lit("employee")
>> '{'
>> int_ >> ','
>> +(char_) >> ','
>> +(char_) >> ','
>> double_
>> '}'
;
My assumption is that char_ includes all characters until a comma is reached. However, compiling and running with the following string returns a failure to parse.
./employee
employee{10,my,name,20.0}
-------------------------
Parsing failed
-------------------------
I'm also attempting to write a similar parser to automatically cast to the appropriate types of my struct type. I'm sure I'm missing something fundamentally wrong as far as defining the correct grammar for an input string like above, so any help is greatly appreciated!
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
+(char_)
消耗一个或多个字符,因此它也会消耗逗号,并且永远不会移动到>>> ','
。真是贪心啊。您应该使用差分运算符
-
编写+(char_ - ',')
:解析器
+(char_ - ',')
将消耗每个char 直到到达逗号。之后它将移至>>> ','
,使用它,然后继续下一行+(char_ - ',')
直到逗号等。有关此运算符的更多信息,您可以在这里找到: http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/difference.html
OR
如果您想解析仅包含字母的名称,您还可以考虑编写仅接受字母的解析器:
+(char_)
consumes one or more char, so it will also consume commas and will never move to>> ','
. It's greedy.You should write
+(char_ - ',')
, using difference operator-
:Parser
+(char_ - ',')
would consume every char until comma is reached. After that it will move to>> ','
, consume it and then continue with next line+(char_ - ',')
until comma and so on.More about this operator you can find here: http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/difference.html
OR
If you want to parse names which contains only letters, you can also consider writing parser which accept only letters: