c – 解析器精神x3中的左递归

前端之家收集整理的这篇文章主要介绍了c – 解析器精神x3中的左递归前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我目前正在坚持一个规则,我正在尝试使用boost精神x3来解析.
这里是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%"::",">"]

这第二个语法描述了相同的语言,但没有左递归,而不改变语法的结构.这是真的运气,并不明显地为每一种语法工作.

猜你在找的C&C++相关文章