c++ - X3 : Is this parser, *(char - eol),消耗所有行?

标签 c++ parsing boost-spirit boost-spirit-x3

我的应用基于此示例并获得了完全相同的结果。由于某种原因,输入字符串的内容全部被解析为融合结构“comments”,而没有任何内容被解析为融合结构“numbers”。所以不确定我哪里出错了。

namespace client { 
    namespace ast {

        struct number {
            int num1;
            int num2;  
        };

        struct comment {
            std::string text;
            bool dummy;
        };

        struct input {
            std::vector<comment> comments;  
            std::vector<number> numbers;
        };
    } 
}

BOOST_FUSION_ADAPT_STRUCT(client::ast::comment, text, dummy)
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, num1, num2)
BOOST_FUSION_ADAPT_STRUCT(client::ast::input, comments, numbers)

namespace client {      
    namespace parser {

        namespace x3 = boost::spirit::x3;
        using namespace x3;

        x3::attr_gen dummy;

        typedef std::string::const_iterator It;

        using namespace x3;

        auto const comment = *(char_ - eol) >> dummy(false);
        auto const number = int_ >> int_;

        auto lines = [](auto p) { return *(p >> eol); };

        auto const input = 
            lines(comment) >> 
            lines(number);
   }
}

int main()
{
    namespace x3 = boost::spirit::x3;

    std::string const iss("any char string here\n1 2\n");

    auto iter = iss.begin(), eof = iss.end();

    client::ast::input types;

    bool ok = parse(iter, eof, client::parser::input, types);

    if (iter != eof) {
        std::cout << "Remaining unparsed: '" << std::string(iter, eof) << "'\n";
    }
    std::cout << "Parsed: " << (100.0 * std::distance(iss.begin(), iter) / iss.size()) << "%\n";
    std::cout << "ok = " << ok << std::endl;

    // This range loop prints all contents if input.
    for (auto& item : types.comments)    { std::cout << "comment: " << boost::fusion::as_deque(item) << "\n"; }

    // This loop prints nothing.
    for (auto& item : types.numbers)    { std::cout << "number: " << boost::fusion::as_deque(item) << "\n"; }
}  

我的大型应用程序对一个大的输入文件和多个 AST 执行相同的操作,但似乎我的所有示例都被注释解析器使用了。

这是完整的运行示例。

http://coliru.stacked-crooked.com/a/f983b26d673305a0

想法?

最佳答案

你从我这里的回答中得到了语法思想:X3, how to populate a more complex AST?

它起作用了,因为行格式没有歧义。事实上,您需要特别注意“变体”方法,我在本项目符号中指出:

  • departments need to be ordered before teams, or you get "team" matched instead of departments

您的语法中也存在同样的歧义。 *(char_ - eol) 匹配 "1 2" 就好了,所以很明显它是作为注释添加的。您将不得不消除语法歧义或以某种方式强制切换到“立即解析数字行”模式。

如果您完全不关心数字行之前的内容,只需使用 x3::seek [ lines(number) ]

关于c++ - X3 : Is this parser, *(char - eol),消耗所有行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45625260/

相关文章:

c++ - 从 flv 视频(或任何其他视频)中提取音频的算法。怎么办?

c++ - boost 正则表达式不匹配 "\\s"到空格

c++ - 如何将 const void* 转换为 unsigned int?

c - 如何使用 yacc 解析 if/else 语句

java - 我如何解析 Ping 请求(字符串)的 Ping 时间(整数)?

c++ - boost::spirit::qi::lexeme 没有捕获完整的 token

c# - AnyCPU C# DLL in 64bit process is unable to refer 64 bit C++ DLL(Giving error : Could not load file or assembly)

python - 解析问题

c++ - 将 Spirit int boost 为字符串规则

c++ - 对 boost Spirit/phoenix/C++11 交互感到困惑