我目前陷入了一条规则,我试图使用 boostspirit x3 来解析。
这是我要解析的 EBNF(使用 Spirit 中的 % 运算符作为列表):
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%",", ">"]
使用 boostspirit x3,我尝试解析为以下结构/变体:
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_;
};
我有一个我目前正在尝试的活生生的例子here,这不起作用,我还尝试更改变体解析器的顺序,这没有帮助,我得到无尽的递归,或者不是我期望(或希望)的行为。
有人可以帮我调试这个解析器吗?
我认为我在解析器中有某种类型的左递归,是否有机会避免这种情况,或者没有机会重写语法?
这个语法可以用 boost Spirit x3 解析吗?
EDIT:
我设法消除了这个语法中的左递归。
现在语法如下:
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
但现在有下一个问题,如何让 boostspirit x3 将这些规则解析为给定的结构?我无法想象是什么A
or the one_arg_lambda
解析器现在正在返回,one_arg_lambda
解析器应该解析成LambdaType
结构,但取决于什么A
解析为现在不一定是这样。所以现在的问题是,如何获得一个非左递归解析器,它使用 boost-spirit-x3 将上面的语法解析为我的结构?
EDIT II:
我想=>
是右结合的,所以foo => bar => baz => baham
means foo => (bar => (baz => bahama))