I am currently stuck with a rule I am trying to parse using boost spirit x3. Here is te EBNF(using the % operator from spirit for lists) for what I am trying to parse:
type ::= class_type | lambda_type
lambda_type ::= more_arg_lambda | one_arg_lambda
more_arg_lambda ::= "(", type%",", ")", "=>", type
one_arg_lambda ::= type, "=>", type <- here is the left recursion
class_type ::= identifier%"::", ["<", type%",", ">"]
usng boost spirit x3, I am trying to parse into the following struct/variant:
typedef x3::variant<
nil,
x3::forward_ast<LambdaType>,
x3::forward_ast<ClassType>
> Type;
struct LambdaType {
std::vector<Type> parameters_;
Type return_type_;
};
struct ClassType{
std::vector<std::string> name_;
std::vector<Type> template_args_;
};
I have a live example of what I am currently trying here, which is not working, I also tried to change the order of the variant parser, wich doesnt help, I get endless recusion, or not the behaviour I would expect(or wish). Can anybody help me debugging this parser? I think I have some type of left-recursion in the parser, is there a chance to avoid this or is there no chance to rewrite the grammar? Is this gramar even parsable with boost spirit x3?
EDIT:
I managed to eleminate the left recursion in this grammar. Now te grammar is the following:
type ::= class_type | lambda_type
lambda_type ::= more_arg_lambda | one_arg_lambda
more_arg_lambda ::= "(", type%",", ")", "=>", type
one_arg_lambda ::= class_type, "=>" type, A
| "(", type%",", ")", "=>", type, "=>", type, A
class_type ::= identifier%"::", ["<", type%",", ">"]
A::= "=>", type, A | eps
but now there is the next problem, how can I make boost spirit x3 to parse these rules into the given structs? I cannot imagine what the A
or the one_arg_lambda
parsers are returning now, the one_arg_lambda
parser should parse into a LambdaType
struct, but depending on what A
parses into thats not necessary true now. So the question is now, how can I get a non-left recursive parser, which parses the grammar above into my structs using boost-spirit-x3?
EDIT II:
i would like =>
to be right associative so foo => bar => baz => baham
means foo => (bar => (baz => bahama))
I solved this problem and the solution was incredibly easy. The trick is to change the grammar, so I dont have a left recursion, and it parses nice into my structs.
so I changed
to
this second grammar descripes the exaclty same language, but without left recursion, and without changing the structure of the grammar. This was actualy luck and doesnt work for every grammar obviously.