2016-10-09 11 views
3

현재 부스트 스피릿 x3을 사용하여 x3::variant으로 파싱하려고합니다.부스트 스피릿을 사용하여 재귀 변형으로 구문 분석하는 데 문제가 있습니다. x3

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을 할당하고 싶지 않으므로 혼란 스럽습니다. 나는 파서를 가지고 있고 그것을 컴파일하려고 할 때, 문제와 오류를 보여주는 라이브 예제 here을 가지고있다. 나는이 문제를 하루 종일 해결하려고 노력하고 있는데 왜 지금이 일이 왜 작동하지 않는지 전혀 알지 못합니다. 이 도움이 필요하면 감사 할 것입니다.

답변

3

마지막 인수로 을 입력하면 파서의 속성에 바인드됩니다.

물론 원하지 않았습니다.

스키퍼를 통과하려면 x3::phrase_parse을 사용하십시오.

PS 파서에 추가 문제가 있습니다. 유형/lambdaType에 왼쪽 재귀가 있습니다. 난 당신이 (foo, foo) => foo로 입력을 수정하면 그래서 여기에 당신이 식별자 구문 분석 (x3::string("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> 
+0

추가 몇 가지 힌트와 [라이브 샘플] (http://coliru.stacked-crooked.com/a/b6563a54ddc9048e) – sehe

+0

농담이 아닙니다 : (나는 지금 바보 같다고 느낀다. 지난 3 시간 동안 아무런 성공도없이 디버깅을하고 있었다. 내 눈을 열어 주셔서 감사합니다. – Exagon

+0

왼쪽 재귀를 인식했습니다. [여기] (http://stackoverflow.com/questions/39949480/boost-spirit-failing-to-parse-recursive-rule)은 내 질문입니다. 그것에 대해, 나는 전에이 문제를 다루지 않았고 나는 왼쪽 재귀를 피하기 위해 고심하고있다. – Exagon