#include "orga-comp.h" #include struct token * parser::parse_tokens() { // LR(k) parsing. // Pushea al stack hasta encontrar una cantidad de token suficiente // como para saber que hacer. // El parse a su vez arma un abstract syntax tree. if(pos < _tokens.size()) { _stack.push(_tokens[pos]); pos++; //_stack.push(tok); switch (_stack.top()->tok_type) { case token::TOK_ID: statement(); break; case token::STM_COMPOUND: break; case token::TOK_IF: std::cout << "ENTERING COND REDUCTION"; conditional(); // conditional follows the form of IF EXP DO STM END break; case token::TOK_END: break; default: std::cout << "ERROR PARSING\n"; err(); break; } parse_tokens(); } return _stack.top(); //check if reduce is possible, if it is reduce. } parser::parser(std::vector tokens) { _tokens = tokens; pos = 0; } void parser::reduce() { if(_stack.size() <= 1) return; struct token *tok = pop(); std::cout << str_token(*tok) << " "; switch (tok->tok_type) { case token::TOK_NUM: // std::cout << "reduzco numero\n"; reduce_num(tok); // reduce(); break; case token::EXP_ID: case token::EXP_OPERATION: case token::EXP_NUMBER: // EL SIGUIENTE ES UN OP O UN ASSIGN reduce_exp(tok); break; case token::TOK_ID: reduce_id(tok); break; case token::TOK_SEMI: // reduce(); break; case token::STM_CJUMP: std::cout << "CJUMP 44\n"; reduce_blck(); break; case token::STM_ASSIGN: reduce_stm(tok); default: break; } reduce(); } void parser::reduce_stm(struct token *stm) { struct token *tok = pop(); struct token *tmp; switch (tok->tok_type) { case token::STM_CJUMP: case token::STM_ASSIGN: case token::STM_COMPOUND: tmp = new struct token; tmp->tok_type = token::STM_COMPOUND; tmp->rvalue = stm; tmp->lvalue = tok; push(tmp); // std::cout << "CHAD STM REDUCER " << str_token(*tmp); break; default: std::cout << "ERROR REDUCING STM\n"; std::cout << str_token(*tok) << "\n"; err(); break; } } void parser::reduce_id(struct token *id) { struct token *tmp = new struct token; tmp->tok_type = token::EXP_ID; tmp->value = id->value; push(tmp); } void parser::reduce_num(struct token *num) { struct token *tmp = new struct token; tmp->tok_type = token::EXP_NUMBER; 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(); struct token *tmp; struct token *stm; 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"; stm = new struct token; stm->tok_type = token::STM_ASSIGN; stm->rvalue = exp; stm->value = pop()->value; push(stm); break; case token::TOK_EQ: std::cout << "CMP_EXP\n"; if(_stack.top()->tok_type == token::TOK_NUM) { reduce_num(pop()); } if(_stack.top()->tok_type == token::TOK_ID) { reduce_id(pop()); } stm = new struct token; stm->tok_type = token::EXP_COMPARE; stm->value = modifier->value; stm->rvalue = exp; stm->lvalue = pop(); push(stm); std::cout << "\n" << str_token(*stm) << '\n'; break; case token::TOK_OP: if(_stack.top()->tok_type == token::TOK_NUM) { reduce_num(pop()); } 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 = exp; stm->lvalue = pop(); push(stm); break; default: std::cout << "ERROR REDUCING EXP\n"; err(); } std::cout << "\nTOKENS " << pos << '\n'; print_tokens(_tokens); } struct token * parser::pop() { 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); expression(); } void parser::expression() { _stack.push(_tokens[pos]); pos++; switch (_stack.top()->tok_type) { case token::TOK_ID: case token::TOK_NUM: expression(); break; case token::EXP_ID: case token::EXP_NUMBER: case token::EXP_OPERATION: std::cout << "This shouldn't be here...\n"; err(); break; case token::TOK_EQ: case token::TOK_OP: expression(); break; case token::TOK_SEMI: reduce(); break; case token::TOK_DO: std::cout << "Found do\n"; reduce_blck(); break; default: err(); break;; } } void parser::reduce_blck() { if(_stack.size() == 1) return; struct token *tok = pop(); std::cout << "\n--REDUCING BLOCK--\n"; std::cout << str_token(*tok) << "\n"; struct token *tmp; switch (tok->tok_type) { case token::STM_CJUMP: case token::STM_COMPOUND: case token::STM_ASSIGN: reduce_stm(tok); break; case token::EXP_COMPARE: assert(_stack.top()->tok_type == token::TOK_IF); pop(); tmp = new struct token; tmp->tok_type = token::STM_CJUMP; tmp->rvalue = parse_until_tok_end(); tmp->lvalue = tok; std::cout << str_token(*tmp->lvalue) << "\n"; std::cout << str_token(*tmp) << "\n"; std::cout << "CJUMP 5\n"; push(tmp); break; case token::TOK_NUM: reduce_num(tok); break; case token::TOK_ID: reduce_id(tok); break; case token::EXP_ID: case token::EXP_OPERATION: case token::EXP_NUMBER: // EL SIGUIENTE ES UN OP O UN ASSIGN reduce_exp(tok); break; default: break; } reduce_blck(); } void parser::conditional() { push(_tokens[pos]); pos++; expression(); } void parser::err() { std::cout << "unexpected symbol: " << str_token(*_stack.top()) << '\n'; exit(-1); } struct token* parser::parse_until_tok_end() { std::vector tokens; int depth = 0; while (depth >= 0) { tokens.push_back(_tokens[pos]); if(_tokens[pos]->tok_type == token::TOK_DO) depth++; if(_tokens[pos]->tok_type == token::TOK_END) depth--; pos++; } tokens.pop_back(); parser pars(tokens); std::cout << "NESTED PARSING BEGIN \n"; return pars.parse_tokens(); } parser::~parser() { // free_tree(pop()); }