我目前正在使用boost spirit X3开发DSL。我正在使用this example来实现表达式和运算符层次结构,并避免在表达式解析器中使用左递归。
我还想为成员访问实现.
- 运算符,为数组实现索引访问的[]
- 运算符,并且由于DSL将是一种函数式语言,我想实现函数调用()
- 运算符,也作为运算符,因为每个表达式都可以返回一个函数,()
- 运算符应该可以应用于任何其他表达式。
顽固,我想解析看起来像这样:
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
创建解析器(查看编辑中的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
也没有优先权,如何使这两个规则具有优先权如何将函数调用实现为运算符表达式,同样具有相同的优先级?
编辑:here是我如何使用index_access_expr
和data_access_expr
完成的。在这个例子中,我想添加()-operator
,我希望这三个运算符具有相同的优先级。
编辑II:here是另一个mcve,关于我如何将函数调用实现为表达式,但就像你在示例中看到它根本不起作用。我的方法是将std::vector<Expression>
添加到Operand
变体,然后尝试添加函数调用解析器,如下所示:
auto const func_call_expr_def =
data_access_expr >> *(func_call_op > (expression % ",") > ")");
这个doest工作,看看main
中的我的测试,还有操作符层次问题仍然存在。