2012-11-18 40 views
0

假設我想用boost正則表達式解析簡單的編程語言。Boost.Regex解析

import a 
import b 

class c 

現在我想有這樣的佈局:

#include <string> 
#include <boost/filesystem.hpp> 
#include <exception> 

using namespace std; 
using namespace boost; 
using namespace boost::filesystem; 

class parser 
{ 
    string _source; 
    unsigned int pos; 
public: 
    parser(const string& source) : _source(source), pos(0) {} 

    string expect(const regex& expr) 
    { 
     string s = next(expr) 
     if (s != "") 
      return s; 
     else 
     {   
      --pos; 
      throw exception("Expected another expression."); 
     } 
    } 

    string next(const regex& expr) 
    { 
     // Removing all whitespace before first non-whitespace character 
     // Check if characters 0 till x matches regex expr 
     // Return matched string of "" if not matched. 
    } 

    bool peek(const regex& expr); 

    parse() 
    { 
     regex identifier("\a*"); 
     if (peek("import")) 
      string package = expect(identifier); 
     else if (peek("class")) 
      string classname = expect(identifier); 
    } 
}; 

現在我需要你的幫助來定義函數解析器::接下來的(常量正則表達式&)。 我不清楚如何通過std :: string迭代boost正則表達式。

我希望有人能幫助我!

回答

1

假設Boost regexp使用類似於標準C++庫中正則表達式的方法(我意識到標準中的那些是基於來自Boost的提議,但其他組件並不完全相同),您可以使用在std::match_results<...>對象中獲得的信息來確定與匹配相關的信息。

0

對於有興趣的人。我解決了它這種方式在當前實現:

注意關鍵的部分可能會丟失,但這個答案

int submatch(const std::string& input, const regex& e) 
{ 
    boost::match_results<std::string::const_iterator> what; 
    if(0 == boost::regex_match(input, what, e, boost::match_default | boost::match_partial)) 
    { 
     // the input so far could not possibly be valid so reject it: 
     return 0; 
    } 
    // OK so far so good, but have we finished? 
    if(what[0].matched) 
    { 
     // excellent, we have a result: 
     return 2; 
    } 
    // what we have so far is only a partial match... 
    return 1; 
} 

void skip_ws() 
{ 
    // Skip all whitespaces 
    regex ws("\\s"); 
    while ((pos < (source.length() - 1)) && boost::regex_match(source.substr(pos++, 1), ws)) 
    { 
    } 
    pos -= 1; 
} 

string lex(const token& t) 
{ 
    skip_ws(); 
    string sub; 

    unsigned int subpos = pos; 
    bool matched = false; 
    while (subpos < (source.length() - 1)) 
    { 
     sub.push_back(source[subpos++]); 
     int result = submatch(sub, t.expr); 
     if (result == 1) // Partial 
     { 
      continue; 
     } 
     else if (result == 2) 
     { 

      matched = true; 
      continue; 
     } 
     else if (result == 0) // No match 
     { 
      if (matched) 
      { 
       sub.erase(sub.end()-1); 
       subpos -= 1; 
       break; 
      } 
      else 
      { 
       return ""; 
      } 
     } 
    } 

    return sub; 
} 

string expect(const token& t) 
{ 
    cout << " string expect(\"" << t.expr << "\")"; 
    string s = lex(t); 
    pos += s.length(); 
    if (s != "") 
    { 
     cout << endl; 
     return s; 
    } 
    else 
    {    
     --pos; 
     cout << "-> False" << endl; 
     throw string("Expected another expression."); 
    } 
}