def get_insert_string(token): insert_string = "\n" position = mylexer.find_column_start(data, token) for i in range(0, position - 1): insert_string += " " for j in range(0, len(token.value)): insert_string += "^" return insert_string
def HandleError(self, typeLeft, typeRight, exp): operand = "operands" if typeLeft is None: typeLeft = "" operand = "operand" msg = "Incompatible {3}: {0} {2} {1}".format(typeLeft, typeRight, exp.operator, operand) tok = self.tokens[exp.operatorPosition] startPos = mylexer.find_column_start(self.data, tok) lastPos = startPos + len(tok.value) return "error", Error(msg, tok.lineno, startPos, lastPos)
def getValueType(self, value, methodName): if value is None: return None, None type = "" error = None if value.__class__.__name__ == "Expression": type, error = self.findError(value, methodName) elif value.__class__.__name__ == "ReadInteger": type, error = "int", None elif value.__class__.__name__ == "Consant": type = value.idtype elif value.__class__.__name__ == "FieldAccess": obj = self.symbolTable.getSymbol(value.identifier, methodName) if obj is not None: type = obj.type else: msg = "No declaration found for variable '{0}'".format( value.identifier) type = "error" tok = self.tokens[value.tokenPosition] ltok = self.tokens[value.tokenPosition] startPos = mylexer.find_column_start(self.data, tok) lastPos = mylexer.find_column_start(self.data, ltok) + len( ltok.value) error = Error(msg, tok.lineno, startPos, lastPos) elif value.__class__.__name__ == "Caller": obj = self.symbolTable.getMethodSymbol(value.identifier) if obj is not None: type = obj.type if len(value.exps) != len(obj.formals): msg = "Function '{0}' expects {1} arguments but {2} given".format( value.identifier, len(obj.formals), len(value.exps)) type = "error" tok = self.tokens[value.tokenPosition] ltok = self.tokens[value.tokenPosition] startPos = mylexer.find_column_start(self.data, tok) lastPos = mylexer.find_column_start(self.data, ltok) + len( ltok.value) error = Error(msg, tok.lineno, startPos, lastPos) else: for i in range(0, len(obj.formals)): typeexp, error = self.findError( value.exps[i].value, methodName) if typeexp == "error": break elif typeexp != obj.formals[i].type.type: msg = "Incompatible argument {0}: {1} given, {2} expected".format( i + 1, typeexp, obj.formals[i].type.type) type = "error" tok = self.tokens[value.exps[i].tokenPosition] ltok = self.tokens[ value.exps[i].tokenPostionProcessed] startPos = mylexer.find_column_start( self.data, tok) lastPos = mylexer.find_column_start( self.data, ltok) + len(ltok.value) error = Error(msg, tok.lineno, startPos, lastPos) break return type, error
def handleNoDeclError(self, value, txt="variable"): msg = "No declaration found for {0} {1}".format(txt, value.identifier) tok = self.tokens[value.tokenPosition] startPos = mylexer.find_column_start(self.data, tok) lastPos = startPos + len(tok.value) return "error", Error(msg, tok.lineno, startPos, lastPos)
def findErrorFromStmt(self, stmt, methodName, caller, methodType): if stmt.stmtType == "block": self.findErrorFromBlock(stmt.stmtblock, methodName, caller, methodType) elif stmt.stmtType == "if": type, error = self.HandleExprError(stmt.ifStmt.exp, methodName) if type != "bool" and type != "error": mssage = "Test expression must have boolean type" tok = self.tokens[stmt.ifStmt.exp.tokenPosition] ltok = self.tokens[stmt.ifStmt.exp.tokenPostionProcessed] startPos = mylexer.find_column_start(self.data, tok) lastPos = mylexer.find_column_start(self.data, ltok) + len( ltok.value) error = Error(mssage, tok.lineno, startPos, lastPos) self.errorList.append(error) if stmt.ifStmt.ifstmt.stmtType == "block": self.findErrorFromBlock(stmt.ifStmt.ifstmt.stmtblock, methodName, "if", methodType) if stmt.ifStmt.hasElse and stmt.ifStmt.elstmt.stmtType == "block": self.findErrorFromBlock(stmt.ifStmt.elstmt.stmtblock, methodName, "else", methodType) elif stmt.ifStmt.hasElse and stmt.ifStmt.elstmt.__class__.__name__ == "Stmt": self.findErrorFromStmt(stmt.ifStmt.elstmt, methodName, "else", methodType) elif stmt.stmtType == "while": self.HandleExprError(stmt.wStmt.exp, methodName) if stmt.wStmt.stmt.stmtType == "block": self.findErrorFromBlock(stmt.wStmt.stmt.stmtblock, methodName, "while", methodType) elif stmt.stmtType == "return": if stmt.rStmt.hasExp: type, error = self.HandleExprError(stmt.rStmt.exp, methodName) if type != methodType and type != "error": msg = "Incompatible return: {0} given, {1} expected".format( type, methodType) tok = self.tokens[stmt.rStmt.tokenPosition + 1] ltok = self.tokens[stmt.rStmt.tokenPostionProcessed - 1] startPos = mylexer.find_column_start(self.data, tok) lastPos = mylexer.find_column_start(self.data, ltok) + len( ltok.value) error = Error(msg, tok.lineno, startPos, lastPos) self.errorList.append(error) elif stmt.stmtType == "print": for i in range(0, len(stmt.pStmt.exps)): exp = stmt.pStmt.exps[i] type, error = self.HandleExprError(exp, methodName) if type == "double": mssage = "Incompatible argument {0}: double given, int/bool/string expected".format( i + 1) tok = self.tokens[exp.tokenPosition] ltok = self.tokens[exp.tokenPostionProcessed] startPos = mylexer.find_column_start(self.data, tok) lastPos = mylexer.find_column_start(self.data, ltok) + len( ltok.value) error = Error(mssage, tok.lineno, startPos, lastPos) self.errorList.append(error) elif stmt.stmtType == "break": if not (caller == "while" or caller == "for"): msg = "break is only allowed inside a loop" tok = self.tokens[stmt.bStmt.tokenPosition] startPos = mylexer.find_column_start(self.data, tok) lastPos = startPos + len("break") error = Error(msg, tok.lineno, startPos, lastPos) self.errorList.append(error) elif stmt.stmtType == "for": if stmt.fStmt.hasFirstExp: self.HandleExprError(stmt.fStmt.firstexp, methodName) type, error = self.HandleExprError(stmt.fStmt.middleexp, methodName) if type != "bool" and type != "error": mssage = "Test expression must have boolean type" tok = self.tokens[stmt.fStmt.middleexp.tokenPosition] ltok = self.tokens[stmt.fStmt.middleexp.tokenPostionProcessed] startPos = mylexer.find_column_start(self.data, tok) lastPos = mylexer.find_column_start(self.data, ltok) + len( ltok.value) error = Error(mssage, tok.lineno, startPos, lastPos) self.errorList.append(error) if stmt.fStmt.hasLastExp: self.HandleExprError(stmt.fStmt.lastexp, methodName) if stmt.fStmt.stmt.stmtType == "block": self.findErrorFromBlock(stmt.fStmt.stmt.stmtblock, methodName, "for", methodType) elif stmt.stmtType == "exp": self.HandleExprError(stmt.exp, methodName)