def visitListTypeExp(self, listTypeExp): #print('visitListTypeExp') variaveis = listTypeExp.IdentifierList.accept(self) tipo = st.getNewType(listTypeExp.Type) for indice in range(len(variaveis)): if (st.getBindable(variaveis[indice]) == None): st.addVar(variaveis[indice], tipo) else: listTypeExp.accept(self.printer) print('\n\t[ERRO]:', variaveis[indice], 'redefinida neste bloco') expressao = listTypeExp.ExpressionList.accept(self) if (type(expressao) is not list): if (expressao in st.TiposPrimitivos and expressao != tipo): listTypeExp.accept(self.printer) print( '\n\t[ERRO]: Atribuicao nao compativel com o tipo declarado' ) elif (expressao != tipo): expressao = st.getBindable(expressao) if (None == expressao or expressao[st.TYPE] != tipo): listTypeExp.accept(self.printer) print( '\n\t[ERRO]: Atribuicao nao compativel com o tipo declarado' ) else: for ind in range(len(expressao)): if (expressao[ind] != tipo): listTypeExp.accept(self.printer) print('\n\t[ERRO]: Atribuicao nao compativel') break
def visitCompIfElse(self, compIfElse): #print('visitCompIfElse') st.beginScope(st.IF) compIfElse.Expression.accept(self) compIfElse.Block.accept(self) st.varCheck(st.endScope()) compIfElse.IfStmt.accept(self)
def visitClassicVarSpec(self, classicVarSpec): #print('visitClassicVarSpec') variaveis = classicVarSpec.IdentifierList.accept(self) tipo = classicVarSpec.Type tipo = st.getNewType(tipo) if (tipo == None): classicVarSpec.accept(self.printer) print('\n\t[ERRO] Tipo indefinido') for k in range(len(variaveis)): if (st.getBindable(variaveis[k]) == None): st.addVar(variaveis[k], tipo) else: classicVarSpec.accept(self.printer) print('\n\t[Erro]:', variaveis[k], 'redefinida neste bloco') expressao = classicVarSpec.ExpressionList.accept(self) if (type(expressao) != type([])): if (expressao != tipo): classicVarSpec.accept(self.printer) print( '\n\t[Erro]: Atribuicao nao compativel com o tipo declarado' ) else: for i in range(len(expressao)): if (expressao[i] != tipo): classicVarSpec.accept(self.printer) print( '\n\t[Erro]: Atribuicao nao compativel com o tipo declarado' ) break
def visitExprSwitch(self, exprSwitch): #print('visitExprSwitch') st.beginScope(st.SWITCH) tipo = exprSwitch.switchStmt_Head.accept(self) st.symbolTable[-1][st.SWITCHTYPE] = tipo exprSwitch.switchStmt_Body.accept(self) st.varCheck(st.endScope())
def visitExpressionDiferente(self, expressionDiferente): #print('visitExpressionDiferente') tipoExp1 = expressionDiferente.Expr2.accept(self) tipoExp2 = expressionDiferente.Expr3.accept(self) tipoExp1 = st.getNewType(tipoExp1) tipoExp2 = st.getNewType(tipoExp2) if (tipoExp1 not in st.TiposPrimitivos): tipoExp1 = st.getBindable(tipoExp1) if (tipoExp1 != None): tipoExp1 = tipoExp1[st.TYPE] if (tipoExp2 not in st.TiposPrimitivos): tipoExp2 = st.getBindable(tipoExp1) if (tipoExp2 != None): tipoExp2 = tipoExp2[st.TYPE] c = coercion(tipoExp1, tipoExp2) if (c == None): expressionDiferente.accept(self.printer) print('\n\t[Erro]: Comparação invalida. A expressao ', end='') expressionDiferente.Expr2.accept(self.printer) print(' eh do tipo', tipoExp1, 'enquanto a expressao ', end='') expressionDiferente.Expr3.accept(self.printer) print(' eh do tipo', tipoExp2, 'quando deveriam ser do mesmo tipo\n') return c
def visitDefinirShortVar(self, shortVar): #print('visitShortVarDecl') variaveis = shortVar.IdentifierList.accept(self) tipos = shortVar.ExpressionList.accept(self) if (type(variaveis) is list and type(tipos) is list): if (len(variaveis) == len(tipos)): for k in range(len(variaveis)): if (variaveis[k] in lex.reserved): shortVar.accept(self.printer) print('\n\t[Erro]: Declaracao invalida') else: for k in range(len(variaveis)): if (tipos[k] in st.TiposPrimitivos): st.addVar(variaveis[k], tipos[k]) else: shortVar.accept(self.printer) print('\n\t[Erro]: Declaracao invalida') else: shortVar.accept(self.printer) print('\n\t[Erro]: Declaracao invalida') elif (type(variaveis) is list): shortVar.accept(self.printer) print('\n\t[Erro]: Declaracao invalida') elif (variaveis in lex.reserved): shortVar.accept(self.printer) print('\n\t[Erro]: Declaracao invalida') elif (tipos in st.TiposPrimitivos): st.addVar(variaveis, tipos) else: shortVar.accept(self.printer) print('\n\t[Erro]: Declaracao invalida')
def visitIfElse(self, ifElse): #print('visitIfElse') st.beginScope(st.IF) ifElse.Expression.accept(self) ifElse.Block.accept(self) st.varCheck(st.endScope()) st.beginScope(st.ELSE) ifElse.Block1.accept(self) st.varCheck(st.endScope())
def visitSpecType(self, specType): #print('visitSpecType') identifier = specType.ID tipo = st.getNewType(specType.Type) if (tipo == None): specType.accept(self.printer) print('\n\t[ERRO] Tipo indefinido') st.addNewType(identifier, tipo)
def visitSpecVar(self, specVar): #print('visitSpecVar') variaveis = specVar.IdentifierList.accept(self) tipo = st.getNewType(specVar.Type) if (tipo == None): specVar.accept(self.printer) print('\n\t[ERRO] Tipo indefinido') for k in range(len(variaveis)): st.addVar(variaveis[k], tipo)
def visitDefinirTipo(self, definirTipo): tipo = st.getNewType(definirTipo.Type) if (tipo == None): definirTipo.accept(self.printer) print('\n\t[ERRO] tipo de retorno indefinido') return [tipo]
def visitExpressionMod(self, expressionMod): #print('visitExpressionMod') tipoExp1 = expressionMod.Expr5.accept(self) tipoExp2 = expressionMod.Expr4.accept(self) tipoExp1 = st.getNewType(tipoExp1) tipoExp2 = st.getNewType(tipoExp2) c = coercion(tipoExp1, tipoExp2) if (c != st.INT): expressionMod.accept(self.printer) print('\n\t[Erro]: Operacao de Mod invalida. A expressao ', end='') expressionMod.Expr5.accept(self.printer) print(' eh do tipo', tipoExp1, 'enquanto a expressao ', end='') expressionMod.Expr4.accept(self.printer) print(' eh do tipo', tipoExp2, 'quando deveriam ser do tipo int\n') return c
def visitExpressionDivide(self, expressionDivide): #print('visitExpressionDivide') tipoExp1 = expressionDivide.Expr5.accept(self) tipoExp2 = expressionDivide.Expr4.accept(self) tipoExp1 = st.getNewType(tipoExp1) tipoExp2 = st.getNewType(tipoExp2) c = coercion(tipoExp1, tipoExp2) if (c == None): expressionDivide.accept(self.printer) print('\n\t[Erro]: Divisao invalida. A expressao ', end='') expressionDivide.Expr5.accept(self.printer) print(' eh do tipo', tipoExp1, 'enquanto a expressao ', end='') expressionDivide.Expr4.accept(self.printer) print(' eh do tipo', tipoExp2, '\n') return c
def visitExpressionTimes(self, expressionTimes): #print('visitExpressionTimes') tipoExp1 = expressionTimes.Expr5.accept(self) tipoExp2 = expressionTimes.Expr4.accept(self) tipoExp1 = st.getNewType(tipoExp1) tipoExp2 = st.getNewType(tipoExp2) c = coercion(tipoExp1, tipoExp2) if (c == None): expressionTimes.accept(self.printer) print('\n\t[Erro]: Multiplicacao invalida. A expressao ', end='') expressionTimes.exp1.accept(self.printer) print(' eh do tipo', tipoExp1, 'enquanto a expressao ', end='') expressionTimes.exp2.accept(self.printer) print(' eh do tipo', tipoExp2, '\n') return c
def visitExpressionAND(self, expressionAND): #print('visitExpressionAND') tipoExp1 = expressionAND.Expr1.accept(self) tipoExp2 = expressionAND.Expr2.accept(self) tipoExp1 = st.getNewType(tipoExp1) tipoExp2 = st.getNewType(tipoExp2) c = coercion(tipoExp1, tipoExp2) if (c != st.BOOL): expressionAND.accept(self.printer) print('\n\t[Erro]: Comparacao invalida. A expressao ', end='') expressionAND.Expr1.accept(self.printer) print('eh do tipo', tipoExp1, 'e a expressao ', end='') expressionAND.Expr2.accept(self.printer) print('eh do tipo', tipoExp2, 'onde ambas deveriam ser do tipo', st.BOOL, '\n') return c
def visitExpressionGreaterEqual(self, expressionGreaterEqual): #print('visitExpressionGreaterEqual') tipoExp1 = expressionGreaterEqual.Expr2.accept(self) tipoExp2 = expressionGreaterEqual.Expr3.accept(self) tipoExp1 = st.getNewType(tipoExp1) tipoExp2 = st.getNewType(tipoExp2) c = coercion(tipoExp1, tipoExp2) if (c == None): expressionGreaterEqual.accept(self.printer) print('\n\t[Erro]: Comparação invalida. A expressao ', end='') expressionGreaterEqual.Expr2.accept(self.printer) print(' eh do tipo', tipoExp1, 'enquanto a expressao ', end='') expressionGreaterEqual.Expr3.accept(self.printer) print(' eh do tipo', tipoExp2, 'quando deveriam ser do mesmo tipo\n') return c
def visitRangeExpList(self, rangeExpList): #print('visitRangeExpList') left = rangeExpList.ExpressionList.accept(self) right = rangeExpList.Expression.accept(self) if (type(left) is list): if (left[0] in st.TiposPrimitivos and left[0] != st.INT): rangeExpList.accept(self.printer) print( '\n\t [ERRO] O tipo da primeira variavel precisa ser inteiro.' ) elif (left[0] != st.INT): st.addVar(left[0], st.INT) if (left[1] in st.TiposPrimitivos and left[1] != st.STRING): rangeExpList.accept(self.printer) print( '\n\t [ERRO] O tipo da segunda variavel precisa ser string.' ) elif (left[1] != st.STRING): st.addVar(left[1], st.STRING) elif (left in lex.reserved and left != st.STRING): rangeExpList.accept(self.printer) print('\n\t[ERRO] Variavel precisa ser do tipo string.') elif (left != st.STRING): st.addVar(left, st.STRING) if (right != st.STRING): rangeExpList.accept(self.printer) print('\n\t[ERRO] Declaracao range precisa ser do tipo string')
def visitSimpleVarSpec(self, simpleVarSpec): #print('visitSimpleVarSpec') variavel = simpleVarSpec.IdentifierList.accept(self) tipo = simpleVarSpec.ExpressionList.accept(self) if (type(tipo) is not list): tipo = [tipo] if (len(variavel) != len(tipo)): simpleVarSpec.accept(self.printer) print('\n\t[Erro]:', len(variavel), 'variaveis mas', len(tipo), 'valores') else: for x in range(len(variavel)): if (st.getBindable(variavel[x]) == None): if (tipo[x] not in st.TiposPrimitivos): tipoAux = st.getBindable(tipo[x]) if (tipoAux == None): simpleVarSpec.accept(self.printer) print('\n\t[ERRO]: Atribuicao nao compativel') else: st.addVar(variavel[x], tipoAux[st.TYPE]) else: st.addVar(variavel[x], tipo[x]) else: simpleVarSpec.accept(self.printer) print('\n\t[Erro]:', variavel[x], 'redefinida neste bloco')
def visitListIdExp(self, listIdExp): #print('visitListIdExp') idList = listIdExp.IdentifierList.accept(self) expList = listIdExp.ExpressionList.accept(self) if (type(expList) is not list): expList = [expList] if (len(idList) != len(expList)): listIdExp.accept(self.printer) print('[Erro]: ', len(idList), 'constantes mas', len(expList), 'valores') else: for i in range(len(idList)): if (st.getBindable(idList[i]) == None): if (expList[i] not in st.TiposPrimitivos): expAux = st.getBindable(expList[i]) if (expAux == None): listIdExp.accept(self.printer) print('\n\t[ERRO]: Atribuicao nao compativel') else: st.addVar(idList[i], expList[st.TYPE]) st.symbolTable[-1][idList[i]][st.CONST] = 'const' else: st.addVar(idList[i], expList[i]) st.symbolTable[-1][idList[i]][st.CONST] = 'const' else: listIdExp.accept(self.printer) print('\n\t[Erro]:', idList[i], 'redefinida neste bloco')
def visitAssignOp(self, assignOp): #print('visitAssignOp') listaExp = assignOp.ExpressionList.accept(self) # lado esquerdo listaExp1 = assignOp.ExpressionList1.accept(self) # lado direito if (listaExp not in st.TiposPrimitivos): bindable = st.getBindable(listaExp) if (st.CONST in bindable): assignOp.accept(self.printer) print('\n\t[Erro]: Atribuicao invalida de constante') if (listaExp1 not in st.TiposPrimitivos): bindable = st.getBindable(listaExp1) if (bindable != None): if (st.TYPE in bindable): listaExp1 = bindable[st.TYPE] if (listaExp != listaExp1): assignOp.accept(self.printer) print('\n\t[Erro]: Tipo de atribuicao invalida') else: assignOp.accept(self.printer) print('\n\t[Erro]: Erro de atribuicao')
def visitParamIdDecl(self, paramIdDecl): # ok listaIDs = paramIdDecl.IdentifierList.accept(self) tipo = st.getNewType(paramIdDecl.Type) if (tipo == None): paramIdDecl.accept(self.printer) print('\n\t[ERRO] Tipo indefenido') for k in range(len(listaIDs) + len(listaIDs)): if (k % 2 != 0): listaIDs.insert(k, tipo) return listaIDs
def visitExpReturn(self, expReturn): #print('visitExpReturn') tipoExp = expReturn.ExpressionList.accept(self) if (tipoExp not in st.TiposPrimitivos and tipoExp != None): tipoExp = st.getBindable(tipoExp) if (tipoExp != None): tipoExp = tipoExp[st.TYPE] # Volta ao escopo que tem o tipo de retorno. for indice in reversed(range(len(st.symbolTable))): scope = st.symbolTable[indice][st.SCOPE] bindable = st.getBindable(scope) if (bindable != None): break if (tipoExp != bindable[st.TYPE]): expReturn.accept(self.printer) print('\n\t[Erro]: O retorno da funcao', scope, 'eh do tipo', bindable[st.TYPE], end='') print(' no entanto, o retorno passado foi do tipo', tipoExp, '\n')
def visitPrintNumberID(self, printNumberID): #print('visitPrintNumberID') if (isinstance(printNumberID.numberOrId, int)): return st.INT elif (printNumberID.numberOrId == 'true' or printNumberID.numberOrId == 'false'): return st.BOOL elif (printNumberID.numberOrId[0] == '\"'): return st.STRING else: idName = st.getBindable(printNumberID.numberOrId) if (idName != None): if (st.CONST in idName): return printNumberID.numberOrId return idName[st.TYPE] return printNumberID.numberOrId
def visitDefinirFuncBody(self, definirFuncBody): parametrosRetorno = definirFuncBody.Signature.accept(self) st.addFunction(definirFuncBody.ID, parametrosRetorno[0:-1], parametrosRetorno[-1]) st.beginScope(definirFuncBody.ID) if (parametrosRetorno[0] != None): for k in range(0, len(parametrosRetorno[0:-1]), 2): st.addVar(parametrosRetorno[0:-1][k], parametrosRetorno[0:-1][k + 1]) definirFuncBody.FunctionBody.accept(self)
def visitSimpleCallFunc(self, simpleCallFunc): #print('visitSimpleCallFunc') idFunc = simpleCallFunc.ID bindable = st.getBindable(idFunc) params = [] for i in range(1, len(bindable[st.PARAMS]), 2): params.append(bindable[st.PARAMS][i]) paramsCall = simpleCallFunc.ExpressionList.accept(self) if (type(paramsCall) is not list): paramsCall = [paramsCall] if (params != paramsCall): simpleCallFunc.accept(self.printer) print('\n\t[Erro]: Parametros incompativeis') return bindable[st.TYPE]
def visitExprSwitchSimple(self, exprSwitchSimple): #print('visitExprSwitchSimple') st.beginScope(st.SWITCH) st.symbolTable[-1][st.SWITCHTYPE] = '' exprSwitchSimple.switchStmt_Body.accept(self) st.varCheck(st.endScope())
def __init__(self): self.printer = Visitor() st.beginScope('main')
def visitStmtFor(self, stmtFor): #print('visitStmtFor') st.beginScope(st.FOR) stmtFor.Condition.accept(self) stmtFor.Block.accept(self) st.varCheck(st.endScope())
def visitStmtForRange(self, stmtForRange): #print('visitStmtForRange') st.beginScope(st.FOR) stmtForRange.RangeClause.accept(self) stmtForRange.Block.accept(self) st.varCheck(st.endScope())
def visitStmtForBlock(self, stmtForBlock): #print('visitStmtForBlock') st.beginScope(st.FOR) stmtForBlock.Block.accept(self) st.varCheck(st.endScope())
def visitCallParenFunc(self, callParenFunc): #print('visitCallParenFunc') idFunc = callParenFunc.ID bindable = st.getBindable(idFunc) return bindable[st.TYPE]