我目前正在坚持一个规则,我正在尝试使用boost精神x3来解析.
这里是EBNF(使用列表中的精灵的%运算符)为了解决我的问题:
这里是EBNF(使用列表中的精灵的%运算符)为了解决我的问题:
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%"::",["<",">"]
usng提升精神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,这是不工作,我也试图改变变体解析器的顺序,没有帮助,我得到无休止的回忆,或不是我会期望的行为(或希望) .
有人可以帮我调试这个解析器吗?
我认为我在解析器中有一些类型的左递归,有机会避免这种情况吗,还是没有机会重写语法?
这个格拉姆甚至可以用提升精神x3来解释吗?
编辑:
我设法解除了这个语法中的左递归.
现在te语法如下:
type ::= class_type | lambda_type lambda_type ::= more_arg_lambda | one_arg_lambda more_arg_lambda ::= "(",type one_arg_lambda ::= class_type,"=>" type,A | "(",type,A class_type ::= identifier%"::",">"] A::= "=>",A | eps
但是现在还有下一个问题,我如何能够提升精神x3来将这些规则解析成给定的结构体?我无法想象A或one_arg_lambda解析器现在返回的是什么,one_arg_lambda解析器应该解析成LambdaType结构,但是取决于现在解析为不需要的内容.所以现在的问题是,如何获得一个非左递归解析器,它使用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 ::= class_type | lambda_type lambda_type ::= more_arg_lambda | one_arg_lambda more_arg_lambda ::= "(",type one_arg_lambda ::= class_type,type <- here is the magic trick class_type ::= identifier%"::",">"]
这第二个语法描述了相同的语言,但没有左递归,而不改变语法的结构.这是真的运气,并不明显地为每一种语法工作.