2015-09-05 82 views
-3

我們需要解析出給定的程序代碼。代碼示例:C++程序解析器

procedure example1 { 
    x = 0; 
    z = y + x; 
    a =1; 
    while a{ 
    x = z + x; 
    while x { 
     c = a + b; 
     } 
} 
} 

我曾嘗試: 的示例代碼是在一個文本文件,所以我打開它,然後我通過信息的載體,在這之後,我從矢量標記逐個分析並尋找關鍵字。目前,我的代碼一直在Error方法中顯示錯誤消息,我看不出明白爲什麼。這是一個學校作業。我的代碼如下。任何和所有的幫助表示讚賞。

vector<string> tokens; 
SimpleParser::SimpleParser() 
{ 
    cout << "Please enter a file name: "; 
    cin >> userInput; 
    cout << "fILENAME: " + userInput; 
    openFile(userInput); 
} 


SimpleParser::~SimpleParser() 
{ 
} 

void SimpleParser::openFile(string fileName) { 

    ifstream myfile(fileName); 
    if (myfile.is_open()) 
    { 
     while (getline(myfile, currLine)) 
     { 
      size_t comments = currLine.find("//"); 
      if (comments != string::npos) 
      { 
       currLine = currLine.erase(comments); 
       allLines += " " + currLine; 
      } 
      else { 
       allLines += " " + currLine; 
      } 
     } 
     myfile.close(); 
     fillVector(allLines); 
    } 

    else 
    { 
     cout << "Unable to open file"; 
    } 
} 

//check if line is proc, while,assign 
void SimpleParser::fillVector(string line) { 
    istringstream iss(line); 
    copy(istream_iterator<string>(iss), 
    istream_iterator<string>(), 
    back_inserter(tokens)); 
    next_token = getToken(); 
    procedure(); 
} 

void SimpleParser::procedure() { 
    Match("procedure"); 
    //string proc_name = next_token; 
    //Match(proc_name); 
    Match("{"); 
    stmtLst(); 
    Match("}"); 
} 

void SimpleParser::stmtLst() { 
    cout << "All lines : "+ allLines; 
} 

void SimpleParser::Match(string token) { 
    if (next_token.compare(token) == 0) { 
     next_token = getToken(); 
      } 
    else { 
     Error(); 
    } 

} 

string SimpleParser::getToken() { 
    string t = ""; 
    if (countOfVecs < tokens.size()) { 
     t = tokens[countOfVecs]; 
    } 
    countOfVecs++; 
    return t; 

} 

void SimpleParser::Error() { 
    cout << "Error parsing!"; 
    //exit(0); 
} 

void SimpleParser::Stmt() { 
    string var_name = next_token; 
    Match(var_name); 
    Match("="); 
    Match(next_token); 

} 
+9

所以,你想我在你的代碼中使用調試器來找出是什麼導致了錯誤?對不起,但是在你自己的代碼中使用調試器會更有效率。 –

+2

有意思的是,你發佈不相關的函數,但不要發佈非常相關的類定義。 –

+0

我發現如果'nextToken'與傳遞給'Match'函數的令牌不匹配,就會執行'Error'。如果只有我有一個調試器方便,我可以在'Match'的'if'語句中放置一個斷點,並查看變量'next_token'和'token'來了解它們爲什麼不同。由於我沒有全部代碼,因此無法爲您運行調試器。 –

回答

0

正如我所看到的,問題是相關要麼你get或您:

void SimpleParser::Match(string token) { 
    // compare token with next_token 
    if (next_token.compare(token) == 0){ 
     // if they match assign next_token to the next token 
     next_token = getToken(); 
    }else{ 
     // if they don't compare equal throw an error 
     Error(); 
    } 
} 

到底是什麼上述功能的目的是什麼?

一般來說,沒有必要浪費太多的內存和讀取所有的文件,你可以逐字解析,直到你得到所需的關鍵字。因此,這裏有一個稍微不同的實現,它將實際解析而不復制所有文件內容。

class Token{ 
public: 
    // data members for the three types of tokens: 
    // algebraic operator, number, and user defined variable(name, value) 
    char kind; 
    double value; 
    string name; 

    // constructors for each of the three tokens 
    Token(char ch): kind(ch), value(0) { } 
    Token(char ch, double val) :kind(ch), value(val) { } 
    Token(char ch, string n) :kind(ch), name(n) { } 
}; 


// class used as an input stream for tokens 
class Token_stream { 
public: 
    // constructor 
    Token_stream() :full(false), buffer(0) { } 
    // member functions 
    Token get(); 

private: 
    // data members defining the Token_stream buffer 
    bool full; 
    Token buffer; 
}; 


const string firstKeyword = "key1"; 

// get function implementation 
Token Token_stream::get(){ 
    if (full) { 
     full=false; 
     return buffer; 
    } 

    char ch; 
    // to read from file change cin to the relevant input stream object 
    cin.get(ch); 
    switch (ch){ 
    // if the token some of the above symbols: return it 
    case '(': case ')': case '+': case '-': case ',': case '!': 
    case '*': case '/': case '%': case 'Q': case '=': 
     return Token(ch); 
    // if the token a number int of float: return it as "number token" 
    case '.': 
    case '0': case '1': case '2': case '3': case '4': 
    case '5': case '6': case '7': case '8': case '9': 
    { 
     cin.putback(ch); 
     double val; 
     cin >> val; 
     return Token(number,val); 
    } 
    case '\n': case '\r': 
     return Token(print); 
    default: 
     { 
      if (isspace(ch))   // skips whitespaces; taking up this funciton from the replaced 'cin' 
     { 
      while(isspace(ch)) cin.get(ch); 
     } 
     if (isalpha(ch) || ch == '_' || ch == '#') { 
      string s; 
      s += ch; 
      while(cin.get(ch) && (isalpha(ch) || isdigit(ch) || ch == '_' || ch == '#')) s += ch; 

      cin.putback(ch); 
      // if the token is some of the predefined "Keywords": return it as the respective token 
      if (s == firstKeyword) return Token(keyToken); 
      if (s == secondKeyword) return Token(sekondKeyToken); 
      if (s == thirdKeyword) return Token(thirdKeyToken); 

      return Token(name,s); 
     } 
     error("bad input token!", ch); 
    } 
} 
}