所以我知道这是一个非常常见的错误,但我对C ++很新,我们将它用于编程语言类,而这个错误让我陷入困境。删除解析器; line是导致此错误的行,我无法弄清楚原因。
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;
}
我不知道这是否足以帮助你们帮助你们,如果你需要更多的东西只是问,它不是秘密或任何东西:)我知道它是解析器的解构函数,但是我不知道如何修复它,或者为什么会发生这种情况......我已经添加了scanner.cpp,因为有些人认为问题可能出在解构器中,所以我希望有所帮助。
答案 0 :(得分:0)
失败的原因是你在堆栈上分配的东西上使用delete
。
注意ifstream in(filename);
的组合,在堆栈上创建ifstream,在扫描器的析构函数中创建delete inStream;
。
最简单的建议是在堆上分配in
,而不是ifstream *in = new ifstream(filename)
或其他什么。
更好的解决方案可能是让其他类(Scanner,Parser等)通过引用获取ifstream,并避免指针,除非需要它们。
答案 1 :(得分:0)
您正在尝试在Scanner的析构函数中删除堆栈变量。
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 (...) {}
}