2017-06-18 46 views
1

我正在努力提升精神x3,並且對一點不清楚。我有一個具有非常不同和重複行的文件。前幾行可能是註釋。接下來的1000行可能是座標,下一千行可能是int的列表等等...使用Spirit x3,如何控制在每個不同的輸入上調用哪個解析器?

我的問題是如何識別行並知道該行使用哪個解析器。例如,這裏有兩個解析器函數....

template <typename Iterator> 
bool parse_ints(Iterator first, Iterator last, std::vector<int>& v) 
{ 
    using x3::int_; 
    using x3::phrase_parse; 
    using x3::_attr; 
    using ascii::space; 

    auto push_back = [&](auto& ctx){ v.push_back(_attr(ctx)); }; 

    bool r = phrase_parse(first, last, 
     (
      int_[push_back] 
       >> *(',' >> int_[push_back]) 
     ) 
     , 
     space); 

    if (first != last) 
     return false; 
    return r; 
} 

template <typename Iterator> 
bool parse_doubles(Iterator first, Iterator last, std::vector<double>& v) 
{ 
    using x3::double_; 
    using x3::phrase_parse; 
    using x3::_attr; 
    using ascii::space; 

    auto push_back = [&](auto& ctx){ v.push_back(_attr(ctx)); }; 

    bool r = phrase_parse(first, last, 
     (
      double_[push_back] 
       >> *(',' >> double_[push_back]) 
     ) 
     , 
     space); 

    if (first != last) // fail if we did not get a full match 
     return false; 
    return r; 
} 

這裏是如何輸入(istringstream是數百MB的大小)。而在while循環中,我很想知道要調用哪個解析器。

int main() 
{ 
    istringstream str(my.data()); 

    while (getline(str, line)) { 
     // based on the format of 'line', how does one know which 
     // parser to call? 
    } 
} 

回答

1

你的語法可以描述整個輸入。所以,你可以說

auto input = *headerComment 
      >> points 
      >> edges; 

在哪裏,你可以簡單地定義

auto headerComment = '#' >> *(char_ - eol) >> eol; 

而如

auto points = skip(blank) [ 
    *(point >> eol) 
    ]; 

auto edges = skip(blank) [ 
    *(edge >> eol) 
    ]; 

point = int_ >> int_ >> int_; // assuming x y z 
edge = int_ >> int_;   // assuming from to 

這假設輸入格式是明確的。即如果積分只有x y,那麼它就無法工作,因爲它無法區分當時的邊緣。

相關問題