Boost::Spirit 简单语法示例

6

我正在学习 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
-------------------------

我也试图编写一个类似的解析器,自动将数据类型转换为我的结构体类型。我相信我在定义上述输入字符串的正确语法方面可能存在基本错误,因此非常感谢任何帮助!谢谢!
1个回答

11

+(char_) 消耗一个或多个字符,因此它也会消耗逗号,并且永远不会移动到 >> ','。 它是贪心的。

您应该使用差集运算符-编写+(char_ - ',')

//...
>>  int_ >> ','     
>>  +(char_ - ',') >> ','     
>>  +(char_ - ',') >> ','     
>>  double_
//...

解析器+(char_ - ',')会消耗每个字符,直到遇到逗号。然后它将移动到>> ',',消耗它,然后继续使用下一行+(char_ - ','),直到逗号等等。

关于这个运算符的更多信息,您可以在这里找到:http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/operator/difference.html

或者

如果您想解析只包含字母的名称,您还可以考虑编写只接受字母的解析器:

//...
>>  int_ >> ','     
>>  +(char_("a-zA-Z")) >> ','     
>>  +(char_("a-zA-Z")) >> ','     
>>  double_
//...

2
...那将只包含ASCII字母,然后... José并不觉得好笑。;-) - DevSolar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接