2013-01-13 2 views
1

변수 선언 및 -Instantiations을 사용하여 텍스트 파일을 읽는 구문 분석기를 작성하려고합니다. 그리고 선언 된 모든 변수가 관련 값과 함께 포함 된 변수 테이블을 구성합니다.규칙 속성의 호환성

파일처럼 보이는 다음

int a = 18, b = 1+a*5; 
float test = rand(a); 

는이를 위해 나는에 기호를 연결할 수있는 동적 심볼 테이블 파서를 제공하는 부스트 :: 정신 :: 제나라 파서 라이브러리를 사용하고 싶습니다 가변 데이터 유형 T. 제공된 심볼 테이블 구문 분석기의 단점은 심볼을 하나의 데이터 유형 값에만 연결할 수 있다는 것입니다.

#include <boost/spirit/include/qi.hpp> 
#include <stdint.h> 
#include <string> 
template<typename VTYPE> 
struct VTable : boost::spirit::qi::symbols<char, VTYPE> { 
     VTable() {} // empty 
}; 

int main() 
{ 
     using boost::spirit::qi::rule; 
     using boost::spirit::qi::space_type; 

     VTable<int64_t> intDecs; VTable<double> floatDecs; 
     rule<std::string::iterator, boost::variant<int64_t, double>() ,space_type> decs %= (!floatDecs >> intDecs) | floatDecs; 
     return 0; 
} 

문제는 return 문 앞에 한 줄을있다 :

나는 다음과 같은 코드가 있습니다. '% ='의 왼쪽에있는 속성은 분명히 오른쪽에있는 속성과 호환되지 않습니다 (Visual Studio가 해당 코드에 대해 불평하므로).

내 질문은 무엇입니까? 파서가 속성에 대해 내가 성령의 문서를 읽을

는 :: 제나라는 다음과 같은 말했다 :

  • 기호 < 숯불, T>의 속성 유형은 intDecs의 T.
    => 속성 유형해야 int64_t()이고 floatDecs의 속성 유형은 double()이어야합니다.
  • 파서! a의 속성 유형은 사용되지 않습니다.
  • 파서 X의 속성 유형이 사용되지 않고 페이 서 Y가 T 인 경우 파서 (X >> Y)의 속성 유형은 T입니다.
    => 속성 유형 (! floatDecs >> intDecs)은이어야합니다. parser a의 속성 유형이 A이고 파서 b의 속성 유형이 B 인 경우 구문 분석기 (a | b)의 속성 유형은 boost :: variant()
    속성 유형이 (! floatDecs >> intDecs) | "http://boost-spirit.com/home/2010/ : floatDecs)는 부스트 :: 변형()

답변

1

내가 정신을 파서 소스의 속성을 표시하는 알고리즘을 제공하는 소스를 발견해야한다 01/31/무엇 인 - 더 - 속성 유형 노출별로 A-파서 일부 수정 후/"

, I 밖으로 발견

  • (! floatDecs >> intDecs의 속성) __int64 (나는 놀랄 일이 아니다라고 생각한다.)
  • floatDecs는 double (놀랄 일이 아니다)이고
  • (!floatDecs >> intDecs) | floatDecs 클래스 부스트입니다 :: 변형 < _ int64, double, struct boost :: detail :: variant :: void, structboost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail : : variant :: void_, struct boost :: detail :: variant :: void_, struct boost :: detail :: variant :: void_>

관심있는 사람들을 위해 알고리즘 :

#include <boost/spirit/include/qi.hpp> 
#include <stdint.h> 
#include <iostream> 
#include <string> 

template<typename VTYPE> 
struct VTable : boost::spirit::qi::symbols<char, VTYPE> { 
    VTable() {} // empty 
}; 

template <typename Expr, typename Iterator = std::string::iterator> 
struct attribute_of_parser { 
    typedef typename boost::spirit::result_of::compile<boost::spirit::qi::domain, Expr>::type parser_expression_type; 
    typedef typename boost::spirit::traits::attribute_of<parser_expression_type, boost::spirit::unused_type, Iterator>::type type; 
}; 

template <typename T> 
void display_attribute_of_parser(T const&) 
{ 
    typedef typename attribute_of_parser<T>::type attribute_type; 
    std::cout << typeid(attribute_type).name() << std::endl; 
} 

int main() 
{ 
    using boost::spirit::qi::eps; 
    using boost::spirit::qi::rule; 
    using boost::spirit::qi::space_type; 

    VTable<int64_t> intDecs; VTable<double> floatDecs; 
    display_attribute_of_parser((!floatDecs >> intDecs)); 
    display_attribute_of_parser(floatDecs); 
    display_attribute_of_parser((!floatDecs >> intDecs) | floatDecs); 

    return 0; 
}