c++ - spirit X3怎么加条件期望值

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

我目前正在为 X3 中的语法添加期望点。 现在我遇到了一条规则,看起来像这样。

auto const id_string = +x3::char("A-Za-z0-9_);

auto const nested_identifier_def =
        x3::lexeme[
                *(id_string >> "::")
                >> *(id_string >> ".")
                >> id_string
        ];

我想知道如何向这条规则添加条件期望点。 就像“如果有一个“::”那么必须跟随一个id_string”或者“当有一个.时必须跟随一个id_string >" 等等。 我怎样才能为这样的规则实现这样的行为?

最佳答案

我会完全按照您的意图编写它:

auto const identifier 
    = lexeme [+char_("A-Za-z0-9_")];

auto const qualified_id 
    = identifier >> *("::" > identifier);

auto const simple_expression // only member expressions supported now
    = qualified_id >> *('.' > identifier);

具有相应的 AST:

namespace AST {
    using identifier = std::string;

    struct qualified_id : std::vector<identifier> { using std::vector<identifier>::vector; };

    struct simple_expression {
        qualified_id lhs;
        std::vector<identifier> rhs;
    };
}

现场演示

Live On Coliru

#include <iostream>
#include <string>
#include <vector>

namespace AST {
    using identifier = std::string;

    struct qualified_id : std::vector<identifier> { using std::vector<identifier>::vector; };

    struct simple_expression {
        qualified_id lhs;
        std::vector<identifier> rhs;
    };
}

#include <boost/fusion/adapted.hpp>
BOOST_FUSION_ADAPT_STRUCT(AST::simple_expression, lhs, rhs)

#include <boost/spirit/home/x3.hpp>

namespace Parser {
    using namespace boost::spirit::x3;

    auto const identifier 
        = rule<struct identifier_, AST::identifier> {}
        = lexeme [+char_("A-Za-z0-9_")];

    auto const qualified_id 
        = rule<struct qualified_id_, AST::qualified_id> {}
        = identifier >> *("::" > identifier);

    auto const simple_expression // only member expressions supported now
        = rule<struct simple_expression_, AST::simple_expression> {}
        = qualified_id >> *('.' > identifier);
}

int main() {
    using It = std::string::const_iterator;

    for (std::string const input : { "foo", "foo::bar", "foo.member", "foo::bar.member.subobject" }) {
        It f = input.begin(), l = input.end();
        AST::simple_expression data;

        bool ok = phrase_parse(f, l, Parser::simple_expression, boost::spirit::x3::space, data);

        if (ok) {
            std::cout << "Parse success: ";
            for (auto& el : data.lhs) std::cout << "::" << el;
            for (auto& el : data.rhs) std::cout << "." << el;
            std::cout << "\n";
        }
        else {
            std::cout << "Parse failure ('" << input << "')\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed input: '" << std::string(f, l) << "'\n";
    }
}

打印

Parse success: ::foo
Parse success: ::foo::bar
Parse success: ::foo.member
Parse success: ::foo::bar.member.subobject

关于c++ - spirit X3怎么加条件期望值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39053814/

相关文章:

c++ - 基于伪代码编写的高斯消元中的std::bad_alloc

c++ - 为什么g++需要模板类及其友元函数的定义?

c++ - 无法专门化函数模板编译器错误

c++ - WM_NEXTDLGCTL 可以与非对话框窗口一起使用吗?

java - 无法使用 Jackson 解析 JSON(映射不起作用)

python - 使用带有 1 字节变量的 Python struct.unpack

c++ - header 中的模板规范问题

javascript - 如何将简单语法转换为可在 PEG.js 中使用的语法(预期为 "a"但找到了 "a")

c++ - 如何初始化 Matrix<T,Rows,Cols> 类型的 constexpr 矩阵?

c++ - shared_ptr 未在线程中释放自定义 malloc