2021-10-01 14:20:03 +00:00
|
|
|
#include "orga-comp.h"
|
2021-10-05 05:29:55 +00:00
|
|
|
#include <iostream>
|
2021-10-01 14:20:03 +00:00
|
|
|
|
2021-10-05 05:29:55 +00:00
|
|
|
struct token *
|
2021-10-01 14:20:03 +00:00
|
|
|
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);
|
2021-10-05 05:29:55 +00:00
|
|
|
switch (_stack.top()->tok_type) {
|
2021-10-01 14:20:03 +00:00
|
|
|
case token::TOK_ID:
|
|
|
|
statement();
|
|
|
|
break;
|
|
|
|
case token::STM_COMPOUND:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
err();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return parse_tokens();
|
|
|
|
}
|
|
|
|
/*std::cout << "ESTADO FINAL DEL STACK:\n";
|
|
|
|
for(int i = 0; i < _stack.size(); i++) {
|
|
|
|
std::cout << str_token(pop()) << " ";
|
|
|
|
}*/
|
|
|
|
|
|
|
|
return _stack.top();
|
|
|
|
//check if reduce is possible, if it is reduce.
|
|
|
|
}
|
|
|
|
|
2021-10-05 05:29:55 +00:00
|
|
|
parser::parser(std::vector<struct token*> tokens) {
|
2021-10-01 14:20:03 +00:00
|
|
|
_tokens = tokens;
|
|
|
|
pos = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
parser::reduce() {
|
|
|
|
if(_stack.size() == 1) return;
|
2021-10-05 05:29:55 +00:00
|
|
|
struct token *tok = pop();
|
2021-10-01 14:20:03 +00:00
|
|
|
|
2021-10-06 14:44:39 +00:00
|
|
|
// std::cout << str_token(*tok) << " ";
|
2021-10-05 05:29:55 +00:00
|
|
|
switch (tok->tok_type) {
|
2021-10-01 14:20:03 +00:00
|
|
|
case token::TOK_NUM:
|
2021-10-06 14:44:39 +00:00
|
|
|
// std::cout << "reduzco numero\n";
|
2021-10-01 14:20:03 +00:00
|
|
|
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::TOK_ID:
|
|
|
|
|
|
|
|
case token::STM_ASSIGN:
|
|
|
|
reduce_stm(tok);
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
reduce();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-05 05:29:55 +00:00
|
|
|
parser::reduce_stm(struct token *stm) {
|
|
|
|
struct token *tok = pop();
|
2021-10-01 14:20:03 +00:00
|
|
|
struct token *tmp;
|
2021-10-05 05:29:55 +00:00
|
|
|
switch (tok->tok_type) {
|
2021-10-01 14:20:03 +00:00
|
|
|
case token::STM_ASSIGN:
|
|
|
|
case token::STM_COMPOUND:
|
|
|
|
tmp = new struct token;
|
2021-10-05 02:28:08 +00:00
|
|
|
tmp->tok_type = token::STM_COMPOUND;
|
2021-10-05 05:29:55 +00:00
|
|
|
tmp->rvalue = stm;
|
|
|
|
tmp->lvalue = tok;
|
|
|
|
push(tmp);
|
2021-10-06 14:44:39 +00:00
|
|
|
// std::cout << "CHAD STM REDUCER " << str_token(*tmp);
|
2021-10-01 14:20:03 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
err();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-05 05:29:55 +00:00
|
|
|
parser::reduce_id(struct token *id) {
|
2021-10-01 14:20:03 +00:00
|
|
|
struct token *tmp = new struct token;
|
2021-10-05 02:28:08 +00:00
|
|
|
tmp->tok_type = token::EXP_ID;
|
2021-10-05 05:29:55 +00:00
|
|
|
tmp->value = id->value;
|
|
|
|
push(tmp);
|
2021-10-01 14:20:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-05 05:29:55 +00:00
|
|
|
parser::reduce_num(struct token *num) {
|
2021-10-01 14:20:03 +00:00
|
|
|
struct token *tmp = new struct token;
|
2021-10-05 02:28:08 +00:00
|
|
|
tmp->tok_type = token::EXP_NUMBER;
|
2021-10-05 05:29:55 +00:00
|
|
|
tmp->value = num->value;
|
|
|
|
push(tmp);
|
2021-10-01 14:20:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-05 05:29:55 +00:00
|
|
|
parser::reduce_exp(struct token *exp) {
|
2021-10-06 14:44:39 +00:00
|
|
|
// std::cout << "reducing exp: " << str_token(*exp) << "\n";
|
2021-10-05 05:29:55 +00:00
|
|
|
struct token *modifier = pop();
|
2021-10-01 14:20:03 +00:00
|
|
|
struct token *tmp;
|
|
|
|
struct token *stm;
|
2021-10-05 05:29:55 +00:00
|
|
|
switch (modifier->tok_type) {
|
2021-10-01 14:20:03 +00:00
|
|
|
case token::TOK_ASSIGN:
|
2021-10-06 14:44:39 +00:00
|
|
|
// std::cout << "assign found\n";
|
2021-10-05 05:29:55 +00:00
|
|
|
if(_stack.top()->tok_type != token::TOK_ID) err();
|
2021-10-06 14:44:39 +00:00
|
|
|
// std::cout << str_token(*_stack.top()) << "\n";
|
2021-10-01 14:20:03 +00:00
|
|
|
stm = new struct token;
|
2021-10-05 02:28:08 +00:00
|
|
|
stm->tok_type = token::STM_ASSIGN;
|
2021-10-05 05:29:55 +00:00
|
|
|
stm->rvalue = exp;
|
|
|
|
stm->value = pop()->value;
|
|
|
|
push(stm);
|
2021-10-01 14:20:03 +00:00
|
|
|
break;
|
|
|
|
case token::TOK_OP:
|
2021-10-05 05:29:55 +00:00
|
|
|
if(_stack.top()->tok_type == token::TOK_NUM) {
|
2021-10-01 14:20:03 +00:00
|
|
|
reduce_num(pop());
|
|
|
|
}
|
2021-10-05 05:29:55 +00:00
|
|
|
if(_stack.top()->tok_type == token::TOK_ID) {
|
2021-10-01 14:20:03 +00:00
|
|
|
reduce_id(pop());
|
|
|
|
}
|
|
|
|
stm = new struct token;
|
2021-10-05 02:28:08 +00:00
|
|
|
stm->tok_type = token::EXP_OPERATION;
|
2021-10-05 05:29:55 +00:00
|
|
|
stm->value = modifier->value;
|
|
|
|
stm->rvalue = exp;
|
|
|
|
stm->lvalue = pop();
|
|
|
|
push(stm);
|
2021-10-01 14:20:03 +00:00
|
|
|
//reduce_exp(pop());
|
|
|
|
break;
|
|
|
|
default: err();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-05 05:29:55 +00:00
|
|
|
struct token *
|
2021-10-01 14:20:03 +00:00
|
|
|
parser::pop() {
|
2021-10-05 05:29:55 +00:00
|
|
|
struct token *tmp = _stack.top();
|
2021-10-01 14:20:03 +00:00
|
|
|
_stack.pop();
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2021-10-05 05:29:55 +00:00
|
|
|
void
|
|
|
|
parser::push(struct token *tok) {
|
|
|
|
_stack.push(tok);
|
|
|
|
}
|
|
|
|
|
2021-10-01 14:20:03 +00:00
|
|
|
void
|
|
|
|
parser::statement() {
|
|
|
|
_stack.push(_tokens[pos]);
|
|
|
|
pos++;
|
2021-10-05 05:29:55 +00:00
|
|
|
assert(_stack.top()->tok_type == token::TOK_ASSIGN);
|
2021-10-01 14:20:03 +00:00
|
|
|
expression();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
parser::expression() {
|
|
|
|
_stack.push(_tokens[pos]);
|
|
|
|
pos++;
|
2021-10-06 14:44:39 +00:00
|
|
|
// std::cout << "POS: " << pos << '\n';
|
2021-10-05 05:29:55 +00:00
|
|
|
switch (_stack.top()->tok_type) {
|
2021-10-01 14:20:03 +00:00
|
|
|
// case token::EXP_NUMBER:
|
|
|
|
// case token::EXP_ID:
|
|
|
|
case token::TOK_ID:
|
|
|
|
case token::TOK_NUM:
|
|
|
|
expression();
|
|
|
|
break;
|
|
|
|
case token::EXP_OPERATION:
|
2021-10-06 14:44:39 +00:00
|
|
|
// std::cout << "Nested operations not supported\n";
|
2021-10-01 14:20:03 +00:00
|
|
|
err();
|
|
|
|
break;
|
|
|
|
case token::TOK_OP:
|
|
|
|
expression();
|
|
|
|
break;
|
|
|
|
case token::TOK_SEMI:
|
2021-10-06 14:44:39 +00:00
|
|
|
// std::cout << "REDUCE\n";
|
2021-10-01 14:20:03 +00:00
|
|
|
reduce();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
err();
|
|
|
|
break;;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
parser::err() {
|
|
|
|
std::cout
|
|
|
|
<< "unexpected symbol: "
|
2021-10-05 05:29:55 +00:00
|
|
|
<< str_token(*_stack.top())
|
2021-10-01 14:20:03 +00:00
|
|
|
<< '\n';
|
|
|
|
exit(-1);
|
|
|
|
}
|
2021-10-05 05:29:55 +00:00
|
|
|
|
|
|
|
parser::~parser(){
|
|
|
|
free_tree(pop());
|
|
|
|
// while (_stack.size() > 0) {
|
|
|
|
// delete pop();
|
|
|
|
// }
|
|
|
|
}
|