微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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%"::",">"]

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

原文地址:https://www.jb51.cc/c/115850.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐