-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
1,636 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
Grammar lsbasi; | ||
|
||
expr | ||
: term (('-' | '+') term ) * | ||
; | ||
|
||
term | ||
: factor (('*' | '/' | 'DIV' ) factor ) * | ||
; | ||
|
||
factor | ||
: '+' factor | ||
| '-' factor | ||
| NUM | ||
| ID | ||
| '(' expr ')' | ||
; | ||
|
||
assignment_statement | ||
: ID ':=' expr | ||
; | ||
|
||
empty: | ||
; | ||
|
||
statement | ||
: assignment_statement | ||
| compound_statement | ||
| empty | ||
; | ||
|
||
program | ||
: 'PROGRAM' ID ';' block '.' | ||
; | ||
|
||
block | ||
: declarations compound_statement | ||
; | ||
|
||
declarations | ||
: 'VAR' (variable_declaration ';')+ | ||
| empty | ||
; | ||
|
||
variable_declaration | ||
: ID (',' ID)* ':' TYPE | ||
; | ||
|
||
compound_statement | ||
: 'BEGIN' statement_list 'END' | ||
; | ||
|
||
statement_list | ||
: statement | ||
| statement ';' statement_list | ||
; | ||
|
||
ID | ||
: "[a-zA-Z][a-zA-Z0-9]*" | ||
; | ||
|
||
NUM | ||
: "[0-9]+(.[0-9]+)?" | ||
; | ||
|
||
TYPE | ||
: "INTEGER" | ||
| "REAL" | ||
; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
#include <string> | ||
#include <cctype> | ||
#include <stdexcept> | ||
#include <iostream> | ||
#include <sstream> | ||
#include <map> | ||
|
||
namespace lsbasi { | ||
|
||
class Interpreter: public VisitorInterpreter { | ||
|
||
AST *ast; | ||
std::map<std::string, float> symbols; | ||
float dispatcher(AST *node){ | ||
return node->handler(this); | ||
} | ||
|
||
float visit(Assign * node){ | ||
std::string var = (static_cast<Id *>(node->id))->value; | ||
float value = dispatcher(node->expr); | ||
symbols[var] = value; | ||
return value; | ||
} | ||
|
||
float visit(Id * node){ | ||
std::stringstream error; | ||
std::string var = node->value; | ||
if (symbols.count(var)) | ||
return symbols[var]; | ||
else{ | ||
error << "Undefined variable => " << var; | ||
throw std::runtime_error(error.str()); | ||
} | ||
} | ||
|
||
float visit(Num *node){ | ||
return node->value; | ||
} | ||
|
||
float visit(BinOp *node){ | ||
float ret = 0; | ||
|
||
switch(node->token->type){ | ||
case Token::_PLUS: | ||
ret = dispatcher(node->left) + dispatcher(node->right); | ||
break; | ||
case Token::_MINUS: | ||
ret = dispatcher(node->left) - dispatcher(node->right); | ||
break; | ||
case Token::_MUL: | ||
ret = dispatcher(node->left) * dispatcher(node->right); | ||
break; | ||
case Token::_INT_DIV: | ||
ret = int(dispatcher(node->left) / dispatcher(node->right)); | ||
break; | ||
case Token::_REAL_DIV: | ||
ret = dispatcher(node->left) / dispatcher(node->right); | ||
break; | ||
} | ||
return ret; | ||
} | ||
|
||
float visit(UnaryOp *node){ | ||
float ret = 0; | ||
switch(node->token->type){ | ||
case Token::_PLUS: | ||
ret = (+1) * dispatcher(node->fact); | ||
break; | ||
case Token::_MINUS: | ||
ret = (-1) * dispatcher(node->fact); | ||
break; | ||
} | ||
return ret; | ||
} | ||
|
||
float visit(Empty *node){ | ||
return 0; | ||
} | ||
|
||
float visit(StatementList *node){ | ||
float ret = 0; | ||
std::vector<AST*>::iterator begin = node->statements.begin(); | ||
std::vector<AST*>::iterator end = node->statements.end(); | ||
for (std::vector<AST*>::iterator it = begin; it != end; ++it) | ||
ret = dispatcher(*it); | ||
return ret; | ||
} | ||
|
||
float visit(Program *node){ | ||
float ret = 0; | ||
//dispatcher(node->id); | ||
dispatcher(node->bloque); | ||
return ret; | ||
} | ||
|
||
float visit(Block *node){ | ||
float ret = 0; | ||
dispatcher(node->declarations); | ||
dispatcher(node->compound_statement); | ||
return ret; | ||
} | ||
|
||
float visit(DecList *node){ | ||
float ret = 0; | ||
return ret; | ||
} | ||
|
||
float visit(Type *node){ | ||
float ret = 0; | ||
return ret; | ||
} | ||
|
||
float visit(VarDecl *node){ | ||
float ret = 0; | ||
return ret; | ||
} | ||
|
||
public: | ||
|
||
std::string environment(){ | ||
std::stringstream ss; | ||
std::string sep = ""; | ||
ss << "{"; | ||
for (std::map<std::string, float>::iterator it=symbols.begin(); it!=symbols.end(); ++it){ | ||
ss << sep << it->first << " => " << it->second; | ||
sep = ","; | ||
} | ||
ss << "}"; | ||
return ss.str(); | ||
} | ||
|
||
Interpreter(AST * ast): ast(ast){} | ||
float interpret (){ | ||
return dispatcher(ast); | ||
} | ||
}; | ||
}; |
Oops, something went wrong.