From 02017854db69c44074c6196fb884d725dc3662db Mon Sep 17 00:00:00 2001 From: fsan Date: Tue, 5 Oct 2021 02:29:55 -0300 Subject: [PATCH] no more leaks, less copy assignments, fixed an error where I would be assigning TOK_ID to STM_ASSIGN lvalue. --- interpreter.cpp | 4 +-- lexer.cpp | 15 ++++++-- main.cpp | 9 ++--- orga-comp.h | 36 +++++++++++-------- parser.cpp | 96 ++++++++++++++++++++++++++----------------------- scope.cpp | 0 utilities.cpp | 33 ++++++++++++++--- 7 files changed, 121 insertions(+), 72 deletions(-) create mode 100644 scope.cpp diff --git a/interpreter.cpp b/interpreter.cpp index dc40c59..21ceb17 100644 --- a/interpreter.cpp +++ b/interpreter.cpp @@ -4,8 +4,8 @@ void interpreter::evalSTM(struct token stm) { switch (stm.tok_type) { case token::STM_ASSIGN: - table[stm.lvalue->value] = evalEXP(*stm.rvalue); - std::cout << stm.lvalue->value << " igual a " << table[stm.lvalue->value] << '\n'; + table[stm.value] = evalEXP(*stm.rvalue); + std::cout << stm.value << " igual a " << table[stm.value] << '\n'; break; case token::STM_COMPOUND: evalSTM(*stm.lvalue); diff --git a/lexer.cpp b/lexer.cpp index 58bb8a5..0bad7c3 100644 --- a/lexer.cpp +++ b/lexer.cpp @@ -1,6 +1,6 @@ #include "orga-comp.h" -std::vector +std::vector lexer::lex_file(std::string filename) { //leer un char -> ver que es -> pasar a un estado // [a-z] -> id @@ -37,11 +37,13 @@ lexer::lex_file(std::string filename) { case '-': if(id) add_token(token::TOK_ID, *value); if(num) add_token(token::TOK_NUM, *value); + delete value; value = new std::string(); *value += c; add_token(token::TOK_OP, *value); id = false; num = false; + delete value; value = new std::string(); //OP break; @@ -51,6 +53,7 @@ lexer::lex_file(std::string filename) { add_token(token::TOK_ASSIGN, ""); id = false; num = false; + delete value; value = new std::string(); break; case ';': @@ -59,6 +62,7 @@ lexer::lex_file(std::string filename) { add_token(token::TOK_SEMI, ""); id = false; num = false; + delete value; value = new std::string(); //STM END break; @@ -67,6 +71,7 @@ lexer::lex_file(std::string filename) { if(num) add_token(token::TOK_NUM, *value); id = false; num = false; + delete value; value = new std::string(); default: break; @@ -83,5 +88,11 @@ lexer::add_token(token::type type, std::string value) { struct token *token = new struct token; token->tok_type = type; token->value = value; - _tokens.push_back(*token); + _tokens.push_back(token); +} + +lexer::~lexer(){ + for(int i = 0; i < _tokens.size(); i++){ + delete _tokens[i]; + } } \ No newline at end of file diff --git a/main.cpp b/main.cpp index 4afe07d..a0d31c3 100644 --- a/main.cpp +++ b/main.cpp @@ -9,11 +9,12 @@ main(){ interpreter inter; lexer lex; - parser parser(lex.lex_file("tst.cfran")); - struct token end = parser.parse_tokens(); + std::vector lexed = lex.lex_file("tst.cfran"); + parser parser(lexed); + struct token *end = parser.parse_tokens(); std::cout << "\n-----------------------\n"; std::cout << "EVALUATING RESULTING TREE:\n"; - inter.evalSTM(end); - + inter.evalSTM(*end); +// free_tree(end); return 1; } \ No newline at end of file diff --git a/orga-comp.h b/orga-comp.h index 20295b3..49e2037 100644 --- a/orga-comp.h +++ b/orga-comp.h @@ -30,11 +30,13 @@ struct token { }; type tok_type; std::string value; - struct token *lvalue; - struct token *rvalue; + struct token *lvalue = nullptr; + struct token *rvalue = nullptr; }; -void print_tokens(std::vector tokens); +void print_tokens(std::vector tokens); +bool leaf(struct token *tok); +void free_tree(struct token *head); std::string str_token(struct token tok); class interpreter { @@ -49,34 +51,39 @@ private: class lexer { public: - std::vector lex_file(std::string filename); + std::vector lex_file(std::string filename); + ~lexer(); private: - std::vector _tokens; + std::vector _tokens; void add_token(token::type, std::string value); }; class parser { public: - parser(std::vector tokens); - struct token parse_tokens(); + parser(std::vector tokens); + struct token *parse_tokens(); + ~parser(); private: void reduce(); - void reduce_num(struct token num); - void reduce_id(struct token id); - void reduce_stm(struct token stm); - void reduce_exp(struct token exp); + void reduce_num(struct token *num); + void reduce_id(struct token *id); + void reduce_stm(struct token *stm); + void reduce_exp(struct token *exp); void statement(); //pops an statement into stack void expression(); //pops an expression into stack void err(); - struct token pop(); - std::vector _tokens; - std::stack _stack; + struct token *pop(); + void push(struct token *tok); + std::vector _tokens; + std::stack _stack; size_t pos; }; class scope { public: + scope(); + scope(scope const &father); enum symbol_type{ VALUE, }; @@ -85,6 +92,7 @@ class scope { std::string key; symbol_type type; }; + struct node head; }; class translate { diff --git a/parser.cpp b/parser.cpp index d6320ed..242c7b9 100644 --- a/parser.cpp +++ b/parser.cpp @@ -1,6 +1,7 @@ #include "orga-comp.h" +#include -struct token +struct token * parser::parse_tokens() { // LR(k) parsing. // Pushea al stack hasta encontrar una cantidad de token suficiente @@ -10,7 +11,7 @@ parser::parse_tokens() { _stack.push(_tokens[pos]); pos++; //_stack.push(tok); - switch (_stack.top().tok_type) { + switch (_stack.top()->tok_type) { case token::TOK_ID: std::cout << "STATEMENT\n"; statement(); @@ -32,7 +33,7 @@ parser::parse_tokens() { //check if reduce is possible, if it is reduce. } -parser::parser(std::vector tokens) { +parser::parser(std::vector tokens) { _tokens = tokens; pos = 0; } @@ -40,10 +41,10 @@ parser::parser(std::vector tokens) { void parser::reduce() { if(_stack.size() == 1) return; - struct token tok = pop(); + struct token *tok = pop(); - std::cout << str_token(tok) << " "; - switch (tok.tok_type) { + std::cout << str_token(*tok) << " "; + switch (tok->tok_type) { case token::TOK_NUM: std::cout << "reduzco numero\n"; reduce_num(tok); @@ -71,19 +72,17 @@ parser::reduce() { } void -parser::reduce_stm(struct token stm) { - struct token tok = pop(); +parser::reduce_stm(struct token *stm) { + struct token *tok = pop(); struct token *tmp; - switch (tok.tok_type) { + switch (tok->tok_type) { case token::STM_ASSIGN: case token::STM_COMPOUND: tmp = new struct token; tmp->tok_type = token::STM_COMPOUND; - tmp->rvalue = new struct token; - *tmp->rvalue = stm; - tmp->lvalue = new struct token; - *tmp->lvalue = tok; - _stack.push(*tmp); + tmp->rvalue = stm; + tmp->lvalue = tok; + push(tmp); std::cout << "CHAD STM REDUCER " << str_token(*tmp); break; default: @@ -93,74 +92,74 @@ parser::reduce_stm(struct token stm) { } void -parser::reduce_id(struct token id) { +parser::reduce_id(struct token *id) { struct token *tmp = new struct token; tmp->tok_type = token::EXP_ID; - tmp->value = id.value; - _stack.push(*tmp); + tmp->value = id->value; + push(tmp); } void -parser::reduce_num(struct token num) { +parser::reduce_num(struct token *num) { struct token *tmp = new struct token; tmp->tok_type = token::EXP_NUMBER; - tmp->value = num.value; - _stack.push(*tmp); + tmp->value = num->value; + push(tmp); } void -parser::reduce_exp(struct token exp) { - std::cout << "reducing exp: " << str_token(exp) << "\n"; - struct token modifier = pop(); +parser::reduce_exp(struct token *exp) { + std::cout << "reducing exp: " << str_token(*exp) << "\n"; + struct token *modifier = pop(); struct token *tmp; struct token *stm; - switch (modifier.tok_type) { + switch (modifier->tok_type) { case token::TOK_ASSIGN: std::cout << "assign found\n"; - if(_stack.top().tok_type != token::TOK_ID) err(); - std::cout << str_token(_stack.top()) << "\n"; + if(_stack.top()->tok_type != token::TOK_ID) err(); + std::cout << str_token(*_stack.top()) << "\n"; stm = new struct token; stm->tok_type = token::STM_ASSIGN; - stm->rvalue = new struct token; - *stm->rvalue = exp; - stm->lvalue = new struct token; - *stm->lvalue = pop(); - _stack.push(*stm); + stm->rvalue = exp; + stm->value = pop()->value; + push(stm); break; case token::TOK_OP: - if(_stack.top().tok_type == token::TOK_NUM) { + if(_stack.top()->tok_type == token::TOK_NUM) { reduce_num(pop()); } - if(_stack.top().tok_type == token::TOK_ID) { + if(_stack.top()->tok_type == token::TOK_ID) { reduce_id(pop()); } stm = new struct token; stm->tok_type = token::EXP_OPERATION; - stm->value = modifier.value; - stm->rvalue = new struct token; - *stm->rvalue = exp; - stm->lvalue = new struct token; - *stm->lvalue = pop(); - _stack.push(*stm); + stm->value = modifier->value; + stm->rvalue = exp; + stm->lvalue = pop(); + push(stm); //reduce_exp(pop()); break; default: err(); } - } -struct token +struct token * parser::pop() { - struct token tmp = _stack.top(); + struct token *tmp = _stack.top(); _stack.pop(); return tmp; } +void +parser::push(struct token *tok) { + _stack.push(tok); +} + void parser::statement() { _stack.push(_tokens[pos]); pos++; - assert(_stack.top().tok_type == token::TOK_ASSIGN); + assert(_stack.top()->tok_type == token::TOK_ASSIGN); expression(); } @@ -169,7 +168,7 @@ parser::expression() { _stack.push(_tokens[pos]); pos++; std::cout << "POS: " << pos << '\n'; - switch (_stack.top().tok_type) { + switch (_stack.top()->tok_type) { // case token::EXP_NUMBER: // case token::EXP_ID: case token::TOK_ID: @@ -197,7 +196,14 @@ void parser::err() { std::cout << "unexpected symbol: " - << str_token(_stack.top()) + << str_token(*_stack.top()) << '\n'; exit(-1); } + +parser::~parser(){ + free_tree(pop()); +// while (_stack.size() > 0) { +// delete pop(); +// } +} \ No newline at end of file diff --git a/scope.cpp b/scope.cpp new file mode 100644 index 0000000..e69de29 diff --git a/utilities.cpp b/utilities.cpp index 7581c1e..d648bf5 100644 --- a/utilities.cpp +++ b/utilities.cpp @@ -1,16 +1,39 @@ #include "orga-comp.h" +#include void -print_tokens(std::vector tokens){ - for(struct token tok : tokens) { - std::cout << str_token(tok) << " "; +print_tokens(std::vector tokens){ + for(struct token *tok : tokens) { + std::cout << str_token(*tok) << " "; } std::cout << '\n'; } +bool +leaf(struct token *tok){ + if(tok->lvalue != nullptr) + return false; + if(tok->rvalue != nullptr) + return false; + return true; +} + +void +free_tree(struct token *head){ + if(head == nullptr) + return; + if (leaf(head)) { + delete(head); + } else { + free_tree(head->lvalue); + free_tree(head->rvalue); + delete(head); + } +} + std::string str_token(struct token tok){ - switch (tok.t) { + switch (tok.tok_type) { case token::TOK_ID: return "ID(" + tok.value + ")"; case token::TOK_NUM: @@ -22,7 +45,7 @@ str_token(struct token tok){ case token::TOK_SEMI: return "SEMI "; case token::STM_ASSIGN: - return "STM_ASSIGN( " + str_token(*tok.lvalue) + ", " + str_token(*tok.rvalue) + ")"; + return "STM_ASSIGN( " + tok.value + ", " + str_token(*tok.rvalue) + ")"; case token::STM_COMPOUND: return "STM_COMPOUND( " + str_token(*tok.lvalue) + ", " + str_token(*tok.rvalue) + ")"; case token::EXP_NUMBER: