2012-02-27 46 views
0

所以我知道這是一個很常見的錯誤,但我很新的C++中,我們使用它的編程語言類,而這個錯誤有我卡住了。刪除解析器;線是導致這個錯誤的線,我不明白爲什麼。_block_type_is_valid phead- nblockuse上刪除命令

Turtle2.cpp

#include <iostream> 
#include <sstream> 
#include <string> 
#include <fstream> 
#include "scanner.h" 
#include "parser.h" 

using namespace std; 

int main(int argc, char* argv[]) { 
//string line; 
if (argc != 2) { 
    cout << "Usage: turtle filename" << endl; 
    return 0; 
} 
char* filename = argv[1]; 
cout << "filename is " << filename << endl; 
ifstream in(filename); 
Parser * parser = new Parser(&in); 
AST* tree = parser->parse(); 

tree->evaluate(); 

delete tree; 
delete parser; //This is the line that causes the error! 
return 0; 
} 

parser.cpp

#include "parser.h" 
#include "calcex.h" 
#include <string> 
#include <sstream> 

Parser::Parser(istream* in) { 
scan = new Scanner(in); 
} 

Parser::~Parser() { 
try { 
    delete scan; 
} catch (...) { 
} 
} 

AST* Parser::parse() { 
AST* returnValue = Prog(); 
cout << "We are still ok1" << endl; 
return returnValue; 
} 

AST* Parser::Prog() { 
AST* result = StmtList(); 
Token* t = scan->getToken(); 

if (t->getType() != eof) { 
    cout << "Syntax Error: Expected EOF, found token at column " << t->getCol() << endl; 
throw ParseError; 
} 
cout << "We are still ok2" << endl; 
return result; 
} 

AST* Parser::StmtList() { 
AST* result = Statement(); 
Token* t = scan->getToken(); 
scan->putBackToken(); 

if (t->getType() != eof) { 
    AST* result = StmtList(); 
     return result; 
} 

return result; 
} 

AST* Parser::Statement() { 
float num1; 
float num2; 
stmtNode* node; 
Token* t = scan->getToken(); 
/*if (turtle->getType() != keyword || turtle->getLex() != "turtle"){ 
    cerr <<"expected turtle" << endl; //print to standard error stream 
    throw ParseError; 
}*/ 
if (t->getType() == keyword && t->getLex() == "turtle"){ 
    t = scan->getToken(); 
    if (t->getType() == dot){ 
     t = scan->getToken(); 
     if (t->getType() == keyword && t->getLex() == "goto"){ 
      t = scan->getToken(); 
      if (t->getType() == lparen){ 
       t = scan->getToken(); 
       if (t->getType() == number){ 
        istringstream in(t->getLex()); 
        in >> num1; 
        t = scan->getToken(); 
        if (t->getType() == comma){ 
         t = scan->getToken(); 
         if (t->getType() == number){ 
          istringstream in(t->getLex()); 
          in >> num2; 
          t = scan->getToken(); 
          if (t->getType() == rparen){ 
           cout << "Good" << endl; 
           node = new stmtNode(num1,num2); 
           cout << "X is " << node->getX() << endl; 
           cout << "Y is " << node->getY() << endl; 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 
else{ 
    cout << "bad" << endl; 
} 
return node; 
} 

scanner.cpp

#include "scanner.h" 
#include "calcex.h" 
#include <iostream> 
#include <string> 

using namespace std; 

//Uncomment this to get debug information 
//#define debug 

const int numberOfKeywords = 2; 

const string keywd[numberOfKeywords] = { //defining the keywords 
string("turtle"), string("goto") 
}; 

int isLetter(char c) { //c is bigger or equal to 'a' and small or equal to 'z'. same  for captial versions 
return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); 
} 

int isDigit(char c) { //c is bigger or equal to '0' or smaller or equal to '9' 
return (c >= '0' && c <= '9'); 
} 

int isWhiteSpace(char c) { //c is a space, tab or newline 
return (c == ' ' || c == '\t' || c == '\n'); 
} 

Scanner::Scanner(istream* in): //scanner constructor 
inStream(in), 
lineCount(1), 
colCount(0), 
needToken(true), 
lastToken(0) 
{} 

Scanner::~Scanner() { //scanner de-constructor 
try { 
    delete inStream; 
} catch (...) {} 
} 

void Scanner::putBackToken() { //method? 
needToken = false; 
} 

Token* Scanner::getToken() { //method? 
if (!needToken) { 
    needToken=true; 
    return lastToken; 
} 

Token* t; 
int state=0; 
bool foundOne=false; 
char c; 
string lex; 
TokenType type; 
int k; 
int column, line; 

c = inStream->get(); 

while (!foundOne) { 
    colCount++; 
    switch (state) { 
    case 0 : 
     lex = ""; 
     column=colCount; 
     line = lineCount; 
     if (isLetter(c)) state=1; 
     else if (isDigit(c)) state=2; 
     else if (c=='.') state=3; 
     else if (c==',') state=4; 
     else if (c=='(') state=5; 
     else if (c==')') state=6; 
     else if (c=='\n') { 
      colCount=0; 
      lineCount++; 
     } 
     else if (isWhiteSpace(c)); 
     else if (inStream->eof()) { 
      foundOne=true; 
      type=eof; 
     } 
     else { 
      cout << "Unrecognized Token found at line " << line << 
       " and column " << column << endl; 
      throw UnrecognizedToken; 
     } 
     break; 
    case 1 : 
     if (isLetter(c) || isDigit(c)) state=1; 
     else { 
      for (k=0;k<numberOfKeywords;k++) 
       if (lex == keywd[k]) { 
       foundOne = true; 
       type = keyword; 
       } 
      if (!foundOne) { 
       type = identifier; 
       foundOne = true; 
      } 
     } 
     break; 
    case 2 : 
     if (isDigit(c)) state=2; 
     else { 
      type = number; 
      foundOne=true; 
     } 
     break; 
    case 3 : 
     type = dot; 
     foundOne = true; 
     break; 
    case 4 : 
     type = comma; 
     foundOne = true; 
     break; 
    case 5 : 
     type = lparen; 
     foundOne=true; 
     break; 
    case 6 : 
     type = rparen; 
     foundOne=true; 
     break; 
    } 

    if (!foundOne) { 
    lex = lex + c; 
    c = inStream->get(); 
    } 
} 

inStream->putback(c); 
colCount--; 
if (type == number || type == identifier || type == keyword) { 
    t = new Token(type,new string(lex),line, column); 
} 
else { 
    t = new Token(type,new string(lex),line,column); 
} 

#ifdef debug 
cout << "just found " << lex << " with type " << type << endl; 
#endif 

lastToken = t; 
return t; 

} 

我不知道這是否是足夠的代碼來幫助你們出去或不,如果你需要更多的東西,只要問一下,它不是祕密或任何東西:)我知道它是解析器的構造器,但我不知道何w解決它,或者真的爲什麼會發生這種情況...我已經添加了scanner.cpp,因爲有些人認爲問題可能出現在解構器中,所以我希望這會有所幫助。

+0

調試器應該告訴你它到底死了哪條線。 (而在解構的解析器的唯一代碼掃描的進一步缺失,所以我們需要看到的解構爲掃描儀和) – Lalaland 2012-02-27 05:20:42

+0

我已經添加了掃描儀的代碼,這是否幫助呢? – marblecatdog 2012-02-28 01:57:25

回答

0

這是爲什麼失敗的原因是您正在使用的是被分配在堆棧上的東西delete

請注意ifstream in(filename);的組合,在堆棧中創建一個ifstream,在Scanner的析構函數中創建delete inStream;

最簡單的建議是在堆上分配in,例如ifstream *in = new ifstream(filename)或什麼都沒有。

更好的解決方案很可能是通過參照具有其他類(掃描儀,解析器等)取ifstream的,和避免指針,除非需要它們。

+0

K,我將代碼更改爲ifstream * in = new ifstream(filename); \t分析器*解析器=新解析器(在);這工作,謝謝一羣傢伙! – marblecatdog 2012-02-28 03:43:08

0

您正在試圖刪除堆棧變量,在掃描儀的析構函數。

Parser * parser = new Parser(&in); 

Parser::Parser(istream* in) { 
scan = new Scanner(in); 
} 

Parser::Parser(istream* in) { 
scan = new Scanner(in); 
} 

Parser::~Parser() { 
try { 
    delete scan; 
} catch (...) { 
} 
} 

Scanner::~Scanner() { //scanner de-constructor 
try { 
    delete inStream; 
} catch (...) {} 
}