消除 spirit x3 解析器规则中的左递归
Eleminating left recursion in parser rule of spirit x3
我目前受困于我尝试使用 boost spirit 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%",", ">"]
使用 boost spirit x3,我试图解析为以下 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_;
};
我有一个我目前正在尝试的实例 here,它不起作用,我还尝试更改变体解析器的顺序,但没有帮助,我得到了无休止的递归,或不是我期望(或希望)的行为。
谁能帮我调试这个解析器?
我想我在解析器中有某种类型的左递归,是否有机会避免这种情况或者没有机会重写语法?
这个语法甚至可以用 boost spirit x3 解析吗?
编辑:
我设法消除了这个语法中的左递归。
现在语法如下:
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
但是现在有下一个问题,我如何让boost spirit x3将这些规则解析成给定的结构?我无法想象 A
或 one_arg_lambda
解析器现在返回什么,one_arg_lambda
解析器应该解析成 LambdaType
结构,但取决于 A
解析的内容现在没有必要了。所以现在的问题是,我怎样才能得到一个非左递归解析器,它使用 boost-spirit-x3 将上面的语法解析到我的结构中?
编辑二:
我希望 =>
是正确的关联所以 foo => bar => baz => baham
表示 foo => (bar => (baz => bahama))
我解决了这个问题,而且解决起来非常简单。
诀窍是改变语法,所以我没有左递归,它很好地解析到我的结构中。
所以我改变了
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%",", ">"]
到
type ::= class_type | lambda_type
lambda_type ::= more_arg_lambda | one_arg_lambda
more_arg_lambda ::= "(", type%",", ")", "=>", type
one_arg_lambda ::= class_type, "=>", type <- here is the magic trick
class_type ::= identifier%"::", ["<", type%",", ">"]
这第二个文法描述了完全相同的语言,但没有左递归,也没有改变文法的结构。
这实际上是运气,显然并不适用于所有语法。
我目前受困于我尝试使用 boost spirit 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%",", ">"]
使用 boost spirit x3,我试图解析为以下 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_;
};
我有一个我目前正在尝试的实例 here,它不起作用,我还尝试更改变体解析器的顺序,但没有帮助,我得到了无休止的递归,或不是我期望(或希望)的行为。
谁能帮我调试这个解析器?
我想我在解析器中有某种类型的左递归,是否有机会避免这种情况或者没有机会重写语法? 这个语法甚至可以用 boost spirit x3 解析吗?
编辑:
我设法消除了这个语法中的左递归。 现在语法如下:
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
但是现在有下一个问题,我如何让boost spirit x3将这些规则解析成给定的结构?我无法想象 A
或 one_arg_lambda
解析器现在返回什么,one_arg_lambda
解析器应该解析成 LambdaType
结构,但取决于 A
解析的内容现在没有必要了。所以现在的问题是,我怎样才能得到一个非左递归解析器,它使用 boost-spirit-x3 将上面的语法解析到我的结构中?
编辑二:
我希望 =>
是正确的关联所以 foo => bar => baz => baham
表示 foo => (bar => (baz => bahama))
我解决了这个问题,而且解决起来非常简单。 诀窍是改变语法,所以我没有左递归,它很好地解析到我的结构中。
所以我改变了
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%",", ">"]
到
type ::= class_type | lambda_type
lambda_type ::= more_arg_lambda | one_arg_lambda
more_arg_lambda ::= "(", type%",", ")", "=>", type
one_arg_lambda ::= class_type, "=>", type <- here is the magic trick
class_type ::= identifier%"::", ["<", type%",", ">"]
这第二个文法描述了完全相同的语言,但没有左递归,也没有改变文法的结构。 这实际上是运气,显然并不适用于所有语法。