|  | @@ -1,7 +1,7 @@
 | 
	
		
			
				|  |  |  import { CommonTokenStream, InputStream } from 'antlr4/index';
 | 
	
		
			
				|  |  |  import { SyntaxError } from './SyntaxError';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -export class AnalisadorSintatico {
 | 
	
		
			
				|  |  | +export class IVProgParser {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    constructor (input, lexerClass) {
 | 
	
		
			
				|  |  |      this.lexerClass = lexerClass;
 | 
	
	
		
			
				|  | @@ -9,12 +9,12 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |      this.tokenStream = new CommonTokenStream(this.lexer);
 | 
	
		
			
				|  |  |      this.tokenStream.fill();
 | 
	
		
			
				|  |  |      this.pos = 1;
 | 
	
		
			
				|  |  | -    this.variableTypes = [this.lexerClass.PR_INTEIRO,
 | 
	
		
			
				|  |  | -      this.lexerClass.PR_REAL,
 | 
	
		
			
				|  |  | -      this.lexerClass.PR_LOGICO,
 | 
	
		
			
				|  |  | -      this.lexerClass.PR_CADEIA
 | 
	
		
			
				|  |  | +    this.variableTypes = [this.lexerClass.RK_INTEGER,
 | 
	
		
			
				|  |  | +      this.lexerClass.RK_REAL,
 | 
	
		
			
				|  |  | +      this.lexerClass.RK_LOGIC,
 | 
	
		
			
				|  |  | +      this.lexerClass.RK_STRING
 | 
	
		
			
				|  |  |      ];
 | 
	
		
			
				|  |  | -    this.functionTypes = this.variableTypes.push(this.lexerClass.PR_VAZIO);
 | 
	
		
			
				|  |  | +    this.functionTypes = this.variableTypes.concat(this.lexerClass.RK_VOID);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    parseTree () {
 | 
	
	
		
			
				|  | @@ -37,7 +37,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |      let globalVars = [];
 | 
	
		
			
				|  |  |      let functions = [];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if(this.lexerClass.PR_PROGRAMA === token.type) {
 | 
	
		
			
				|  |  | +    if(this.lexerClass.RK_PROGRAM === token.type) {
 | 
	
		
			
				|  |  |        this.pos++;
 | 
	
		
			
				|  |  |        this.consumeNewLines();
 | 
	
		
			
				|  |  |        this.checkOpenCurly();
 | 
	
	
		
			
				|  | @@ -45,9 +45,9 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |        while(true) {
 | 
	
		
			
				|  |  |          this.consumeNewLines();
 | 
	
		
			
				|  |  |          const token = this.getToken();
 | 
	
		
			
				|  |  | -        if (token.type === this.lexerClass.PR_CONST || token.type === this.lexerClass.ID) {
 | 
	
		
			
				|  |  | +        if (token.type === this.lexerClass.RK_CONST || token.type === this.lexerClass.ID) {
 | 
	
		
			
				|  |  |            globalVars = globalVars.concat(this.parseGlobalVariables());
 | 
	
		
			
				|  |  | -        } else if (token.type === this.lexerClass.PR_FUNCAO) {
 | 
	
		
			
				|  |  | +        } else if (token.type === this.lexerClass.RK_FUNCTION) {
 | 
	
		
			
				|  |  |            functions = functions.concat([]);
 | 
	
		
			
				|  |  |          } else {
 | 
	
		
			
				|  |  |            break;
 | 
	
	
		
			
				|  | @@ -62,20 +62,20 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        return {global: globalVars, functions: functions};
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  | -      throw SyntaxError.createError(this.lexer.literalNames[this.lexerClass.PR_PROGRAMA], token);
 | 
	
		
			
				|  |  | +      throw SyntaxError.createError(this.lexer.literalNames[this.lexerClass.RK_PROGRAM], token);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    checkOpenCurly () {
 | 
	
		
			
				|  |  |      const token = this.getToken();
 | 
	
		
			
				|  |  | -    if(this.lexerClass.ABRE_CHA !== token.type){
 | 
	
		
			
				|  |  | +    if(this.lexerClass.OPEN_CURLY !== token.type){
 | 
	
		
			
				|  |  |        throw SyntaxError.createError('{', token);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    checkCloseCurly () {
 | 
	
		
			
				|  |  |      const token = this.getToken();
 | 
	
		
			
				|  |  | -    if(this.lexerClass.FECHA_CHA !== token.type){
 | 
	
		
			
				|  |  | +    if(this.lexerClass.CLOSE_CURLY !== token.type){
 | 
	
		
			
				|  |  |        throw SyntaxError.createError('}', token);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -90,7 +90,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |    **/
 | 
	
		
			
				|  |  |    checkOpenBrace (attempt = false) {
 | 
	
		
			
				|  |  |      const token = this.getToken();
 | 
	
		
			
				|  |  | -    if(this.lexerClass.ABRE_COL !== token.type){
 | 
	
		
			
				|  |  | +    if(this.lexerClass.OPEN_BRACE !== token.type){
 | 
	
		
			
				|  |  |        if (!attempt) {
 | 
	
		
			
				|  |  |          throw SyntaxError.createError('[', token);
 | 
	
		
			
				|  |  |        } else {
 | 
	
	
		
			
				|  | @@ -102,7 +102,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    checkCloseBrace (attempt = false) {
 | 
	
		
			
				|  |  |      const token = this.getToken();
 | 
	
		
			
				|  |  | -    if(this.lexerClass.FECHA_COL !== token.type){
 | 
	
		
			
				|  |  | +    if(this.lexerClass.CLOSE_BRACE !== token.type){
 | 
	
		
			
				|  |  |        if (!attempt) {
 | 
	
		
			
				|  |  |          throw SyntaxError.createError(']', token);
 | 
	
		
			
				|  |  |        } else {
 | 
	
	
		
			
				|  | @@ -114,7 +114,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    checkOpenParenthesis (attempt = false) {
 | 
	
		
			
				|  |  |      const token = this.getToken();
 | 
	
		
			
				|  |  | -    if(this.lexerClass.ABRE_PAR !== token.type){
 | 
	
		
			
				|  |  | +    if(this.lexerClass.OPEN_PARENTHESIS !== token.type){
 | 
	
		
			
				|  |  |        if (!attempt) {
 | 
	
		
			
				|  |  |          throw SyntaxError.createError('(', token);
 | 
	
		
			
				|  |  |        } else {
 | 
	
	
		
			
				|  | @@ -126,7 +126,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    checkCloseParenthesis (attempt = false) {
 | 
	
		
			
				|  |  |      const token = this.getToken();
 | 
	
		
			
				|  |  | -    if(this.lexerClass.FECHA_PAR !== token.type){
 | 
	
		
			
				|  |  | +    if(this.lexerClass.CLOSE_PARENTHESIS !== token.type){
 | 
	
		
			
				|  |  |        if (!attempt) {
 | 
	
		
			
				|  |  |          throw SyntaxError.createError(')', token);
 | 
	
		
			
				|  |  |        } else {
 | 
	
	
		
			
				|  | @@ -162,7 +162,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |    **/
 | 
	
		
			
				|  |  |    parseHasConst () {
 | 
	
		
			
				|  |  |      const constToken = this.getToken();
 | 
	
		
			
				|  |  | -    if(constToken.type === this.lexerClass.PR_CONST) {
 | 
	
		
			
				|  |  | +    if(constToken.type === this.lexerClass.RK_CONST) {
 | 
	
		
			
				|  |  |        this.pos++;
 | 
	
		
			
				|  |  |        const typeString = this.parseType();
 | 
	
		
			
				|  |  |        return this.parseDeclararion(typeString, true);
 | 
	
	
		
			
				|  | @@ -200,13 +200,13 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      const equalsToken = this.getToken();
 | 
	
		
			
				|  |  | -    if(equalsToken.type === this.lexerClass.ATRIBUICAO) {
 | 
	
		
			
				|  |  | +    if(equalsToken.type === this.lexerClass.EQUAL) {
 | 
	
		
			
				|  |  |        //process Expression(EAnd) => initial != null
 | 
	
		
			
				|  |  |        console.log("= found");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      const commaToken = this.getToken();
 | 
	
		
			
				|  |  | -    if(commaToken.type === this.lexerClass.VIRGULA) {
 | 
	
		
			
				|  |  | +    if(commaToken.type === this.lexerClass.COMMA) {
 | 
	
		
			
				|  |  |        console.log("comma found");
 | 
	
		
			
				|  |  |        this.pos++;
 | 
	
		
			
				|  |  |        return [{
 | 
	
	
		
			
				|  | @@ -248,7 +248,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |    **/
 | 
	
		
			
				|  |  |    getArrayDimension () {
 | 
	
		
			
				|  |  |      const dimToken = this.getToken();
 | 
	
		
			
				|  |  | -    if(dimToken.type === this.lexerClass.INTEIRO) {
 | 
	
		
			
				|  |  | +    if(dimToken.type === this.lexerClass.INTEGER) {
 | 
	
		
			
				|  |  |        //parse as int literal
 | 
	
		
			
				|  |  |        this.pos++;
 | 
	
		
			
				|  |  |        return this.parseIntLiteral(dimToken);
 | 
	
	
		
			
				|  | @@ -311,7 +311,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |    parseFunction () {
 | 
	
		
			
				|  |  |      let formalParams = [];
 | 
	
		
			
				|  |  |      const token = this.getToken();
 | 
	
		
			
				|  |  | -    if(token.type !== this.lexerClass.PR_FUNCAO) {
 | 
	
		
			
				|  |  | +    if(token.type !== this.lexerClass.RK_FUNCTION) {
 | 
	
		
			
				|  |  |        //throw SyntaxError.createError(this.lexer.literalNames[this.lexerClass.PR_FUNCAO], token);
 | 
	
		
			
				|  |  |        return null;
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -367,7 +367,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |        list.push({type: typeString, id: idString, dimensions: dimensions});
 | 
	
		
			
				|  |  |        this.consumeNewLines();
 | 
	
		
			
				|  |  |        const commaToken = this.getToken();
 | 
	
		
			
				|  |  | -      if (commaToken.type !== this.lexerClass.VIRGULA)
 | 
	
		
			
				|  |  | +      if (commaToken.type !== this.lexerClass.COMMA)
 | 
	
		
			
				|  |  |          break;
 | 
	
		
			
				|  |  |        this.pos++;
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -387,19 +387,19 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |      const token = this.getToken();
 | 
	
		
			
				|  |  |      if(token.type === this.lexerClass.ID && isFunction) {
 | 
	
		
			
				|  |  |        return 'void';
 | 
	
		
			
				|  |  | -    } else if (token.type === this.lexerClass.PR_VAZIO && isFunction) {
 | 
	
		
			
				|  |  | +    } else if (token.type === this.lexerClass.RK_VOID && isFunction) {
 | 
	
		
			
				|  |  |        this.pos++;
 | 
	
		
			
				|  |  |        return 'void';
 | 
	
		
			
				|  |  |      } else if (this.isVariableType(token)) {
 | 
	
		
			
				|  |  |        this.pos++;
 | 
	
		
			
				|  |  |        switch(token.type) {
 | 
	
		
			
				|  |  | -        case this.lexerClass.PR_INTEIRO:
 | 
	
		
			
				|  |  | +        case this.lexerClass.RK_INTEGER:
 | 
	
		
			
				|  |  |            return 'int';
 | 
	
		
			
				|  |  | -        case this.lexerClass.PR_LOGICO:
 | 
	
		
			
				|  |  | +        case this.lexerClass.RK_LOGIC:
 | 
	
		
			
				|  |  |            return 'logic';
 | 
	
		
			
				|  |  | -        case this.lexerClass.PR_REAL:
 | 
	
		
			
				|  |  | +        case this.lexerClass.RK_REAL:
 | 
	
		
			
				|  |  |            return 'real';
 | 
	
		
			
				|  |  | -        case this.lexerClass.PR_CADEIA:
 | 
	
		
			
				|  |  | +        case this.lexerClass.RK_STRING:
 | 
	
		
			
				|  |  |            return 'string';
 | 
	
		
			
				|  |  |          default:
 | 
	
		
			
				|  |  |            break;
 | 
	
	
		
			
				|  | @@ -411,6 +411,7 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    parseFunctionBody () {
 | 
	
		
			
				|  |  |      let variablesDecl = [];
 | 
	
		
			
				|  |  | +    let commands = [];
 | 
	
		
			
				|  |  |      this.checkOpenCurly();
 | 
	
		
			
				|  |  |      this.pos++;
 | 
	
		
			
				|  |  |      while(true) {
 | 
	
	
		
			
				|  | @@ -421,18 +422,103 @@ export class AnalisadorSintatico {
 | 
	
		
			
				|  |  |          variablesDecl = variablesDecl.concat(this.parseDeclararion(token));
 | 
	
		
			
				|  |  |        } else if (token.type === this.lexerClass.ID) {
 | 
	
		
			
				|  |  |          this.pos++;
 | 
	
		
			
				|  |  | +        this.consumeNewLines();
 | 
	
		
			
				|  |  |          const equalOrParenthesis = this.getToken();
 | 
	
		
			
				|  |  | -        if (equalOrParenthesis.type === this.lexerClass.ATRIBUICAO) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        } else if (equalOrParenthesis.type === this.lexerClass.ABRE_PAR) {
 | 
	
		
			
				|  |  | +        if (equalOrParenthesis.type === this.lexerClass.EQUAL) {
 | 
	
		
			
				|  |  | +          this.pos++
 | 
	
		
			
				|  |  | +          // parse Expression (EAnd)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        } else if (equalOrParenthesis.type === this.lexerClass.OPEN_PARENTHESIS) {
 | 
	
		
			
				|  |  | +          // parse function call => ID '(' actual parameters list ')'
 | 
	
		
			
				|  |  | +          // actual parameter => EAnd
 | 
	
		
			
				|  |  |          } else {
 | 
	
		
			
				|  |  |            throw SyntaxError.createError("= or (", equalOrParenthesis);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +      } else if (token.type === this.lexerClass.RK_RETURN) {
 | 
	
		
			
				|  |  | +        // parse EAnd
 | 
	
		
			
				|  |  | +      } else if (token.type === this.lexerClass.RK_WHILE) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      } else if (token.type === this.lexerClass.RK_FOR) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      } else if (token.type === this.lexerClass.RK_BREAK) {
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +      } else if (token.type === this.lexerClass.RK_SWITCH) {
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +      } else if (token.type === this.lexerClass.RK_DO) {
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +      } else if (token.type === this.lexerClass.RK_IF) {
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    this.consumeNewLines();
 | 
	
		
			
				|  |  | +    this.checkCloseCurly();
 | 
	
		
			
				|  |  | +    return {variables: variablesDecl, commands: commands};
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /*
 | 
	
		
			
				|  |  | +  * Parses an Expression following the structure:
 | 
	
		
			
				|  |  | +  *
 | 
	
		
			
				|  |  | +  * EAnd  => EOR ( 'and' EAnd)? #expression and
 | 
	
		
			
				|  |  | +  *
 | 
	
		
			
				|  |  | +  * EOR   => ENot ('or' EAnd)? #expression or
 | 
	
		
			
				|  |  | +  *
 | 
	
		
			
				|  |  | +  * ENot  => 'not'? ER #expression not
 | 
	
		
			
				|  |  | +  *
 | 
	
		
			
				|  |  | +  * ER    => E ((>=, <=, ==, >, <) E)? #expression relational
 | 
	
		
			
				|  |  | +  *
 | 
	
		
			
				|  |  | +  * E     => factor ((+, -) E)? #expression
 | 
	
		
			
				|  |  | +  *
 | 
	
		
			
				|  |  | +  * factor=> term ((*, /, %) factor)?
 | 
	
		
			
				|  |  | +  *
 | 
	
		
			
				|  |  | +  * term  => literal || arrayAccess || FuncCall || ID || '('EAnd')'
 | 
	
		
			
				|  |  | +  **/
 | 
	
		
			
				|  |  | +  parseExpressionOR () {
 | 
	
		
			
				|  |  | +    const andEpxression1 = this.parseExpressionAND();
 | 
	
		
			
				|  |  | +    let andEpxression2 = null;
 | 
	
		
			
				|  |  | +    let or = null;
 | 
	
		
			
				|  |  | +    const maybeAnd = this.getToken();
 | 
	
		
			
				|  |  | +    if (maybeAnd.type === this.lexerClass.OR_OPERATOR) {
 | 
	
		
			
				|  |  | +      this.pos++;
 | 
	
		
			
				|  |  | +      or = 'or';
 | 
	
		
			
				|  |  | +      andEpxression2 = this.parseExpressionAND();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return {left: andEpxression1, op:or, right: andEpxression2};
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  parseExpressionAND () {
 | 
	
		
			
				|  |  | +    const eNot1 = this.parseExpressionNot();
 | 
	
		
			
				|  |  | +    let and = null;
 | 
	
		
			
				|  |  | +    let eNot2 = null;
 | 
	
		
			
				|  |  | +    const andToken = this.getToken();
 | 
	
		
			
				|  |  | +    if (andToken.type === this.lexerClass.AND_OPERATOR) {
 | 
	
		
			
				|  |  | +      this.pos++;
 | 
	
		
			
				|  |  | +      and = 'and';
 | 
	
		
			
				|  |  | +      eNot2 = this.parseExpressionNot();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return {left: eNot1, op: or, right: eNot2};
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  parseExpressionNot () {
 | 
	
		
			
				|  |  | +    this.consumeNewLines();
 | 
	
		
			
				|  |  | +    let not = null;
 | 
	
		
			
				|  |  | +    const notToken = this.getToken();
 | 
	
		
			
				|  |  | +    if (notToken.type === this.lexerClass.NOT_OPERATOR) {
 | 
	
		
			
				|  |  | +      this.pos++;
 | 
	
		
			
				|  |  | +      not = 'not';
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const eRel = this.parseExpressionRel();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return {left: null, op: not, right: eRel};
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    getTypesAsString (isFunction = false) {
 | 
	
		
			
				|  |  |      const types = isFunction ? this.functionTypes : this.variableTypes;
 | 
	
		
			
				|  |  |      return types.map( x => this.lexer.literalNames[x])
 |