【问题标题】:problems parsing into recursive variant using boost spirit x3使用 boost spirit x3 解析为递归变体的问题
【发布时间】:2016-10-09 20:18:46
【问题描述】:

我目前正在尝试使用 boost spirit x3 解析为x3::variant。 变体看起来像:

typedef x3::variant<
    nil,
    x3::forward_ast<LambdaType>,
    x3::forward_ast<ClassType>
> Type

LambdaType 和 ClassType 的样子:

struct LambdaType {
        std::vector<Type> parameters_;
        Type return_type_;
    };

struct ClassType{
    std::vector<std::string> name_; 
   std::vector<Type> template_args_;
};

如果我尝试解析为 Type 或这些结构之一,我会收到编译器错误,告诉我无法将 const boost::spirit::x3::char_class 分配给 Type, 我对此感到困惑,因为我不想分配const boost::spirit::x3::char_class。 我有一个实时示例here,它有一个解析器,当您尝试编译它时会显示问题和错误。 我试图解决这个问题一整天,我现在不知道为什么这不起作用。 如有任何帮助,我将不胜感激。

【问题讨论】:

    标签: c++ parsing boost-spirit boost-spirit-x3


    【解决方案1】:

    您将x3::space 作为最后一个参数传递给x3::parse,因此它将绑定到解析器的属性。

    你当然不想这样。

    如果您想通过船长,请使用x3::phrase_parse

    PS 正如所写,您的解析器还有一个问题:它在 type/lambdaType 中有左递归。我认为这是因为您取消了标识符解析 (x3::string("foo")) 所以如果您将输入修复为 (foo, foo) =&gt; foo:

    Live On Coliru

    #define BOOST_SPIRIT_X3_DEBUG
    #include <iostream>
    #include <boost/spirit/home/x3.hpp>
    #include <boost/spirit/home/x3/support/ast/variant.hpp>
    #include <boost/fusion/include/adapt_struct.hpp>
    
    namespace x3 = boost::spirit::x3;
    
    namespace ast{
        struct LambdaType;
        struct ClassType;
        struct nil{};
    
        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_;
        };
    
    }
    
    BOOST_FUSION_ADAPT_STRUCT(ast::LambdaType, parameters_, return_type_)
    BOOST_FUSION_ADAPT_STRUCT(ast::ClassType, name_, template_args_)
    
    namespace parser{
        typedef x3::rule<struct lambda_type_class, ast::LambdaType> lambda_type_type;
        typedef x3::rule<struct class_type_class,  ast::ClassType>  class_type_type;
        typedef x3::rule<struct type_class,        ast::Type>       type_type;
    
        const class_type_type  class_type  = "class_type";
        const lambda_type_type lambda_type = "lambda_type";
        const type_type        type_p      = "type";
    
        auto const type_p_def = class_type | lambda_type;
    
        auto const lambda_type_def =
            ("(" >> -(type_p%",") >> ")" >> "=>" >> type_p)
            | (x3::repeat(1)[type_p%","] >> "=>" >> type_p)
                ;
    
        auto const class_type_def =
                (x3::string("foo")%"::") >> -("<" >> type_p%"," >> ">")
                ;
    
        BOOST_SPIRIT_DEFINE(
                lambda_type,
                class_type,
                type_p
        )
    }
    
    int main()
    {
        std::string input = "(foo, foo) => foo";
        x3::phrase_parse(input.begin(), input.end(), parser::type_p, x3::space);
    }
    

    带调试输出

    <type>
      <try>(foo, foo) => foo</try>
      <class_type>
        <try>(foo, foo) => foo</try>
        <fail/>
      </class_type>
      <lambda_type>
        <try>(foo, foo) => foo</try>
        <type>
          <try>foo, foo) => foo</try>
          <class_type>
            <try>foo, foo) => foo</try>
            <success>, foo) => foo</success>
            <attributes>[[[f, o, o]], []]</attributes>
          </class_type>
          <success>, foo) => foo</success>
          <attributes></attributes>
        </type>
        <type>
          <try> foo) => foo</try>
          <class_type>
            <try> foo) => foo</try>
            <success>) => foo</success>
            <attributes>[[[f, o, o]], []]</attributes>
          </class_type>
          <success>) => foo</success>
          <attributes></attributes>
        </type>
        <type>
          <try> foo</try>
          <class_type>
            <try> foo</try>
            <success></success>
          </class_type>
          <success></success>
        </type>
        <success></success>
      </lambda_type>
      <success></success>
    </type>
    

    【讨论】:

    • 添加了更多提示和live sample
    • 开个玩笑不是吗 :(,我现在感觉很傻,我调试了最后 3 个小时没有任何成功。非常感谢你打开我的眼睛
    • 我也认识到了左递归,here 是我的问题,我以前从未处理过这个问题,我正在努力避免左递归
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    相关资源
    最近更新 更多