c++ - 使用 boost::spirit 将字符串解析为列表

标签 c++ boost-spirit

我遇到了一种情况,我正在将输入解析为 vector boost::Spirit 的映射。

它工作得很好,但我遇到了一种情况,我需要在内部为特定的用户输入情况提供固定字符串,以便解析内部字符串来代替用户输入。

这是语法示例:

input_pair = 
    key( std::string("__input")) >> valid_input % ','
    ;

地点:

key = 
    qi::attr( _r1 )
    ;

“valid_input”是一个简单的规则,用于测试特定字符串/字符模式等。

此语法将输入与预定义的内部键配对,并将其作为 vector 存储在映射中。如果输入包含指定的分隔符,则输入将被适本地解析为接收 vector 的单独元素。

但是,我遇到的问题是为“valid_input”提供预定义的字符串。

我的第一个倾向是做我用 map 键所做的事情:

input_pair = 
    key( std::string("__input")) >> key ( std::string("A, B, C")) % ','
    ;

但是,当然,整个字符串将作为 vector 的第一个元素插入。也就是说,“A、B、C”中的逗号分隔符没有像我希望的那样被识别。

因此我的问题:

给定一个 boost::Spirit 解析器,其语法将输入解析为 vector 映射,有没有办法将解析器本身定义的固定字符串解析为 vector ?

最佳答案

给定输入“1 2 3 4”,遵循以下规则:

typedef std::vector<std::string> attr_t;

rule = *qi::lexeme[+qi::char_];

将(显然)解析 std::vector<string> { "1", "2", "3", "4" } 的属性值.

现在将规则更改为

rule %= qi::attr(attr_t { "aap", "noot", "mies" }) >>  *qi::lexeme[+qi::char_];

您将收到std::vector<string> { "aap", "noot", "mies", "1", "2", "3", "4" } 。使用qi::omit如果您只想要硬编码 vector 。

这是工作中的 C++11 统一初始化语法,因此如果您不能使用它,则必须以其他方式提供 vector :

static const std::string hardcoded[] = { "aap", "noot", "mies" };
static const attr_t const_data(hardcoded, hardcoded+3);
rule = qi::attr(const_data) >>  *qi::lexeme[+qi::char_];

这也稍微提高了效率(以更冗长的代码为代价)。


这里是完整的工作示例,其中包含一些变体(假设 C++11 编译器用于测试主程序):

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>

namespace qi    = boost::spirit::qi;
namespace karma = boost::spirit::karma;

typedef std::vector<std::string> attr_t;

int main()
{
    const std::string input = "1 2 3 4";
    auto f(std::begin(input)), l(std::end(input));

    qi::rule<decltype(f), attr_t(), qi::space_type> rule;

    // #1: no hardcoded values
    rule = *qi::lexeme[+qi::char_];

    // #2: hardcoded inline temp vector
    rule = qi::attr(attr_t { "aap", "noot", "mies" }) >>  *qi::lexeme[+qi::char_];

    // #3: hardcoded static vector, C++03 style
    static const std::string hardcoded[] = { "aap", "noot", "mies" };
    static const attr_t const_data(hardcoded, hardcoded+3);
    rule = qi::attr(const_data) >>  *qi::lexeme[+qi::char_];

    try
    {
        attr_t data;
        bool ok = qi::phrase_parse(f, l, rule, qi::space, data);
        if (ok)   
        {
            std::cout << "parse success\n";
            std::cout << "data: " << karma::format_delimited(karma::auto_, ' ', data) << "\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? 0 : 255;
    } catch(const qi::expectation_failure<decltype(f)>& e)
    {
        std::string frag(e.first, e.last);
        std::cerr << e.what() << "'" << frag << "'\n";
        return 255;
    }

}

打印

parse success
data: 1 2 3 4 

关于c++ - 使用 boost::spirit 将字符串解析为列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9750178/

相关文章:

c++ - 为什么cc可以编译c++程序?

c++ - 如何理解这个答案中 "q = i - 4; "的代码?

c++ - 试图在类中使用 boost::spirit::qi 解析器的段错误

c++ - 字符串到 bool 表达式不起作用 C++

c# - 有没有一种方法可以对使用数据库系统的应用程序进行编程,而不需要在客户端计算机上安装数据库服务器

python - 集成 Python 和 C++ MacOS PyModuleDef_HEAD_INIT 未声明

C++ 未定义的命名空间

c++ - boost::spirit 和语法

c++ - Spirit X3,ascii::cntrl 为什么与std::iscntrl 不一致?

c++ - boost::spirit stream_parser 消耗太大?