I am currently developing a DSL using boost spirit X3. I am using this example, to implementing expressions and the operator hierachy, and avoiding left recursion in the expression parsers.
I also would like to implement a .
-operator for member accesses, the []
-operator for index accesses for example for arrays, and since the DSL will be a functional language, I would like to implement function calls, the ()
-operator, also as an operator, since every expression could return a function, the ()
-operator should be applyable on any other expression.
The sturcts, I want to parse in look like this:
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_;
};
I was able to create parsers for the []-operator
and the .-operator
, using the following rules(have a look at the mcve in the EDIT):
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);
now I am trying to do the same for function calls, but I wasnt able to do this, also index_access_expr
and data_access_expr
doesnt have the precedence, how can I make these two rules haveing the precedence and how can I implement function calls as operator expressions, also with the same precedence?
EDIT: here is a mcve on how I did it with index_access_expr
and data_access_expr
. To this example I would like to add the ()-operator
, and I would like to have the three operators the same precedence.
EDIT II: here is another mcve, on how I tired to implement the function calls as expressions, but like you can see in the example it doesnt work at all. My approach was to add std::vector<Expression>
to the Operand
variant and then tried to add the function call parser like this:
auto const func_call_expr_def =
data_access_expr >> *(func_call_op > (expression % ",") > ")");
This doest work at all, have a look at my tests in the main
, also to operator hierachy problem still exists.