2013-01-13 63 views
1

我正在嘗試編寫一個解析器,它使用Variable-Declaration和-Instantiations讀入文本文件,並構造一個Variable-Table,其中包含所有聲明的變量及其關聯的值。規則屬性的兼容性

文件如下所示:

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正在抱怨該代碼)。

我的問題是,爲什麼這樣呢?

當我讀精神的文檔::齊它下面說一下解析器屬性:

  • 符號< CHAR,T>的屬性類型是intDecs的T.
    =>屬性類型應是int64_t()和floatDecs的屬性類型應爲double()
  • 解析器!a的屬性類型未使用。
  • 如果解析器X的屬性類型未使用,並且paser Y是T,那麼解析器(X >> Y)的屬性類型是T.
    =>屬性類型(!floatDecs >> intDecs)應該是int64_t()
  • 如果解析器a的屬性類型是A,解析器b的屬性類型是B,那麼解析器(a | b)的屬性類型是boost :: variant()
    屬性類型(!floatDecs >> intDecs)| floatDecs)應該是boost :: variant()

回答

1

我找到了一個源代碼,它提供了一個算法來顯示spirit解析器源的屬性:「http://boost-spirit.com/home/2010/ 1月31日/什麼,是最屬性類型暴露按一個解析器/」

一些修改後,我發現的

  • (!floatDecs >> intDecs屬性)是__int64(我認爲這並不奇怪!)
  • floatDecs是雙倍的(沒有意外)和
  • (!floatDecs >> intDecs)| floatDecs is class boost :: variant < _ 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_>

對於那些interestered in算法:

#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; 
}