我目前正在使用 boost spirit X3 开发 DSL。我正在使用这个示例来实现表达式和运算符层次结构,并避免表达式解析器中的左递归。我还想.
为成员访问[]
实现 -operator,为索引访问(例如数组)实现 -operator,并且由于 DSL 将是一种函数式语言,我想实现函数调用,即()
-operator,也作为运算符,因为每个表达式都可以返回一个函数,所以()
- 运算符应该适用于任何其他表达式。我想解析的结构看起来像这样:
enum class operator_t {
_eq_, // ==
_ne_, // !=
...
_idx_, // []
_apply_, // ()
_access_ // .
};
typedef x3::variant<
nil,
std::string,
NumberLiteral,
x3::forward_ast<Unary>,
x3::forward_ast<Expression>,
> Operand;
struct Unary {
operator_t operator_;
Operand operand_;
};
struct Operation {
operator_t operator_;
Operand operand_;
};
struct Expression {
Operand first_;
std::vector<Operation> rest_;
};
我能够为[]-operator
和.-operator
使用以下规则创建解析器(查看 EDIT 中的 mcve):
typedef x3::rule<struct primary_expr_class, ast::Operand> primary_expr_type;
typedef x3::rule<struct index_access_expr_class, ast::Expression> index_access_expr_type;
typedef x3::rule<struct data_access_expr_class, ast::Expression> data_access_expr_type;
auto const index_access_expr_def =
primary_expr >> *(helper::idxaccess_op > expression > "]");
auto const data_access_expr_def =
index_access_expr >> *(helper::access_op > index_access_expr);
现在我正在尝试对函数调用做同样的事情,但我无法做到这一点,也index_access_expr
没有data_access_expr
优先级,我怎样才能让这两个规则具有优先级以及如何将函数调用实现为运算符表达式,也可以使用相同的优先级?
编辑:这是一个关于我如何使用index_access_expr
and的 mcve data_access_expr
。在此示例中,我想添加()-operator
, 并且希望三个运算符具有相同的优先级。
编辑二:这是另一个 mcve,关于我如何厌倦将函数调用实现为表达式,但就像您在示例中看到的那样,它根本不起作用。我的方法是添加std::vector<Expression>
到Operand
变体中,然后尝试像这样添加函数调用解析器:
auto const func_call_expr_def =
data_access_expr >> *(func_call_op > (expression % ",") > ")");
这根本不起作用,看看我在 中的测试,main
操作员层次结构问题仍然存在。