Initial commit

This commit is contained in:
fsan 2021-10-01 11:20:03 -03:00
commit 3f2ed01095
9 changed files with 509 additions and 0 deletions

BIN
a.out Executable file

Binary file not shown.

2
build.sh Normal file
View File

@ -0,0 +1,2 @@
#!/bin/sh
g++ -g main.cpp interpreter.cpp lexer.cpp parser.cpp

11
info Normal file
View File

@ -0,0 +1,11 @@
lenguaje orga-straight-line
prgm -> stms
stms -> stm; stm (s = s1;s2) -> compound
stms -> stms; stm -> compound
stm -> id = exp (asignacion) -> assign
exp -> numero (literal) -> number
exp -> id (idExp) -> id
exp -> exp op exp (operacion) -> opexp
op -> + (suma) -> plus
op -> - (resta) -> minus

39
interpreter.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "orga-comp.h"
void
interpreter::evalSTM(struct token stm) {
switch (stm.t) {
case token::STM_ASSIGN:
table[stm.lvalue->value] = evalEXP(*stm.rvalue);
std::cout << stm.lvalue->value << " igual a " << table[stm.lvalue->value] << '\n';
break;
case token::STM_COMPOUND:
evalSTM(*stm.lvalue);
evalSTM(*stm.rvalue);
break;
default:
std::cout << "ERROR \n";
exit(-1);
break;
}
}
int
interpreter::evalEXP(struct token exp) {
switch (exp.t) {
case token::EXP_NUMBER:
return std::stoi(exp.value);
break;
case token::EXP_ID:
return table[exp.value];
break;
case token::EXP_OPERATION:
if(exp.value == "+") return evalEXP(*exp.lvalue) + evalEXP(*exp.rvalue);
if(exp.value == "-") return evalEXP(*exp.lvalue) - evalEXP(*exp.rvalue);
break;
default:
std::cout << "ERROR \n";
exit(-1);
break;
}
}

87
lexer.cpp Normal file
View File

@ -0,0 +1,87 @@
#include "orga-comp.h"
std::vector<struct token>
lexer::lex_file(std::string filename) {
//leer un char -> ver que es -> pasar a un estado
// [a-z] -> id
// [0-9] -> num
// +- -> op
// = -> assign
// ; -> semi
std::ifstream file("tst.cfran", std::ifstream::in);
bool id = false;
bool num = false;
std::string *value = new std::string();
char c;
while(file.get(c)) {
switch (c) {
case 'a' ... 'z':
case 'A' ... 'Z':
if(!num) {
id = true;
*value += c;
} else {
std::cout << "Invalid identifier " << value << c << '\n';
exit(-1);
}
//ID o condicional
break;
case '0' ... '9':
if(!id) num = true;
*value += c;
//NUM o ID
break;
case '+':
case '-':
if(id) add_token(token::TOK_ID, *value);
if(num) add_token(token::TOK_NUM, *value);
value = new std::string();
*value += c;
add_token(token::TOK_OP, *value);
id = false;
num = false;
value = new std::string();
//OP
break;
case '=':
if(id) add_token(token::TOK_ID, *value);
if(num) add_token(token::TOK_NUM, *value);
add_token(token::TOK_ASSIGN, "");
id = false;
num = false;
value = new std::string();
break;
case ';':
if(id) add_token(token::TOK_ID, *value);
if(num) add_token(token::TOK_NUM, *value);
add_token(token::TOK_SEMI, "");
id = false;
num = false;
value = new std::string();
//STM END
break;
case ' ':
if(id) add_token(token::TOK_ID, *value);
if(num) add_token(token::TOK_NUM, *value);
id = false;
num = false;
value = new std::string();
default:
break;
}
}
print_tokens(_tokens);
return _tokens;
}
void
lexer::add_token(token::type type, std::string value) {
struct token *token = new struct token;
token->t = type;
token->value = value;
_tokens.push_back(*token);
}

81
main.cpp Normal file
View File

@ -0,0 +1,81 @@
#include "orga-comp.h"
#include <iostream>
int
main(){
// lex -> parse -> analisis semantico
// realizar un interprete
// interpretar a = 2 + 2
struct token test;
test.t = test.STM_ASSIGN;
struct token rexp;
rexp.t = token::EXP_OPERATION;
struct token lnum;
lnum.t = test.EXP_NUMBER;
lnum.value = "2";
struct token rnum;
rnum.t = test.EXP_NUMBER;
rnum.value = "2";
struct token lexp;
lexp.t = token::EXP_ID;
lexp.value = "a";
rexp.lvalue = &lnum;
rexp.rvalue = &rnum;
test.rvalue = &rexp;
test.lvalue = &lexp;
interpreter *inter = new interpreter();
inter->evalSTM(test);
lexer lex;
parser parser(lex.lex_file("tst.cfran"));
struct token end = parser.parse_tokens();
std::cout << "\n-----------------------\n";
std::cout << "EVALUATING RESULTING TREE:\n";
inter->evalSTM(end);
return 1;
}
void
print_tokens(std::vector<struct token> tokens){
for(struct token tok : tokens) {
std::cout << str_token(tok) << " ";
}
std::cout << '\n';
}
std::string
str_token(struct token tok){
switch (tok.t) {
case token::TOK_ID:
return "ID(" + tok.value + ")";
case token::TOK_NUM:
return "NUM(" + tok.value + ")";
case token::TOK_OP:
return "OP(" + tok.value + ")";
case token::TOK_ASSIGN:
return "ASSIGN ";
case token::TOK_SEMI:
return "SEMI ";
case token::STM_ASSIGN:
return "STM_ASSIGN( " + str_token(*tok.lvalue) + ", " + str_token(*tok.rvalue) + ")";
case token::STM_COMPOUND:
return "STM_COMPOUND( " + str_token(*tok.lvalue) + ", " + str_token(*tok.rvalue) + ")";
case token::EXP_NUMBER:
return "EXP_NUMBER(" + tok.value + ")";
case token::EXP_OPERATION:
return "EXP_OPERATION( " + str_token(*tok.lvalue) + " " + tok.value + " " + str_token(*tok.rvalue) +")";
case token::EXP_ID:
return "EXP_ID ";
default:
return "SOMETHING";
}
}

80
orga-comp.h Normal file
View File

@ -0,0 +1,80 @@
#include <bits/types/FILE.h>
#include <cstddef>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <map>
#include <list>
#include <stack>
#include <string>
#include <vector>
#include <assert.h>
struct token {
enum type {
TOK_ID,
TOK_NUM,
TOK_OP,
TOK_ASSIGN,
TOK_DO,
TOK_END,
TOK_LPAREN,
TOK_RPAREN,
TOK_COMMA,
TOK_SEMI,
STM_ASSIGN,
STM_COMPOUND,
EXP_NUMBER,
EXP_ID,
EXP_OPERATION
};
type t;
std::string value;
struct token *lvalue;
struct token *rvalue;
};
void print_tokens(std::vector<struct token> tokens);
std::string str_token(struct token tok);
class interpreter {
public:
void evalSTM(struct token stm);
int evalEXP(struct token exp);
private:
std::map<std::string, int> table;
};
class lexer {
public:
std::vector<struct token> lex_file(std::string filename);
private:
std::vector<struct token> _tokens;
void add_token(token::type, std::string value);
};
class parser {
public:
parser(std::vector<struct token> tokens);
struct token parse_tokens();
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 statement(); //pops an statement into stack
void expression(); //pops an expression into stack
void err();
struct token pop();
std::vector<struct token> _tokens;
std::stack<struct token> _stack;
size_t pos;
};
class translate {
};

203
parser.cpp Normal file
View File

@ -0,0 +1,203 @@
#include "orga-comp.h"
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().t) {
case token::TOK_ID:
std::cout << "STATEMENT\n";
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.
}
parser::parser(std::vector<struct token> tokens) {
_tokens = tokens;
pos = 0;
}
void
parser::reduce() {
if(_stack.size() == 1) return;
struct token tok = pop();
std::cout << str_token(tok) << " ";
switch (tok.t) {
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::TOK_ID:
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.t) {
case token::STM_ASSIGN:
case token::STM_COMPOUND:
tmp = new struct token;
tmp->t = token::STM_COMPOUND;
tmp->rvalue = new struct token;
*tmp->rvalue = stm;
tmp->lvalue = new struct token;
*tmp->lvalue = tok;
_stack.push(*tmp);
std::cout << "CHAD STM REDUCER " << str_token(*tmp);
break;
default:
err();
break;
}
}
void
parser::reduce_id(struct token id) {
struct token *tmp = new struct token;
tmp->t = token::EXP_ID;
tmp->value = id.value;
_stack.push(*tmp);
}
void
parser::reduce_num(struct token num) {
struct token *tmp = new struct token;
tmp->t = token::EXP_NUMBER;
tmp->value = num.value;
_stack.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.t) {
case token::TOK_ASSIGN:
std::cout << "assign found\n";
if(_stack.top().t != token::TOK_ID) err();
std::cout << str_token(_stack.top()) << "\n";
stm = new struct token;
stm->t = token::STM_ASSIGN;
stm->rvalue = new struct token;
*stm->rvalue = exp;
stm->lvalue = new struct token;
*stm->lvalue = pop();
_stack.push(*stm);
break;
case token::TOK_OP:
if(_stack.top().t == token::TOK_NUM) {
reduce_num(pop());
}
if(_stack.top().t == token::TOK_ID) {
reduce_id(pop());
}
stm = new struct token;
stm->t = 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);
//reduce_exp(pop());
break;
default: err();
}
}
struct token
parser::pop() {
struct token tmp = _stack.top();
_stack.pop();
return tmp;
}
void
parser::statement() {
_stack.push(_tokens[pos]);
pos++;
assert(_stack.top().t == token::TOK_ASSIGN);
expression();
}
void
parser::expression() {
_stack.push(_tokens[pos]);
pos++;
std::cout << "POS: " << pos << '\n';
switch (_stack.top().t) {
// case token::EXP_NUMBER:
// case token::EXP_ID:
case token::TOK_ID:
case token::TOK_NUM:
expression();
break;
case token::EXP_OPERATION:
std::cout << "Nested operations not supported\n";
err();
break;
case token::TOK_OP:
expression();
break;
case token::TOK_SEMI:
std::cout << "REDUCE\n";
reduce();
break;
default:
err();
break;;
}
}
void
parser::err() {
std::cout
<< "unexpected symbol: "
<< str_token(_stack.top())
<< '\n';
exit(-1);
}

6
tst.cfran Normal file
View File

@ -0,0 +1,6 @@
a = 2 + 2;
j = 2 + 1;
h = 2 + 1;
b = 4 + 8;
p = a + 1;
c = 2 - 1;