def __init__(self, lexer): self.lexer = lexer self.token = lexer.proxToken( None) # Leitura inicial obrigatoria do primeiro simbolo self.last_token = None self.ts = TS() if self.token is None: # erro no Lexer sys.exit(0)
def __init__(self, input_file): try: self.input_file = open(input_file, 'rb') self.lookahead = 0 self.n_line = 1 self.n_column = 1 self.ts = TS() except IOError: print('Erro de abertura do arquivo. Encerrando.') sys.exit(0)
def __init__(self, file): try: self.file = open(file, 'rb') self.lookahead = 0 self.n_line = 1 self.n_column = 1 self.n_columnInicial = 1 self.n_lineInicial = 1 self.ts = TS() self.c = '\u0000' except IOError: print('Erro de abertura do arquivo. Encerrando.') sys.exit(0)
def __init__(self): self.bits=None self.ts=TS() self.line_infos=[] self.pesInfos=[] #list of currentPES dict self.currentPES={} self.pesStat=[]
def __init__(self, input_file): try: self._input_file: TextIO = open(input_file, 'rb') self._leitor: Generator = self._le_arquivo() self._lexema: str = '' self._simbolo: str = '' self._sep: tuple = (' ', '\t', '\n', '\r') self._estado: int = 1 self._qtd_erros: int = 0 self.list_tokens: list = [] self._line_atual = 1 self._column_atual = 1 self._line_lexer = 1 self._column_lexer = 1 self.ts = TS() except IOError: print('Erro de abertura do arquivo. Encerrando.') sys.exit(0)
def analyseFromTS(self, filepath, pid): ts = TS() data = ts.extract(pid=pid, infilepath=filepath) print "TS extraction done" self.bits = bitstring.ConstBitStream(hex=data) with open("userdata.bin", "wb") as f: f.write(data) # self.analyse() print self.bits.pos print "nb PES : %s" % len(list(self.bits.findall("0x000001e0"))) print self.bits.pos self.bits.pos = 0 print self.bits.pos print "pictures : %s" % list(self.bits.findall("0x00000100")) print self.bits.pos print "sequence header : %s" % list(self.bits.findall("0x000001b3")) self.parse_sequence_header(list(self.bits.findall("0x000001b3"))) print self.bits.pos print "GOP : %s" % list(self.bits.findall("0x000001b8")) print self.bits.pos print "user data : %s" % list(self.bits.findall("0x000001b2")) print self.bits.pos print "ATSC_user_data : %s" % list(self.bits.findall("0x000001b247413934")) print self.bits.pos print "afd_data : %s" % list(self.bits.findall("0x000001b244544731")) # print 'SEI itu_t_35 : %s' %list(self.bits.findall('0xb50031')) print "SEI ATSC_user_data : %s" % list(self.bits.findall("0xb5003147413934")) for pos in list(self.bits.findall("0xb5003147413934", bytealigned=True)): self.parse_ATSC_user_data(pos + (7 * 8)) print "SEI afd_data : %s" % list(self.bits.findall("0xb5003144544731")) for pos in list(self.bits.findall("0xb5003144544731", bytealigned=True)): self.parse_afd_data(pos + (7 * 8)) print self.bits.find("0x000001b2") # self.getUserData() self.write()
def test_ts(self): ts = TS() self.assertEqual(len(ts), 0) ts.append(1.0) self.assertEqual(len(ts), 1) ts.append(0.0) ts.append(5.0) self.assertEqual(len(ts), 3) self.assertEqual(ts.mean(), 2.0)
def collect(self): data = [] for i in range(self.num_sample): values = self.reader.read() if len(data) == 0: for x in range(len(values)): data.append(TS()) for index, v in enumerate(values): data[index].append(v) time.sleep(self.sleep_time) return data
class TSTest(TestCase): def test_ts(self): ts = TS( ) self.assertEqual( len(ts) , 0 ) ts.append( 1.0 ) self.assertEqual( len(ts) , 1 ) ts.append( 0.0 ) ts.append( 5.0 ) self.assertEqual( len(ts) , 3 ) self.assertEqual( ts.mean() , 2.0 ) def setUp(self): self._ts = TS( [2.71828,3.141592,4.12310] ) self._tsa = TS( [2.71828,3.141592,4.12310], accuracy=2 ) self._tsb = TS( [6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 1000.123] ) self._tsc = TS( [6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 10.0,12.3] ) def test_ts_init(self): self.assertEqual(3, len(self._ts)) self.assertEqual(3, len(self._tsa)) self.assertEqual(8, len(self._tsb)) self.assertEqual(9, len(self._tsc)) self.assertEqual(2.72, self._tsa[0]) def test_math_with_accuracy(self): self.assertEqual(3.141592, self._ts.median()) self.assertEqual(3.14, self._tsa.median()) self.assertAlmostEqual(3.3276573, self._ts.mean()) self.assertEqual(3.33, self._tsa.mean()) self.assertAlmostEqual(0.5884131, self._ts.stddev()) self.assertEqual(0.59, self._tsa.stddev()) def test_median(self): self.assertEqual(3.141592, self._ts.median()) self.assertEqual(5.2, self._tsb.median()) self.assertEqual(5.2, self._tsc.median())
class TSTest(TestCase): def test_ts(self): ts = TS() self.assertEqual(len(ts), 0) ts.append(1.0) self.assertEqual(len(ts), 1) ts.append(0.0) ts.append(5.0) self.assertEqual(len(ts), 3) self.assertEqual(ts.mean(), 2.0) def setUp(self): self._ts = TS([2.71828, 3.141592, 4.12310]) self._tsa = TS([2.71828, 3.141592, 4.12310], accuracy=2) self._tsb = TS([6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 1000.123]) self._tsc = TS([6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 10.0, 12.3]) def test_ts_init(self): self.assertEqual(3, len(self._ts)) self.assertEqual(3, len(self._tsa)) self.assertEqual(8, len(self._tsb)) self.assertEqual(9, len(self._tsc)) self.assertEqual(2.72, self._tsa[0]) def test_math_with_accuracy(self): self.assertEqual(3.141592, self._ts.median()) self.assertEqual(3.14, self._tsa.median()) self.assertAlmostEqual(3.3276573, self._ts.mean()) self.assertEqual(3.33, self._tsa.mean()) self.assertAlmostEqual(0.5884131, self._ts.stddev()) self.assertEqual(0.59, self._tsa.stddev()) def test_median(self): self.assertEqual(3.141592, self._ts.median()) self.assertEqual(5.2, self._tsb.median()) self.assertEqual(5.2, self._tsc.median())
def test_ts(self): ts = TS( ) self.assertEqual( len(ts) , 0 ) ts.append( 1.0 ) self.assertEqual( len(ts) , 1 ) ts.append( 0.0 ) ts.append( 5.0 ) self.assertEqual( len(ts) , 3 ) self.assertEqual( ts.mean() , 2.0 )
def collect(self): data = [] start = datetime.datetime.now() while True: values = self.reader.read() if len(data) == 0: for x in range(len(values)): data.append(TS(accuracy=self.accuracy)) for index, v in enumerate(values): data[index].append(v) dt = datetime.datetime.now() - start if dt.total_seconds() >= self.sample_time: break time.sleep(self.sleep_time) return data
class Lexer(): ''' Classe que representa o Lexer: [1] Voce devera se preocupar quando incremetar as linhas e colunas, assim como quando decrementar ou reinicia-las. Lembre-se, ambas comecam em 1. [2] Toda vez que voce encontrar um lexema completo, voce deve retornar um objeto Token(Tag, "lexema", linha, coluna). Cuidado com as palavras reservadas, que ja sao cadastradas na TS. Essa consulta voce devera fazer somente quando encontrar um Identificador. [3] Se o caractere lido nao casar com nenhum caractere esperado, apresentar a mensagem de erro na linha e coluna correspondente. Obs.: lembre-se de usar o metodo retornaPonteiro() quando necessario. lembre-se de usar o metodo sinalizaErroLexico() para mostrar a ocorrencia de um erro lexico. ''' def __init__(self, input_file): try: self.input_file = open(input_file, 'rb') self.lookahead = 0 self.n_line = 1 self.n_column = 1 self.ts = TS() except IOError: print('Erro de abertura do arquivo. Encerrando execução!') sys.exit(0) def closeFile(self): try: self.input_file.close() except IOError: print('Erro dao fechar arquivo. Encerrando execução!') sys.exit(0) def sinalizaErroLexico(self, message): print("\n[Erro Lexico]: ", message, "\n") def retornaPonteiro(self): if(self.lookahead.decode('ascii') != ''): self.input_file.seek(self.input_file.tell()-1) self.n_column-=1 def printTS(self): self.ts.printTS() def proxToken(self, last_token): estado = 1 lexema = "" c = '\u0000' token = None while(True): self.lookahead = self.input_file.read(1) c = self.lookahead.decode('ascii') #Contando Linhas e Colunas if(c == '\n'): self.n_line += 1 self.n_column = 1 elif (c == '\t'): self.n_column += 4 else: self.n_column += 1 if(estado == 1): if(c == ''): self.ts.addToken("EOF", Token(Tag.EOF, "EOF", self.n_line, self.n_column)) token = Token(Tag.EOF, "EOF", self.n_line, self.n_column) elif(c == ' ' or c == '\t' or c == '\n' or c == '\r'): estado = 1 elif(c == '='): estado = 2 elif(c == '!'): estado = 4 elif(c == '<'): estado = 6 elif(c == '>'): estado = 9 elif(c.isdigit()): lexema += c estado = 12 elif(c.isalpha()): lexema += c estado = 14 elif(c == '\"'): estado = 27 elif(c == '#'): estado = 18 elif(c == '.'): #estado = 16 #self.ts.addToken(".", Token(Tag.KW_PONTO, ".", self.n_line, self.n_column)) token = Token(Tag.KW_PONTO, ".", self.n_line, self.n_column) elif(c == '/'): #estado = 16 #self.ts.addToken("/", Token(Tag.OP_DIVISAO, "/", self.n_line, self.n_column)) token = Token(Tag.OP_DIVISAO, "/", self.n_line, self.n_column) elif (c == ','): #estado = 17 #self.ts.addToken(",", Token(Tag.VG, ",", self.n_line, self.n_column)) token = Token(Tag.VG, ",", self.n_line, self.n_column) elif (c == '*'): #estado = 19 #self.ts.addToken("*", Token(Tag.OP_MULTIPLICACAO, "*", self.n_line, self.n_column)) token = Token(Tag.OP_MULTIPLICACAO, "*", self.n_line, self.n_column) elif (c == '+'): #estado = 20 #self.ts.addToken("+", Token(Tag.OP_SOMA, "+", self.n_line, self.n_column)) token = Token(Tag.OP_SOMA, "+", self.n_line, self.n_column) elif (c == '-'): #estado = 21 if(last_token.nome != Tag.KW_INTEGER and last_token.nome != Tag.KW_DOUBLE and last_token.nome != Tag.ID): token = Token(Tag.OP_INVERSOR, "-", self.n_line, self.n_column) #self.ts.addToken("-", Token(Tag.OP_SUBTRACAO, "-", self.n_line, self.n_column)) else: token = Token(Tag.OP_SUBTRACAO, "-", self.n_line, self.n_column) elif (c == '('): #estado = 22 #self.ts.addToken("(", Token(Tag.AP, "(", self.n_line, self.n_column)) token = Token(Tag.AP, "(", self.n_line, self.n_column) elif (c == ')'): #estado = 23 #self.ts.addToken(")", Token(Tag.FP, ")", self.n_line, self.n_column)) token = Token(Tag.FP, ")", self.n_line, self.n_column) elif (c == '['): #estado = 24 #self.ts.addToken("[", Token(Tag.AT, "[", self.n_line, self.n_column)) token = Token(Tag.AT, "[", self.n_line, self.n_column) elif (c == ':'): #estado = 25 #self.ts.addToken(":", Token(Tag.DP, ":", self.n_line, self.n_column)) token = Token(Tag.DP, ":", self.n_line, self.n_column) elif (c == ']'): #estado = 26 #self.ts.addToken("]", Token(Tag.FT, "]", self.n_line, self.n_column)) token = Token(Tag.FT, "]", self.n_line, self.n_column) elif (c == ';'): #estado = 28 #self.ts.addToken(";", Token(Tag.PV, ";", self.n_line, self.n_column)) token = Token(Tag.PV, ";", self.n_line, self.n_column) else: self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) token = None elif(estado == 2): if(c == '='): #estado = 3 #self.ts.addToken("==", Token(Tag.OP_IGUAL, "==", self.n_line, self.n_column)) token = Token(Tag.OP_IGUAL, "==", self.n_line, self.n_column) else: #estado = 34 self.retornaPonteiro() #self.ts.addToken("=", Token(Tag.CP, "=", self.n_line, self.n_column)) token = Token(Tag.CP, "=", self.n_line, self.n_column) elif(estado == 4): if(c == '='): #estado = 5 #self.ts.addToken("!=", Token(Tag.OP_DIFERENTE, "!=", self.n_line, self.n_column)) token = Token(Tag.OP_DIFERENTE, "!=", self.n_line, self.n_column) else: #estado = 29 self.retornaPonteiro() #self.ts.addToken("!", Token(Tag.OP_NEGACAO, "!", self.n_line, self.n_column)) token = Token(Tag.OP_NEGACAO, "!", self.n_line, self.n_column) elif(estado == 6): if(c == '='): #estado = 7 #self.ts.addToken("<=", Token(Tag.OP_MENOR_IGUAL, "<=", self.n_line, self.n_column)) token = Token(Tag.OP_MENOR_IGUAL, "<=", self.n_line, self.n_column) else: #estado = 8 self.retornaPonteiro() #self.ts.addToken("<", Token(Tag.OP_MENOR, "<", self.n_line, self.n_column)) token = Token(Tag.OP_MENOR, "<", self.n_line, self.n_column) elif(estado == 9): if(c == '='): #estado = 10 #self.ts.addToken(">=", Token(Tag.OP_MAIOR_IGUAL, ">=", self.n_line, self.n_column)) token = Token(Tag.OP_MAIOR_IGUAL, ">=", self.n_line, self.n_column) else: #estado = 11 self.retornaPonteiro() #self.ts.addToken(">", Token(Tag.OP_MAIOR, ">", self.n_line, self.n_column)) token = Token(Tag.OP_MAIOR, ">", self.n_line, self.n_column) elif(estado == 12): if(c.isdigit()): #continua no estado 12 (estado = 12) lexema += c elif(c == '.'): estado = 31 lexema += c else: #estado = 13 self.retornaPonteiro() #self.ts.addToken(lexema, Token(Tag.KW_INTEGER, lexema, self.n_line, self.n_column )) token = Token(Tag.KW_INTEGER, lexema, self.n_line, self.n_column ) elif(estado == 14): if(c.isalnum() or c == '_'): #continua no estado 14 lexema += c else: #estado = 15 self.retornaPonteiro() tokenComp = self.ts.getToken(lexema) if(tokenComp is None): tokenComp = Token(Tag.ID, lexema, self.n_line, self.n_column ) self.ts.addToken(lexema, tokenComp) else: tokenComp = Token(self.ts.getToken(lexema).nome, lexema, self.n_line, self.n_column ) token = tokenComp elif(estado == 18): if(c != '\n'): estado = 18 else: estado = 1 elif(estado == 27): if(c != '\"'): estado = 30 lexema += c elif(c == '\"'): self.sinalizaErroLexico("String vazia na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) #self.ts.addToken(lexema, Token(Tag.KW_STRING, lexema, self.n_line, self.n_column )) estado = 1 token = None else: self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) token = None elif(estado == 30): if(c == ''): self.sinalizaErroLexico("String não finalizada corretamente na linha " + str(self.n_line) + " e coluna " + str(self.n_column) +". Finalizando compilação.") token = None estado = 1 elif(c != '\"'): #estado permanece no 30 (estado = 30) lexema += c elif(c == '\"' ): #estado = 35 #self.ts.addToken(lexema, Token(Tag.KW_STRING, lexema, self.n_line, self.n_column )) token = Token(Tag.KW_STRING, lexema, self.n_line, self.n_column ) else: self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) token = None elif(estado == 31): if(c.isdigit()): estado = 32 lexema +=c else: self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) token = None elif(estado == 32): if(c.isdigit()): #estado permanece no 32 (estado = 32) lexema += c else: #estado = 33 self.retornaPonteiro() #self.ts.addToken(lexema, Token(Tag.KW_DOUBLE, lexema, self.n_line, self.n_column )) token = Token(Tag.KW_DOUBLE, lexema, self.n_line, self.n_column ) if (token is not None): return token
class Lexer(): ''' Classe que representa o Lexer (AFD): [1] Voce devera se preocupar quando incremetar as linhas e colunas, assim como, quando decrementar ou reinicia-las. Lembre-se, ambas comecam em 1. [2] Toda vez que voce encontrar um lexema completo, voce deve retornar um objeto Token(Tag, "lexema", linha, coluna). Cuidado com as palavras reservadas, que ja sao cadastradas na TS. Essa consulta voce devera fazer somente quando encontrar um Identificador. [3] Se o caractere lido nao casar com nenhum caractere esperado, apresentar a mensagem de erro na linha e coluna correspondente. Obs.: lembre-se de usar o metodo retornaPonteiro() quando necessario. lembre-se de usar o metodo sinalizaErroLexico() para mostrar a ocorrencia de um erro lexico. ''' def __init__(self, input_file): try: self._input_file: TextIO = open(input_file, 'rb') self._leitor: Generator = self._le_arquivo() self._lexema: str = '' self._simbolo: str = '' self._sep: tuple = (' ', '\t', '\n', '\r') self._estado: int = 1 self._qtd_erros: int = 0 self.list_tokens: list = [] self._line_atual = 1 self._column_atual = 1 self._line_lexer = 1 self._column_lexer = 1 self.ts = TS() except IOError: print('Erro de abertura do arquivo. Encerrando.') sys.exit(0) def _closeFile(self): try: self._input_file.close() except IOError: print('Erro ao fechar arquivo. Encerrando.') sys.exit(0) def _checa_modo_panico(self): self._qtd_erros += 1 if self._qtd_erros > 2: logging.critical( 'Limite máximo de erros lexicos suportados foi atingido.') raise SyntaxError def sinalizaErroLexico(self, message: str = 'Caractere invalido') -> str: self._simbolo = self._simbolo if self._simbolo else 'EOF' self.list_tokens.append( f"""[Erro Lexico]: {message} [ { repr(self._simbolo )} ] na linha { str(self._line_atual)} e coluna {str(self._column_atual)}""" ) self._checa_modo_panico() def retornaPonteiro(self): self._input_file.seek(self._input_file.tell() - 1) def printTS(self): self.ts.printTS() def printTokens(self): for token in self.list_tokens: try: print(token.toString()) except: print('[Erro Lexico]:', token) def _limpa_lexema(self): self._lexema = '' self._estado = 1 def _atualiza_linha_lexer(self): self._line_lexer = self._line_atual self._column_lexer = self._column_atual def _le_arquivo(self) -> Generator: while True: try: self._simbolo: str = self._input_file.read(1).decode('ascii') # Sinaliza coluna e linha self._column_atual += 1 if self._simbolo == '\n': self._line_atual += 1 self._column_atual = 0 yield self._simbolo.lower() except UnicodeDecodeError: self.list_tokens.append( f'[Decode Error] Não foi possivel ler o caractere na posição linha {self._line_atual}, coluna {self._column_atual}' ) self._checa_modo_panico() def analisa(self): while True: try: self._simbolo: str = next(self._leitor) if self._estado == 1: self._atualiza_linha_lexer() list_simbolos: list = [ smb.value for smb in self.ts.get_SMB() ] list_operadores: list = [ smb.value for smb in self.ts.get_OP() ] list_tokens: list = list_operadores + list_simbolos if self._simbolo in list_tokens and self._simbolo not in ( '/', '<'): self.list_tokens.append( Token(Tag(self._simbolo), Tag(self._simbolo).value, self._line_atual, self._column_atual)) continue if self._simbolo in self._sep: self._estado = 1 continue if self._simbolo == '=': self._estado = 2 continue if self._simbolo == '!': self._estado = 4 continue if self._simbolo == '<': self._estado = 6 continue if self._simbolo == '>': self._estado = 9 continue if self._simbolo.isdigit(): self._lexema += self._simbolo self._estado = 12 continue if self._simbolo.isalpha(): self._lexema += self._simbolo self._estado = 14 continue if self._simbolo == ':': self._estado = 16 continue if self._simbolo == '"': self._estado = 17 continue if self._simbolo == '/': self._lexema += self._simbolo self._estado = 18 continue #EOF if self._simbolo == '': self.list_tokens.append( Token(Tag.EOF, Tag.EOF.value, self._line_atual, self._column_atual)) self._closeFile() break self.sinalizaErroLexico() self._limpa_lexema() continue if self._estado == 2: self._limpa_lexema() if self._simbolo == '=': self.list_tokens.append( Token(Tag.OP_EQ, Tag.OP_EQ.value, self._line_lexer, self._column_lexer)) continue self.sinalizaErroLexico() continue if self._estado == 4: self._limpa_lexema() if self._simbolo == '=': self.list_tokens.append( Token(Tag.OP_NE, Tag.OP_NE.value, self._line_lexer, self._column_lexer)) continue self.sinalizaErroLexico() continue if self._estado == 16: self._limpa_lexema() if self._simbolo == '=': self.list_tokens.append( Token(Tag.OP_ATRIB, Tag.OP_ATRIB.value, self._line_lexer, self._column_lexer)) continue self.sinalizaErroLexico() continue if self._estado == 17: if self._simbolo == '"': if not self._lexema: self.sinalizaErroLexico( "Strings vazias não são validas") continue self.list_tokens.append( Token(Tag.KW_CHAR, self._lexema, self._line_lexer, self._column_lexer)) self._limpa_lexema() continue self._lexema += self._simbolo if self._simbolo == '\n': self.sinalizaErroLexico("Era esperado uma aspas dupla") continue if self._estado == 18: if self._simbolo not in ['/', '*']: self.list_tokens.append( Token(Tag.OP_DIV, self._lexema, self._line_lexer, self._column_lexer)) self._limpa_lexema() continue self._lexema += self._simbolo if self._lexema == '//': continue if self._lexema == '/*': self._estado = 19 continue if self._simbolo == '\n': self._limpa_lexema() continue if not self._lexema.startswith('//'): self.sinalizaErroLexico() continue if self._estado == 19: self._lexema += self._simbolo if self._lexema.endswith('*/'): self._limpa_lexema() continue if self._simbolo == '': self.sinalizaErroLexico('Esperado "*/"') if self._estado == 6: self._limpa_lexema() if self._simbolo == '=': self.list_tokens.append( Token(Tag.OP_LE, Tag.OP_LE.value, self._line_lexer, self._column_lexer)) continue self.retornaPonteiro() self.list_tokens.append( Token(Tag.OP_LT, Tag.OP_LT.value, self._line_lexer, self._column_lexer)) continue if self._estado == 9: self._limpa_lexema() if self._simbolo == '=': self.list_tokens.append( Token(Tag.OP_GE, Tag.OP_GE.value, self._line_lexer, self._column_lexer)) continue self.retornaPonteiro() self.list_tokens.append( Token(Tag.OP_GT, Tag.OP_GT.value, self._line_lexer, self._column_lexer)) continue if self._estado == 12: if self._simbolo.isdigit(): self._lexema += self._simbolo continue self.retornaPonteiro() self.list_tokens.append( Token(Tag.NUM, self._lexema, self._line_lexer, self._column_lexer)) self._limpa_lexema() if self._estado == 14: if self._simbolo.isalnum(): self._lexema += self._simbolo continue token = self.ts.getToken(self._lexema) if token: token = Token(token.nome, token.lexema, self._line_lexer, self._column_lexer) else: token = Token(Tag.ID, self._lexema, self._line_lexer, self._column_lexer) self.list_tokens.append(token) self.ts.addToken(self._lexema, token) self._limpa_lexema() self.retornaPonteiro() except SyntaxError: break
class Lexer(): #Classe que representa o Lexer: #[1] Voce devera se preocupar quando incremetar as linhas e colunas, #assim como quando decrementar ou reinicia-las. Lembre-se, ambas #comecam em 1. #[2] Toda vez que voce encontrar um lexema completo, voce deve retornar #um objeto Token(Tag, "lexema", linha, coluna). Cuidado com as #palavras reservadas, que ja sao cadastradas na TS. Essa consulta #voce devera fazer somente quando encontrar um Identificador. #[3] Se o caractere lido nao casar com nenhum caractere esperado, #vapresentar a mensagem de erro na linha e coluna correspondente. #Obs.: lembre-se de usar o metodo retornaPonteiro() quando necessario. # lembre-se de usar o metodo sinalizaErroLexico() para mostrar # a ocorrencia de um erro lexico. def __init__(self, input_file): try: self.input_file = open(input_file, 'rb') self.lookahead = 0 self.n_line = 1 self.n_column = 1 self.ts = TS() except IOError: print('Erro de abertura do arquivo. Encerrando.') sys.exit(0) def closeFile(self): try: self.input_file.close() except IOError: print('Erro ao fechar arquivo. Encerrando.') sys.exit(0) def sinalizaErroLexico(self, message): print("[Erro Lexico]: ", message, "\n") def retornaPonteiro(self): if (self.lookahead.decode('ascii') != ''): self.input_file.seek(self.input_file.tell() - 1) self.n_column -= 1 def printTS(self): self.ts.printTS() def proxToken(self): estado = 1 lexema = "" c = '\u0000' while (True): self.lookahead = self.input_file.read(1) c = self.lookahead.decode('ascii') if (estado == 1): #--------------Q0 if (c == ''): return Token(Tag.EOF, "EOF", self.n_line, self.n_column) elif (c == ' ' or c == '\t' or c == '\n' or c == '\r'): estado = 1 if (c == '\n'): self.n_line += 1 self.n_column = 1 elif (c == ' ' or '\r'): self.n_column += 1 elif (c == '\t'): self.n_column += 3 elif (c == '#'): #--------------Q24 estado = 24 self.n_column += 1 elif (c == '"'): #--------------Q21 estado = 21 self.n_column += 1 elif (c == '='): #--------------Q1 estado = 2 self.n_column += 1 elif (c == '!'): #--------------Q3 estado = 4 self.n_column += 1 elif (c == '<'): #--------------Q6 estado = 6 self.n_column += 1 elif (c == '>'): #--------------Q9 estado = 9 self.n_column += 1 elif (c.isdigit()): #--------------Q16 lexema += c estado = 16 self.n_column += 1 elif (c.isalpha()): #--------------Q26 lexema += c estado = 26 self.n_column += 1 elif (c == '/'): #--------------Q15 self.n_column += 1 token = Token(Tag.OP_DIV, "/", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == '.'): #--------------Q30 self.n_column += 1 token = Token(Tag.SIMB_PONTO, ".", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == ']'): #--------------Q36 self.n_column += 1 token = Token(Tag.SIMB_FECHA_COLCHETES, "]", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == '['): #--------------Q35 self.n_column += 1 token = Token(Tag.SIMB_ABRE_COLCHETES, "[", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == ','): #--------------Q33 self.n_column += 1 token = Token(Tag.SIMB_VIRGULA, ",", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == ')'): #--------------Q34 self.n_column += 1 token = Token(Tag.SIMB_FECHA_PARENTESES, ")", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == '('): #--------------Q32 self.n_column += 1 token = Token(Tag.SIMB_ABRE_PARENTESES, "(", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == ';'): #--------------Q31 self.n_column += 1 token = Token(Tag.SIMB_PONTO_VIRGULA, ";", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == ':'): #--------------Q29 self.n_column += 1 token = Token(Tag.SIMB_DOIS_PONTOS, ":", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == '*'): #--------------Q14 self.n_column += 1 token = Token(Tag.OP_MULT, "*", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == '+'): #--------------Q13 self.n_column += 1 token = Token(Tag.OP_SOMA, "+", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (c == '-'): #--------------Q12 self.n_column += 1 token = Token(Tag.OP_UNARIO, "-", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token else: self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) return None elif (estado == 2): if (c == '='): #--------------Q2 self.n_column += 1 token = Token(Tag.OP_IGUAL, "==", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token else: #--------------Q28 self.retornaPonteiro() token = Token(Tag.OP_ATRIBUI, "=", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (estado == 4): if (c == '='): #--------------Q5 self.n_column += 1 token = Token(Tag.OP_DIFERENTE, "!=", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token else: #--------------Q4 self.retornaPonteiro() token = Token(Tag.OP_UNARIO, "!", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (estado == 6): if (c == '='): #--------------Q7 self.n_column += 1 token = Token(Tag.OP_MENOR_IGUAL, "<=", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token else: #--------------Q8 self.retornaPonteiro() token = Token(Tag.OP_MENOR, "<", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (estado == 9): if (c == '='): #--------------Q10 self.n_column += 1 token = Token(Tag.OP_MAIOR_IGUAL, ">=", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token else: #--------------Q11 self.retornaPonteiro() token = Token(Tag.OP_MAIOR, ">", self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (estado == 16): if (c.isdigit()): #--------------Q16 lexema += c self.n_column += 1 elif (c == '.'): #--------------Q18 lexema += c estado = 18 self.n_column += 1 elif (c == '-'): #RECONHECER INT self.n_column += 1 token = Token(Tag.CONST_INT, lexema, self.n_line, self.n_column) self.ts.addToken(lexema, token) return token #RECONHECER OPERADOR MENOS # token = Token(Tag.OP_SUBTRAI, lexema, self.n_line, self.n_column) #self.ts.addToken(lexema, token) #return token else: #--------------Q17 self.retornaPonteiro() token = Token(Tag.CONST_INT, lexema, self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (estado == 18): #---RECONHECER DOUBLE if (c.isdigit()): #--------------Q19 lexema += c self.n_column += 1 elif (c == '-'): #RECONHECER DOUBLE token = Token(Tag.CONST_DOUBLE, lexema, self.n_line, self.n_column) self.ts.addToken(lexema, token) return token #RECONHECER OPERADOR MENOS #token = Token(Tag.OP_SUBTRAI, lexema, self.n_line, self.n_column) #self.ts.addToken(lexema, token) #return token else: #--------------Q20 self.retornaPonteiro() token = Token(Tag.CONST_DOUBLE, lexema, self.n_line, self.n_column) self.ts.addToken(lexema, token) return token elif (estado == 21): if (c == '"'): #--------------Q23 self.n_column += 1 return Token(Tag.CONST_STRING, lexema, self.n_line, self.n_column) elif (c == '\n'): self.sinalizaErroLexico( "Só é permitido String de uma Linha! Erro na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) self.n_column = 1 self.n_line += 1 else: #--------------Q22 lexema += c self.n_column += 1 elif (estado == 24): if (c == '\n'): #--------------Q0 self.n_line = self.n_line + 1 self.n_column = 1 else: #--------------Q25 estado = 24 elif (estado == 26): if (c.isalnum()): #--------------Q26 lexema += c self.n_column += 1 else: #--------------Q27 self.retornaPonteiro() token = self.ts.getToken(lexema) if (token is None): #--------------VERIFICA TABELA token = Token(Tag.ID, lexema, self.n_line, self.n_column) self.ts.addToken(lexema, token) else: token.setLinha(self.n_line) token.setColuna(self.n_column) return token
def setUp(self): self._ts = TS( [2.71828,3.141592,4.12310] ) self._tsa = TS( [2.71828,3.141592,4.12310], accuracy=2 ) self._tsb = TS( [6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 1000.123] ) self._tsc = TS( [6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 10.0,12.3] )
def setUp(self): self._ts = TS([2.71828, 3.141592, 4.12310]) self._tsa = TS([2.71828, 3.141592, 4.12310], accuracy=2) self._tsb = TS([6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 1000.123]) self._tsc = TS([6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 10.0, 12.3])
class Lexer: def __init__(self, input_file): try: self.input_file = open(input_file, 'rb') self.lookahead = 0 self.n_line = 1 self.n_column = 0 self.ts = TS() self.totalErros = 0 except IOError: print('Erro de abertura do arquivo. Encerrando.') sys.exit(0) def closeFile(self): try: self.input_file.close() except IOError: print('Erro ao fechar arquivo. Encerrando.') sys.exit(0) def sinalizaErroLexico(self, message): self.totalErros = self.totalErros + 1 print("[Erro Lexico]: ", message, "\n") def retornaPonteiro(self): if self.lookahead.decode('ascii') != '': self.input_file.seek(self.input_file.tell() - 1) self.n_column = self.n_column - 1 def printTS(self): self.ts.printTS() def proxToken(self): estado = 1 lexema = "" c = '\u0000' while True: self.lookahead = self.input_file.read(1) c = self.lookahead.decode('ascii') # caractere lido self.n_column = self.n_column + 1 if estado == 1: if c == '': return Token(Tag.EOF, "EOF", self.n_line, self.n_column) elif c == ' ' or c == '\t' or c == '\n' or c == '\r': estado = 1 if c == '\n': self.n_line = self.n_line + 1 self.n_column = 0 elif c == '=': estado = 2 elif c == '!': estado = 4 elif c == '<': estado = 6 elif c == '>': estado = 9 elif c.isdigit(): # Verificando se é um número lexema += c estado = 12 elif c.isalpha(): # Verificando se é uma letra lexema += c estado = 14 elif c == '/': estado = 16 elif c == '+': return Token(Tag.OP_AD, "+", self.n_line, self.n_column) elif c == '*': return Token(Tag.OP_MUL, "*", self.n_line, self.n_column) elif c == '-': return Token(Tag.OP_MIN, "-", self.n_line, self.n_column) elif c == '{': return Token(Tag.SMB_OBC, "{", self.n_line, self.n_column) elif c == '}': return Token(Tag.SMB_CBC, "}", self.n_line, self.n_column) elif c == ';': return Token(Tag.SMB_SEM, ";", self.n_line, self.n_column) elif c == ',': return Token(Tag.SMB_COM, ",", self.n_line, self.n_column) elif c == '(': return Token(Tag.SMB_OPA, "(", self.n_line, self.n_column) elif c == ')': return Token(Tag.SMB_CPA, ")", self.n_line, self.n_column) elif c == '"': estado = 21 else: lexema += c self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) if self.totalErros == 3: return None else: return '' elif estado == 2: if c == '=': return Token(Tag.OP_EQ, "==", self.n_line, self.n_column) else: self.retornaPonteiro() return Token(Tag.OP_ATRIB, "=", self.n_line, self.n_column) elif estado == 4: if c == '=': return Token(Tag.OP_NE, "!=", self.n_line, self.n_column) self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) self.retornaPonteiro() if self.totalErros == 3: return None else: return '' elif estado == 6: if c == '=': return Token(Tag.OP_LE, "<=", self.n_line, self.n_column) self.retornaPonteiro() return Token(Tag.OP_LT, "<", self.n_line, self.n_column) elif estado == 9: if c == '=': return Token(Tag.OP_GE, ">=", self.n_line, self.n_column) self.retornaPonteiro() return Token(Tag.OP_GT, ">", self.n_line, self.n_column) elif estado == 12: if c.isdigit(): lexema += c elif c == '.': lexema += c estado = 20 else: self.retornaPonteiro() return Token(Tag.NUM, lexema, self.n_line, self.n_column) elif estado == 14: if c.isalnum(): # Verificando se é um número ou uma letra lexema += c else: self.retornaPonteiro() token = self.ts.getToken(lexema) if token is None: token = Token(Tag.ID, lexema, 0, 0) self.ts.addToken(lexema, token) token.setColuna(self.n_column) token.setLinha(self.n_line) return token elif estado == 16: if c == '/': estado = 17 elif c == '*': estado = 18 else: self.retornaPonteiro() return Token(Tag.OP_DIV, '/', self.n_line, self.n_column) elif estado == 17: if c == '\n': self.n_line = self.n_line + 1 self.n_column = 0 estado = 1 elif c == '': return Token(Tag.EOF, "EOF", self.n_line, self.n_column) elif estado == 18: if c == '*': estado = 19 elif c == '\n': self.n_line = self.n_line + 1 self.n_column = 1 elif c == '': return Token(Tag.EOF, "EOF", self.n_line, self.n_column - 1) elif estado == 19: if c == '/': estado = 1 else: estado = 18 elif estado == 20: if c.isdigit(): lexema += c else: self.retornaPonteiro() return Token(Tag.NUM_CONST, lexema, self.n_line, self.n_column) elif estado == 21: if c == '"': return Token(Tag.CHAR_CONST, lexema, self.n_line, self.n_column - 1) elif c == '\n': self.n_line = self.n_line + 1 self.n_column = 0 elif c == '': coluna = self.n_column self.n_column = 0 return Token(Tag.CHAR_CONST, lexema, self.n_line, coluna) lexema += c
class Lexer: def __init__(self, file): try: self.file = open(file, 'rb') self.lookahead = 0 self.n_line = 1 self.n_column = 1 self.n_columnInicial = 1 self.n_lineInicial = 1 self.ts = TS() self.c = '\u0000' except IOError: print('Erro de abertura do arquivo. Encerrando.') sys.exit(0) def closeFile(self): try: self.file.close() except IOError: print('Erro ao fechar arquivo. Encerrando.') sys.exit(0) def sinalizaErroLexico(self, message): print("[Erro Lexico]: ", message, "\n") def retornaPonteiro(self): if self.lookahead.decode('ascii') != '': self.file.seek(self.file.tell() - 1) def printTS(self): self.ts.printTS() def proxToken(self): estado = 1 lexema = "" self.c = '\u0000' while True: self.lookahead = self.file.read(1) try: self.c = self.lookahead.decode('ascii') except: self.sinalizaErroLexico("Caractere nao ASCII na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) return None if estado == 1: self.n_lineInicial = self.n_line self.n_columnInicial = self.n_column if self.c == '': return Token(Tag.EOF, "EOF", self.n_lineInicial, self.n_columnInicial) elif self.c == ' ' or self.c == '\n' or self.c == '\t' or self.c == '\r': estado = 1 elif self.c == '+': estado = 2 elif self.c == '-': estado = 3 elif self.c == '{': estado = 4 elif self.c == '}': estado = 5 elif self.c == '(': estado = 6 elif self.c == ')': estado = 7 elif self.c == ',': estado = 8 elif self.c == ';': estado = 9 elif self.c == '/': estado = 10 elif self.c == '*': estado = 13 elif self.c == '=': estado = 16 elif self.c == '!': estado = 19 elif self.c == '>': estado = 21 elif self.c == '<': estado = 24 elif self.c == '"': estado = 29 elif self.c.isalpha(): lexema += self.c estado = 26 elif self.c.isdigit(): lexema += self.c estado = 31 else: self.retornaPonteiro() self.sinalizaErroLexico("Caractere invalido [" + self.c + "] na linha " + str(self.n_lineInicial) + " e coluna " + str(self.n_columnInicial)) return None elif estado == 2: self.retornaPonteiro() return Token(Tag.OP_AD, "+", self.n_lineInicial, self.n_columnInicial) elif estado == 3: self.retornaPonteiro() return Token(Tag.OP_MIN, "-", self.n_lineInicial, self.n_columnInicial) elif estado == 4: self.retornaPonteiro() return Token(Tag.SMB_OBC, "{", self.n_lineInicial, self.n_columnInicial) elif estado == 5: self.retornaPonteiro() return Token(Tag.SMB_CBC, "}", self.n_lineInicial, self.n_columnInicial) elif estado == 6: self.retornaPonteiro() return Token(Tag.SMB_OPA, "(", self.n_lineInicial, self.n_columnInicial) elif estado == 7: self.retornaPonteiro() return Token(Tag.SMB_CPA, ")", self.n_lineInicial, self.n_columnInicial) elif estado == 8: self.retornaPonteiro() return Token(Tag.SMB_COM, ",", self.n_lineInicial, self.n_columnInicial) elif estado == 9: self.retornaPonteiro() return Token(Tag.SMB_SEM, ";", self.n_lineInicial, self.n_columnInicial) elif estado == 10: if self.c == '/': estado = 12 elif self.c == '*': estado = 35 else: self.retornaPonteiro() return Token(Tag.OP_DIV, "/", self.n_lineInicial, self.n_columnInicial) elif estado == 12: if self.c == '\n' or self.c == "": estado = 1 elif estado == 13: self.retornaPonteiro() return Token(Tag.OP_MUL, "*", self.n_lineInicial, self.n_columnInicial) elif estado == 16: if self.c == '=': return Token(Tag.OP_EQ, "==", self.n_lineInicial, self.n_columnInicial) self.retornaPonteiro() return Token(Tag.OP_ATRIB, "=", self.n_lineInicial, self.n_columnInicial) elif estado == 19: if (self.c == '='): return Token(Tag.OP_NE, "!=", self.n_lineInicial, self.n_columnInicial) self.sinalizaErroLexico("Caractere invalido [" + self.c + "] na linha " + str(self.n_lineInicial) + " e coluna " + str(self.n_columnInicial)) return None elif estado == 21: if self.c == '=': return Token(Tag.OP_GE, ">=", self.n_lineInicial, self.n_columnInicial) self.retornaPonteiro() return Token(Tag.OP_GT, ">", self.n_lineInicial, self.n_columnInicial) elif estado == 24: if self.c == '=': return Token(Tag.OP_LE, "<=", self.n_lineInicial, self.n_columnInicial) self.retornaPonteiro() return Token(Tag.OP_LT, "<", self.n_lineInicial, self.n_columnInicial) elif estado == 26: if self.c.isalnum(): lexema += self.c else: self.retornaPonteiro() token = self.ts.getToken(lexema.lower()) if token is None: token = Token(Tag.ID, lexema, self.n_lineInicial, self.n_columnInicial) self.ts.addToken(lexema, token) else: token.linha = self.n_lineInicial token.coluna = self.n_columnInicial return token elif estado == 29: if self.c != '"': if self.c == '\r' or self.c == '\n' or self.c == '': self.sinalizaErroLexico("Erro de sintaxe [" + lexema + "] na linha " + str(self.n_lineInicial) + " e coluna " + str(self.n_columnInicial)) lexema = '' estado = 1 return None lexema += self.c else: estado = 1 return Token(Tag.CHAR_CONST, lexema, self.n_lineInicial, self.n_columnInicial) elif estado == 31: if self.c.isdigit(): lexema += self.c elif self.c == '.': lexema += self.c else: self.retornaPonteiro() return Token(Tag.NUM_CONST, lexema, self.n_lineInicial, self.n_columnInicial) elif estado == 35: if self.c == '*': estado = 36 elif self.c == "": self.sinalizaErroLexico("Erro de sintaxe na linha " + str(self.n_lineInicial) + " e coluna " + str(self.n_columnInicial)) return None elif estado == 36: if self.c == '/': estado = 1 elif self.c == '*': estado = 36 elif self.c == "": self.sinalizaErroLexico("Erro de sintaxe na linha " + str(self.n_lineInicial) + " e coluna " + str(self.n_columnInicial)) return None else: estado = 35 if self.c == '\t': self.n_column += 3 else: self.n_column += 1 if self.c == '\n': self.n_line += 1 self.n_column = 1
# from settings import Settings from ga_settings import GA_settings from ga import GA from ts_settings import TS_settings from ts import TS from sa_settings import SA_settings from sa import SA ga_settings = GA_settings() ga = GA(ga_settings) ga.main() ts_settings = TS_settings() ts = TS(ts_settings) ts.main() sa_settings = SA_settings() sa = SA(sa_settings) sa.main()
class Lexer(): def __init__(self, input_file): try: self.input_file = open(input_file, 'rb') self.lookahead = 0 self.n_line = 1 self.n_column = 1 self.lexemaAnt = "" self.ts = TS() except IOError: print('Erro de abertura do arquivo. Encerrando.') sys.exit(0) def closeFile(self): try: self.input_file.close() except IOError: print('Erro dao fechar arquivo. Encerrando.') sys.exit(0) def sinalizaErroLexico(self, message): print("[Erro Lexico]: ", message, "\n") def retornaPonteiro(self): if (self.lookahead.decode('ascii') != ''): self.input_file.seek(self.input_file.tell() - 1) def printTS(self): self.ts.printTS() def proxToken(self): estado = 1 lexema = "" lexemaAnt = None negacao = False c = '\u0000' while (True): self.lookahead = self.input_file.read(1) c = self.lookahead.decode('ascii') if (estado == 1): if (c == ''): return Token(Tag.EOF, "EOF", self.n_line, self.n_column) elif (c == ' ' or c == '\t' or c == '\r'): estado = 1 elif (c == '\n'): estado = 1 self.n_line += 1 self.n_column = 0 elif (c.isalpha()): lexema += c estado = 2 elif (c.isdigit()): lexema += c estado = 5 elif (c == '"'): lexema += c estado = 11 elif (c == '-'): estado = 15 elif (c == '!'): estado = 16 elif (c == "<"): estado = 17 elif (c == ">"): estado = 20 elif (c == "="): estado = 23 elif (c == "/"): estado = 27 elif (c == "*"): estado = 28 elif (c == "+"): estado = 29 elif (c == "#"): estado = 31 elif (c == ","): estado = 32 elif (c == "."): estado = 33 elif (c == ":"): estado = 34 elif (c == ";"): estado = 35 elif (c == "("): estado = 36 elif (c == ")"): estado = 37 elif (c == "["): estado = 38 elif (c == "]"): estado = 39 else: self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) estado = 1 elif (estado == 2): if (c.isalnum()): lexema += c else: self.retornaPonteiro() token = self.ts.getToken(lexema) if (token is None): token = Token(Tag.ID, lexema, self.n_line, self.n_column) self.ts.addToken(lexema, token) self.lexemaAnt = lexema return token elif (estado == 5): if (c.isdigit() or c == '.'): lexema += c else: self.retornaPonteiro() if ('.' in lexema): token = self.ts.getToken(lexema) if (token is None): token = Token(Tag.DOUBLE, lexema, self.n_line, self.n_column) self.ts.addToken(lexema, token) self.lexemaAnt = lexema return token else: token = self.ts.getToken(lexema) if (token is None): token = Token(Tag.INTEGER, lexema, self.n_line, self.n_column) self.ts.addToken(lexema, token) self.lexemaAnt = lexema return token elif (estado == 11): if (c.isalnum() or c.isalpha() or c.isdigit() or c == '"' or c == " " or c == "!" or c == "," or c == "+" or c == "-" or c == "*" or c == "/" or c == "<" or c == "<=" or c == ">" or c == ">=" or c == "=" or c == "==" or c == "!" or c == "!=" or c == "(" or c == ':'): lexema += c else: self.retornaPonteiro() token = self.ts.getToken(lexema) if (token is None): token = Token(Tag.STRING, lexema, self.n_line, self.n_column) # self.ts.addToken(lexema, token) self.lexemaAnt = lexema return token elif (estado == 15): self.retornaPonteiro() if (self.lexemaAnt == ""): return Token(Tag.OP_UNARIO, "-", self.n_line, self.n_column) elif (self.lexemaAnt == "+" or self.lexemaAnt == "-" or self.lexemaAnt == "*" or self.lexemaAnt == "/" or self.lexemaAnt == "<" or self.lexemaAnt == "<=" or self.lexemaAnt == ">" or self.lexemaAnt == ">=" or self.lexemaAnt == "=" or self.lexemaAnt == "==" or self.lexemaAnt == "!" or self.lexemaAnt == "!=" or self.lexemaAnt == "("): return Token(Tag.OP_UNARIO, "-", self.n_line, self.n_column) elif (self.lexemaAnt.isalpha() or self.lexemaAnt.isalnum()): self.lexemaAnt = '-' return Token(Tag.OP_SUBTRACAO, "-", self.n_line, self.n_column) else: self.lexemaAnt = '-' return Token(Tag.OP_SUBTRACAO, "-", self.n_line, self.n_column) elif (estado == 16): if (c == '='): token = self.ts.getToken('!=') if (token is None): token = Token(Tag.OP_DIFERENTE, "!=", self.n_line, self.n_column) # self.ts.addToken('!=', token) self.lexemaAnt = '!=' return token else: self.retornaPonteiro() token = self.ts.getToken('!') if (token is None): token = Token(Tag.OP_UNARIO, "!", self.n_line, self.n_column) # self.ts.addToken('!', token) self.lexemaAnt = '!' return token elif (estado == 17): if (c == '='): token = self.ts.getToken('<=') if (token is None): token = Token(Tag.OP_MENOR_IGUAL, "<=", self.n_line, self.n_column) # self.ts.addToken('<=', token) self.lexemaAnt = '<=' return token else: self.retornaPonteiro() token = self.ts.getToken('<') if (token is None): token = Token(Tag.OP_MENOR, "<", self.n_line, self.n_column) # self.ts.addToken('<', token) self.lexemaAnt = '<' return token elif (estado == 20): if (c == '='): token = self.ts.getToken('>=') if (token is None): token = Token(Tag.OP_MAIOR_IGUAL, ">=", self.n_line, self.n_column) # self.ts.addToken('>=', token) self.lexemaAnt = '>=' return token else: self.retornaPonteiro() token = self.ts.getToken('>') if (token is None): token = Token(Tag.OP_MAIOR, ">", self.n_line, self.n_column) # self.ts.addToken('>', token) self.lexemaAnt = '>' return token elif (estado == 23): if (c == '='): token = self.ts.getToken('==') if (token is None): token = Token(Tag.OP_IGUAL, "==", self.n_line, self.n_column) # self.ts.addToken('==', token) self.lexemaAnt = '==' return token else: self.retornaPonteiro() token = self.ts.getToken('=') if (token is None): token = Token(Tag.OP_IGUAL, "=", self.n_line, self.n_column) # self.ts.addToken('=', token) self.lexemaAnt = '=' return token elif (estado == 27): self.retornaPonteiro() token = self.ts.getToken('/') if (token is None): token = Token(Tag.OP_DIVISAO, "/", self.n_line, self.n_column) # self.ts.addToken('/', token) self.lexemaAnt = '/' return token elif (estado == 28): self.retornaPonteiro() token = self.ts.getToken('*') if (token is None): token = Token(Tag.OP_PRODUTO, "*", self.n_line, self.n_column) # self.ts.addToken('*', token) self.lexemaAnt = '*' return token elif (estado == 29): self.retornaPonteiro() token = self.ts.getToken('+') if (token is None): token = Token(Tag.OP_ADICAO, "+", self.n_line, self.n_column) # self.ts.addToken('+', token) self.lexemaAnt = '+' return token elif (estado == 31): if (c == '\n' or c == ""): estado = 1 self.n_line += 1 self.n_column = 1 self.lexemaAnt = "" elif (estado == 32): self.retornaPonteiro() token = self.ts.getToken(',') if (token is None): token = Token(Tag.SIMB_VIRGULA, ",", self.n_line, self.n_column) # self.ts.addToken(',', token) self.lexemaAnt = ',' return token elif (estado == 33): self.retornaPonteiro() token = self.ts.getToken('.') if (token is None): token = Token(Tag.SIMB_PONTO, ".", self.n_line, self.n_column) # self.ts.addToken('.', token) self.lexemaAnt = '.' return token elif (estado == 34): self.retornaPonteiro() token = self.ts.getToken(':') if (token is None): token = Token(Tag.SIMB_DOIS_PONTOS, ":", self.n_line, self.n_column) # self.ts.addToken(':', token) self.lexemaAnt = ':' return token elif (estado == 35): self.retornaPonteiro() token = self.ts.getToken(';') if (token is None): token = Token(Tag.SIMB_PONTO_VIRGULA, ";", self.n_line, self.n_column) # self.ts.addToken(';', token) self.lexemaAnt = ';' return token elif (estado == 36): self.retornaPonteiro() token = self.ts.getToken('(') if (token is None): token = Token(Tag.SIMB_ABRE_PARENT, "(", self.n_line, self.n_column) # self.ts.addToken('(', token) self.lexemaAnt = '(' return token elif (estado == 37): self.retornaPonteiro() token = self.ts.getToken(')') if (token is None): token = Token(Tag.SIMB_FECHA_PARENT, ")", self.n_line, self.n_column) # self.ts.addToken(')', token) self.lexemaAnt = ')' return token elif (estado == 38): self.retornaPonteiro() token = self.ts.getToken('[') if (token is None): token = Token(Tag.SIMB_ABRE_CHAVE, "[", self.n_line, self.n_column) # self.ts.addToken('[', token) self.lexemaAnt = '[' return token elif (estado == 39): self.retornaPonteiro() token = self.ts.getToken(']') if (token is None): token = Token(Tag.SIMB_FECHA_CHAVE, "]", self.n_line, self.n_column) # self.ts.addToken(']', token) self.lexemaAnt = ']' return token self.n_column += 1
class Lexer(): ''' Classe que representa o Lexer: [1] Voce devera se preocupar quando incremetar as linhas e colunas, assim como quando decrementar ou reinicia-las. Lembre-se, ambas comecam em 1. [2] Toda vez que voce encontrar um lexema completo, voce deve retornar um objeto Token(Tag, "lexema", linha, coluna). Cuidado com as palavras reservadas, que ja sao cadastradas na TS. Essa consulta voce devera fazer somente quando encontrar um Identificador. [3] Se o caractere lido nao casar com nenhum caractere esperado, apresentar a mensagem de erro na linha e coluna correspondente. Obs.: lembre-se de usar o metodo retornaPonteiro() quando necessario. lembre-se de usar o metodo sinalizaErroLexico() para mostrar a ocorrencia de um erro lexico. ''' def __init__(self, input_file): try: self.input_file = open(input_file, 'rb') self.lookahead = 0 self.n_line = 1 self.n_column = 1 self.ts = TS() except IOError: print('Erro de abertura do arquivo. Encerrando execução!') sys.exit(0) def closeFile(self): try: self.input_file.close() except IOError: print('Erro dao fechar arquivo. Encerrando execução!') sys.exit(0) def sinalizaErroLexico(self, message): print("[Erro Lexico]: ", message, "\n"); def retornaPonteiro(self): if(self.lookahead.decode('ascii') != ''): self.input_file.seek(self.input_file.tell()-1) def printTS(self): self.ts.printTS() def proxToken(self): estado = 1 lexema = "" c = '\u0000' while(True): self.lookahead = self.input_file.read(1) c = self.lookahead.decode('ascii') if(estado == 1): if(c == ''): return Token(Tag.EOF, "EOF", self.n_line, self.n_column) elif(c == ' ' or c == '\t' or c == '\n' or c == '\r'): estado = 1 elif(c == '='): estado = 2 elif(c == '!'): estado = 4 elif(c == '<'): estado = 6 elif(c == '>'): estado = 9 elif(c.isdigit()): lexema += c estado = 12 elif(c.isalpha()): lexema += c estado = 14 elif(c == '/'): #estado = 16 return Token(Tag.OP_DIVISAO, "/", self.n_line, self.n_column) elif (c == '*'): #estado = 19 return Token(Tag.OP_MULTIPLICACAO, "*", self.n_line, self.n_column) elif (c == '+'): #estado = 20 return Token(Tag.OP_SOMA, "+", self.n_line, self.n_column) elif (c == '-'): #estado = 21 return Token(Tag.OP_SUBTRACAO, "-", self.n_line, self.n_column) elif (c == '('): #estado = 22 else: self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) return None elif(estado == 2): if(c == '='): #estado = 3 return Token(Tag.OP_IGUAL, "==", self.n_line, self.n_column) else: self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) return None elif(estado == 4): if(c == '='): #estado = 5 return Token(Tag.OP_DIFERENTE, "!=", self.n_line, self.n_column) else: self.sinalizaErroLexico("Caractere invalido [" + c + "] na linha " + str(self.n_line) + " e coluna " + str(self.n_column)) return None elif(estado == 6): if(c == '='): #estado = 7 return Token(Tag.OP_MENOR_IGUAL, "<=", self.n_line, self.n_column) else: #estado = 8 self.retornaPonteiro() return Token(Tag.OP_MENOR, "<", self.n_line, self.n_column) elif(estado == 9): if(c == '='): #estado = 10 return Token(Tag.OP_MAIOR_IGUAL, ">=", self.n_line, self.n_column) else: #estado = 11 self.retornaPonteiro() return Token(Tag.OP_MAIOR, ">", self.n_line, self.n_column) elif(estado == 12): if(c.isdigit()): #continua no estado 12 lexema += c else: #estado = 13 self.retornaPonteiro() return Token(Tag.NUM, lexema, self.n_line, self.n_column) elif(estado == 14): if(c.isalnum()): #continua no estado 14 lexema += c else: #estado = 15 self.retornaPonteiro() token = self.ts.getToken(lexema) if(token is None): token = Token(Tag.ID, lexema, self.n_line, self.n_column) self.ts.addToken(lexema, token) return token '''
class Parser(): def __init__(self, lexer): self.lexer = lexer self.token = lexer.proxToken( None) # Leitura inicial obrigatoria do primeiro simbolo self.last_token = None self.ts = TS() if self.token is None: # erro no Lexer sys.exit(0) def sinalizaErroSemantico(self, message): print("[Erro Semantico] na linha " + str(self.token.getLinha()) + " e coluna " + str(self.token.getColuna()) + ": ") print(message, "\n") def sinalizaErroSintatico(self, message): print("[Erro Sintatico] na linha " + str(self.token.getLinha()) + " e coluna " + str(self.token.getColuna()) + ": ") print(message, "\n") def advance(self): #print("[DEBUG] token: ", self.token.toString()) self.token = self.lexer.proxToken(self.last_token) self.last_token = self.token if self.token is None: # erro no Lexer sys.exit(0) def skip(self, message): self.sinalizaErroSintatico(message) self.advance() # verifica token esperado t def eat(self, t): if (self.token.getNome() == t): self.advance() return True else: return False """ LEMBRETE: Todas as decisoes do Parser, sao guiadas pela Tabela Preditiva (TP) """ # Programa -> Classe EOF def Programa(self): self.Classe() if (self.token.getNome() != Tag.EOF): self.sinalizaErroSintatico("Esperado \"EOF\"; encontrado " + "\"" + self.token.getLexema() + "\"") def Classe(self): # Classe -> "class" ID ":" ListaFuncao Main "end" "." tempToken = copy.copy( self.token ) # armazena token corrente (necessario para id da regra) if (self.eat(Tag.KW_CLASS)): if (not self.eat(Tag.ID)): self.sinalizaErroSintatico("Esperado \"ID\"; encontrado " + "\"" + self.token.getLexema() + "\"") else: self.lexer.ts.removeToken(tempToken.getLexema()) tempToken.setTipo(Tag.TIPO_VAZIO) self.lexer.ts.addToken(tempToken.getLexema(), tempToken) if (not self.eat(Tag.DP)): self.sinalizaErroSintatico("Esperado \":\"; encontrado " + "\"" + self.token.getLexema() + "\"") self.ListaFuncao() self.Main() if (not self.eat(Tag.KW_END)): self.sinalizaErroSintatico("Esperado \"END\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.KW_PONTO)): self.sinalizaErroSintatico("Esperado \".\"; encontrado " + "\"" + self.token.getLexema() + "\"") else: self.sinalizaErroSintatico("Esperado \"class\"; encontrado " + "\"" + self.token.getLexema() + "\"") def DeclaraID(self): # DeclaraID -> TipoPrimitivo ID ";" noTipoPrimitivo = self.TipoPrimitivo() tempToken = copy.copy( self.token ) # armazena token corrente (necessario para id da regra) if (self.eat(Tag.ID)): self.ts.setTipo(tempToken.getLexema(), noTipoPrimitivo.tipo) if (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \" ; \"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) else: self.sinalizaErroSintatico("Esperado \"ID\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) def ListaFuncao(self): # ListaFuncao -> ListaFuncao’ self.ListaFuncaoLinha() def ListaFuncaoLinha(self): # ListaFuncao’ -> Funcao ListaFuncao’ | ε if (self.token.getNome() == Tag.KW_DEF): self.Funcao() self.ListaFuncao() else: return def Funcao(self): # Funcao -> "def" TipoPrimitivo ID "(" ListaArg ")" ":" RegexDeclaraId ListaCmd Retorno "end" ";" tempToken = copy.copy( self.token ) # armazena token corrente (necessario para id da regra) if (self.eat(Tag.KW_DEF)): noTipoPrimitivo = self.TipoPrimitivo() if (not self.eat(Tag.ID)): self.sinalizaErroSintatico("Esperado \"ID\"; encontrado " + "\"" + self.token.getLexema() + "\"") else: self.lexer.ts.removeToken(tempToken.getLexema()) tempToken.setTipo(noTipoPrimitivo.tipo) self.lexer.ts.addToken(tempToken.getLexema(), tempToken) if (not self.eat(Tag.AP)): self.sinalizaErroSintatico("Esperado \"(\"; encontrado " + "\"" + self.token.getLexema() + "\"") self.ListaArg() if (not self.eat(Tag.FP)): self.sinalizaErroSintatico("Esperado \")\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.DP)): self.sinalizaErroSintatico("Esperado \":\"; encontrado " + "\"" + self.token.getLexema() + "\"") self.RegexDeclaraId() self.ListaCmd() noRetorno = self.Retorno() if (noRetorno.tipo != noTipoPrimitivo.tipo): self.sinalizaErroSemantico("Tipo de retorno incompativel.") if (not self.eat(Tag.KW_END)): self.sinalizaErroSintatico("Esperado \"end\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \";\"; encontrado " + "\"" + self.token.getLexema() + "\"") else: self.sinalizaErroSintatico("Esperado \"def\"; encontrado " + "\"" + self.token.getLexema() + "\"") def RegexDeclaraId(self): # RegexDeclaraId -> DeclaraID RegexDeclaraId | ε if (self.token.getNome() == Tag.KW_INTEGER or self.token.getNome() == Tag.KW_STRING or self.token.getNome() == Tag.KW_DOUBLE or self.token.getNome() == Tag.KW_VOID): self.DeclaraID() self.RegexDeclaraId() else: return def ListaArg(self): # ListaArg -> Arg ListaArg’ self.Arg() self.ListaArgLinha() def ListaArgLinha(self): # ListaArg’ -> "," ListaArg | ε if (self.eat(Tag.VG)): self.ListaArg() else: return def Arg(self): # Arg -> TipoPrimitivo ID tempToken = copy.copy( self.token ) # armazena token corrente (necessario para id da regra) noTipoPrimitivo = self.TipoPrimitivo() if (not self.eat(Tag.ID)): self.sinalizaErroSintatico("Esperado \"ID\"; encontrado " + "\"" + self.token.getLexema() + "\"") else: self.lexer.ts.removeToken(tempToken.getLexema()) tempToken.setTipo(noTipoPrimitivo.tipo) self.lexer.ts.addToken(tempToken.getLexema(), tempToken) def Retorno(self): # Retorno -> "return" Expressao ";" | ε noRetorno = No() if (self.eat(Tag.KW_RETURN)): noExpressao = self.Expressao() if (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \";\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) noRetorno.tipo = noExpressao.tipo return noRetorno else: noRetorno.tipo = Tag.TIPO_VAZIO return noRetorno def Main(self): # Main -> "defstatic" "void" "main" "(" "String" "[" "]" ID ")" ":" RegexDeclaraId ListaCmd "end" ";" tempToken = copy.copy( self.token ) # armazena token corrente (necessario para id da regra) if (self.eat(Tag.KW_DEFSTATIC)): if (not self.eat(Tag.KW_VOID)): self.sinalizaErroSintatico("Esperado \"void\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.KW_MAIN)): self.sinalizaErroSintatico("Esperado \"main\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.AP)): self.sinalizaErroSintatico("Esperado \"(\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.KW_STRING)): self.sinalizaErroSintatico("Esperado \"String\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.AT)): self.sinalizaErroSintatico("Esperado \"[\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.FT)): self.sinalizaErroSintatico("Esperado \"]\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.ID)): self.sinalizaErroSintatico("Esperado \"ID\"; encontrado " + "\"" + self.token.getLexema() + "\"") self.lexer.ts.removeToken(tempToken.getLexema()) tempToken.setTipo(Tag.TIPO_STRING) self.lexer.ts.addToken(tempToken.getLexema(), tempToken) if (not self.eat(Tag.FP)): self.sinalizaErroSintatico("Esperado \")\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.DP)): self.sinalizaErroSintatico("Esperado \":\"; encontrado " + "\"" + self.token.getLexema() + "\"") self.RegexDeclaraId() self.ListaCmd() if (not self.eat(Tag.KW_END)): self.sinalizaErroSintatico("Esperado \"end\"; encontrado " + "\"" + self.token.getLexema() + "\"") if (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \";\"; encontrado " + "\"" + self.token.getLexema() + "\"") else: self.sinalizaErroSintatico("Esperado \"defstatic\"; encontrado " + "\"" + self.token.getLexema() + "\"") def TipoPrimitivo(self): # TipoPrimitivo -> "bool" | "integer" | "String" | "double" | "void" noTipoPrimitivo = No() if (self.token.getNome() == Tag.KW_BOOL): self.eat(Tag.KW_BOOL) noTipoPrimitivo.tipo = Tag.TIPO_LOGICO elif (self.token.getNome() == Tag.KW_INTEGER): self.eat(Tag.KW_INTEGER) noTipoPrimitivo.tipo = Tag.TIPO_INT elif (self.token.getNome() == Tag.KW_STRING): self.eat(Tag.KW_STRING) noTipoPrimitivo.tipo = Tag.TIPO_STRING elif (self.token.getNome() == Tag.KW_DOUBLE): self.eat(Tag.KW_DOUBLE) noTipoPrimitivo.tipo = Tag.TIPO_DOUBLE elif (self.token.getNome() == Tag.KW_VOID): self.eat(Tag.KW_VOID) noTipoPrimitivo.tipo = Tag.TIPO_VAZIO else: self.sinalizaErroSintatico( "Esperado \"'bool' ou 'integer' ou 'String' ou 'double' ou 'void'\"; encontrado " + "\"" + self.token.getLexema() + "\"") return noTipoPrimitivo def ListaCmd(self): # ListaCmd -> ListaCmd’ self.ListaCmdLinha() def ListaCmdLinha(self): # ListaCmd’ -> Cmd ListaCmd’ | ε if (self.token.getNome() == Tag.KW_IF or self.token.getNome() == Tag.KW_WHILE or self.token.getNome() == Tag.ID or self.token.getNome() == Tag.KW_WRITE): self.Cmd() self.ListaCmdLinha() else: return def Cmd(self): # Cmd -> CmdIF | CmdWhile | ID CmdAtribFunc | CmdWrite tempToken = copy.copy( self.token ) # armazena token corrente (necessario para id da regra) if (self.token.getNome() == Tag.KW_IF): self.CmdIF() elif (self.token.getNome() == Tag.KW_WHILE): self.CmdWhile() elif (self.eat(Tag.ID)): if (tempToken.getTipo() == None): self.sinalizaErroSemantico("ID não declarado") sys.exit(0) noCmdAtribFunc = self.CmdAtribFunc() if (noCmdAtribFunc.tipo != Tag.TIPO_VAZIO and tempToken.getTipo() != noCmdAtribFunc.tipo): self.sinalizaErroSemantico("Atribuição incompativel") sys.exit(0) elif (self.token.getNome() == Tag.KW_WRITE): self.CmdWrite() else: self.sinalizaErroSintatico( "Esperado \"'if' ou 'while' ou 'ID' ou 'write'\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) def CmdAtribFunc(self): # CmdAtribFunc -> CmdAtribui | CmdFuncao noCmdAtribFunc = No() if (self.token.getNome() == Tag.CP): noCmdAtribui = self.CmdAtribui() noCmdAtribFunc.tipo = noCmdAtribui.tipo return noCmdAtribFunc elif (self.token.getNome() == Tag.AP): self.CmdFuncao() noCmdAtribFunc.tipo = Tag.TIPO_VAZIO return noCmdAtribFunc else: self.sinalizaErroSintatico("Esperado \"'=' ou '('\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) def CmdIF(self): # CmdIF -> "if" "(" Expressao ")" ":" ListaCmd CmdIF’ if (self.eat(Tag.KW_IF)): if (not self.eat(Tag.AP)): self.sinalizaErroSintatico("Esperado \"(\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) noExpressao = self.Expressao() if (not self.eat(Tag.FP)): self.sinalizaErroSintatico("Esperado \")\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) if (noExpressao.tipo != Tag.TIPO_LOGICO): self.sinalizaErroSemantico("Erro Semantico") sys.exit(0) elif (not self.eat(Tag.DP)): self.sinalizaErroSintatico("Esperado \":\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) self.ListaCmd() self.CmdIFLinha() else: self.sinalizaErroSintatico("Esperado \"if\"; encontrado " + "\"" + self.token.getLexema() + "\"") def CmdIFLinha(self): # CmdIF-> "end" ";" | "else" ":" ListaCmd "end" ";" if (self.eat(Tag.KW_END)): if (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \";\"; encontrado " + "\"" + self.token.getLexema() + "\"") elif (self.eat(Tag.KW_ELSE)): if (not self.eat(Tag.DP)): self.sinalizaErroSintatico("Esperado \":\"; encontrado " + "\"" + self.token.getLexema() + "\"") self.ListaCmd() if (not self.eat(Tag.KW_END)): self.sinalizaErroSintatico("Esperado \"end\"; encontrado " + "\"" + self.token.getLexema() + "\"") elif (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \";\"; encontrado " + "\"" + self.token.getLexema() + "\"") else: self.sinalizaErroSintatico( "Esperado \"'end' ou 'else'\"; encontrado " + "\"" + self.token.getLexema() + "\"") def CmdWhile(self): # CmdWhile -> "while" "(" Expressao ")" ":" ListaCmd "end" ";" if (self.eat(Tag.KW_WHILE)): if (not self.eat(Tag.AP)): self.sinalizaErroSintatico("Esperado \"(\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) noExpressao = self.Expressao() if (not self.eat(Tag.FP)): self.sinalizaErroSintatico("Esperado \")\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) if (noExpressao.tipo != Tag.TIPO_LOGICO): self.sinalizaErroSemantico("Erro Semantico") sys.exit(0) elif (not self.eat(Tag.DP)): self.sinalizaErroSintatico("Esperado \":\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) self.ListaCmd() if (not self.eat(Tag.KW_END)): self.sinalizaErroSintatico("Esperado \"end\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) elif (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \";\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) else: self.sinalizaErroSintatico("Esperado \"while\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) def CmdWrite(self): # CmdWrite -> "write" "(" Expressao ")" ";" if (self.eat(Tag.KW_WRITE)): if (not self.eat(Tag.AP)): self.sinalizaErroSintatico("Esperado \"(\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) noExpressao = self.Expressao() if (not self.eat(Tag.FP)): self.sinalizaErroSintatico("Esperado \")\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) elif (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \";\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) if (noExpressao.tipo != Tag.TIPO_STRING): self.sinalizaErroSemantico("Erro Semantico") sys.exit(0) else: self.sinalizaErroSintatico("Esperado \"write\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) def CmdAtribui(self): # CmdAtribui -> "=" Expressao ";" noCmdAtribui = No() if (self.eat(Tag.CP)): noExpressao = self.Expressao() if (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \";\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) noCmdAtribui.tipo = noExpressao.tipo return noCmdAtribui else: self.sinalizaErroSintatico("Esperado \"=\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) def CmdFuncao(self): # CmdFuncao → "(" RegexExp ")" ";" if (self.eat(Tag.AP)): self.RegexExp() if (not self.eat(Tag.FP)): self.sinalizaErroSintatico("Esperado \")\"; encontrado " + "\"" + self.token.getLexema() + "\"") elif (not self.eat(Tag.PV)): self.sinalizaErroSintatico("Esperado \";\"; encontrado " + "\"" + self.token.getLexema() + "\"") else: self.sinalizaErroSintatico("Esperado \"(\"; encontrado " + "\"" + self.token.getLexema() + "\"") def RegexExp(self): # RegexExp → Expressao RegexExp’ | ε if ((self.token.getNome() == Tag.ID) or (self.token.getNome() == Tag.OP_INVERSOR) or (self.token.getNome() == Tag.OP_NEGACAO) or (self.token.getNome() == Tag.AP) or (self.token.getNome() == Tag.KW_INTEGER) or (self.token.getNome() == Tag.KW_DOUBLE) or (self.token.getNome() == Tag.KW_STRING) or (self.token.getNome() == Tag.KW_TRUE) or (self.token.getNome() == Tag.KW_FALSE)): self.Expressao() self.RegexExpLinha() else: return def RegexExpLinha(self): # RegexExp’ → "," Expressao RegexExp’ | ε if (self.eat(Tag.VG)): self.Expressao() self.RegexExpLinha() else: return def Expressao(self): # Expressao -> Exp1 Exp’ noExpressao = No() noExp1 = self.Exp1() noExpLinha = self.ExpLinha() if (noExpLinha.tipo == Tag.TIPO_VAZIO): noExpressao.tipo = noExp1.tipo elif (noExpLinha.tipo == noExp1.tipo and noExpLinha.tipo == Tag.TIPO_LOGICO): noExpressao.tipo = Tag.TIPO_LOGICO else: noExpressao.tipo = Tag.TIPO_ERRO return noExpressao def ExpLinha(self): noExpLinha = No() # Exp’ -> "or" Exp1 Exp’ | "and" Exp1 Exp’ | ε if (self.eat(Tag.KW_OR) or self.eat(Tag.KW_AND)): noExp1 = self.Exp1() noExpLinhaFilho = self.ExpLinha() if (noExpLinhaFilho.tipo == Tag.TIPO_VAZIO and noExp1.tipo == Tag.TIPO_LOGICO): noExpLinha.tipo = Tag.TIPO_LOGICO elif (noExpLinhaFilho.tipo == noExp1.tipo and noExp1.tipo == Tag.TIPO_LOGICO): noExpLinha.tipo = Tag.TIPO_LOGICO else: noExpLinha.tipo = Tag.TIPO_ERRO return noExpLinha else: noExpLinha.tipo = Tag.TIPO_VAZIO return noExpLinha def Exp1(self): # Exp1 -> Exp2 Exp1’ noExp1 = No() noExp2 = self.Exp2() noExp1Linha = self.Exp1Linha() if (noExp1Linha.tipo == Tag.TIPO_VAZIO): noExp1.tipo = noExp2.tipo elif (noExp1Linha.tipo == noExp2.tipo and (noExp1Linha.tipo == Tag.TIPO_INT or noExp1Linha.tipo == Tag.TIPO_DOUBLE)): noExp1.tipo = Tag.TIPO_LOGICO else: noExp1.tipo = Tag.TIPO_ERRO return noExp1 def Exp1Linha(self): # Exp1’ -> "<" Exp2 Exp1’ | "<=" Exp2 Exp1’ | ">" Exp2 Exp1’ | ">=" Exp2 Exp1’ | "==" Exp2 Exp1’ | "!=" Exp2 Exp1’ | ε noExp1Linha = No() if (self.eat(Tag.OP_MENOR) or self.eat(Tag.OP_MAIOR_IGUAL) or self.eat(Tag.OP_MENOR_IGUAL) or self.eat(Tag.OP_MAIOR) or self.eat(Tag.OP_IGUAL) or self.eat(Tag.OP_DIFERENTE)): noExp2 = self.Exp2() noExp1LinhaFilho = self.Exp1Linha() if (noExp1LinhaFilho.tipo == Tag.TIPO_VAZIO and noExp2.tipo == Tag.TIPO_INT): noExp1Linha.tipo = Tag.TIPO_INT elif (noExp1LinhaFilho.tipo == Tag.TIPO_VAZIO and noExp2.tipo == Tag.TIPO_DOUBLE): noExp1Linha.tipo = Tag.TIPO_DOUBLE elif (noExp1LinhaFilho.tipo == noExp2.tipo and noExp2.tipo == Tag.TIPO_INT): noExp1Linha.tipo = Tag.TIPO_INT elif (noExp1LinhaFilho.tipo == noExp2.tipo and noExp2.tipo == Tag.TIPO_DOUBLE): noExp1Linha.tipo = Tag.TIPO_DOUBLE else: noExp1Linha.tipo = Tag.TIPO_ERRO return noExp1Linha else: noExp1Linha.tipo = Tag.TIPO_VAZIO return noExp1Linha def Exp2(self): #Exp2 -> Exp3 Exp2’ noExp2 = No() noExp3 = self.Exp3() noExp2Linha = self.Exp2Linha() if (noExp2Linha.tipo == Tag.TIPO_VAZIO): noExp2.tipo = noExp3.tipo elif (noExp2Linha.tipo == noExp3.tipo and noExp2Linha.tipo == Tag.TIPO_INT): noExp2.tipo = Tag.TIPO_INT elif (noExp2Linha.tipo == noExp3.tipo and noExp2Linha.tipo == Tag.TIPO_DOUBLE): noExp2.tipo = Tag.TIPO_DOUBLE else: noExp2.tipo = Tag.TIPO_ERRO return noExp2 def Exp2Linha(self): # Exp2’ -> "+" Exp3 Exp2’ | "-" Exp3 Exp2’ | ε noExp2Linha = No() if (self.eat(Tag.OP_SOMA) or self.eat(Tag.OP_MENOR)): noExp3 = self.Exp3() noExp2LinhaFilho = self.Exp2Linha() if (noExp2LinhaFilho.tipo == Tag.TIPO_VAZIO and noExp3.tipo == Tag.TIPO_INT): noExp2Linha.tipo = Tag.TIPO_INT elif (noExp2LinhaFilho.tipo == Tag.TIPO_VAZIO and noExp3.tipo == Tag.TIPO_DOUBLE): noExp2Linha.tipo = Tag.TIPO_DOUBLE elif (noExp2LinhaFilho.tipo == noExp3.tipo and noExp3.tipo == Tag.TIPO_INT): noExp2Linha.tipo = Tag.TIPO_INT elif (noExp2LinhaFilho.tipo == noExp3.tipo and noExp3.tipo == Tag.TIPO_DOUBLE): noExp2Linha.tipo = Tag.TIPO_DOUBLE else: noExp2Linha.tipo = Tag.TIPO_ERRO return noExp2Linha else: noExp2Linha.tipo = Tag.TIPO_VAZIO return noExp2Linha def Exp3(self): # Exp3 -> Exp4 Exp3’ noExp3 = No() noExp4 = self.Exp4() noExp3Linha = self.Exp3Linha() if (noExp3Linha.tipo == Tag.TIPO_VAZIO): noExp3.tipo = noExp4.tipo elif (noExp3Linha == noExp4.tipo and noExp3Linha.tipo == Tag.TIPO_INT): noExp3.tipo = Tag.TIPO_INT elif (noExp3Linha == noExp4.tipo and noExp3Linha.tipo == Tag.TIPO_DOUBLE): noExp3.tipo = Tag.TIPO_DOUBLE else: noExp3Linha.tipo = Tag.TIPO_ERRO return noExp3 def Exp3Linha(self): # Exp3’ -> "*" Exp4 Exp3’ | "/" Exp4 Exp3’ | ε noExp3Linha = No() if (self.eat(Tag.OP_MULTIPLICACAO) or self.eat(Tag.OP_DIVISAO)): noExp4 = self.Exp4() noExp3LinhaFilho = self.Exp3Linha() if (noExp3LinhaFilho.tipo == Tag.TIPO_VAZIO and noExp4.tipo == Tag.TIPO_INT): noExp3Linha.tipo = Tag.TIPO_INT elif (noExp3LinhaFilho.tipo == Tag.TIPO_VAZIO and noExp4.tipo == Tag.TIPO_DOUBLE): noExp3Linha.tipo = Tag.TIPO_DOUBLE elif (noExp3LinhaFilho.tipo == noExp4.tipo and noExp4.tipo == Tag.TIPO_INT): noExp3Linha.tipo = Tag.TIPO_INT elif (noExp3LinhaFilho.tipo == noExp4.tipo and noExp4.tipo == Tag.TIPO_DOUBLE): noExp3Linha.tipo = Tag.TIPO_DOUBLE else: noExp3Linha.tipo = Tag.TIPO_ERRO return noExp3Linha else: noExp3Linha.tipo = Tag.TIPO_VAZIO return noExp3Linha def Exp4(self): # Exp4 -> ID Exp4’ | ConstInteger | ConstDouble | ConstString | "true" | "false" | OpUnario Exp4 | "(" Expressao")" tempToken = copy.copy( self.token ) # armazena token corrente (necessario para id da regra) noExp4 = No() if (self.eat(Tag.ID)): self.Exp4Linha() noExp4.tipo = tempToken.getTipo() if (noExp4.tipo == None): noExp4.tipo = Tag.TIPO_ERRO self.sinalizaErroSemantico("Erro, ID nao declado") sys.exit(0) elif (self.token.getNome() == Tag.OP_INVERSOR or self.token.getNome() == Tag.OP_NEGACAO): noOpUnario = self.OpUnario() noExp4Filho = self.Exp4() if (noExp4Filho.tipo == noOpUnario.tipo and noOpUnario.tipo == Tag.TIPO_INT): noExp4Filho.tipo = Tag.TIPO_INT elif (noExp4Filho.tipo == noOpUnario.tipo and noOpUnario.tipo == Tag.TIPO_DOUBLE): noExp4Filho.tipo = Tag.TIPO_DOUBLE elif (noExp4Filho.tipo == noOpUnario.tipo and noOpUnario.tipo == Tag.TIPO_LOGICO): noExp4Filho.tipo = Tag.TIPO_LOGICO elif (self.eat(Tag.AP)): noExpressao = self.Expressao() if (not self.eat(Tag.FP)): self.sinalizaErroSintatico("Esperado \")\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) noExp4.tipo = noExpressao.tipo elif (self.eat(Tag.KW_INTEGER)): noExp4.tipo = Tag.TIPO_INT elif (self.eat(Tag.KW_DOUBLE)): noExp4.tipo = Tag.TIPO_DOUBLE elif (self.eat(Tag.KW_STRING)): noExp4.tipo = Tag.TIPO_STRING elif (self.eat(Tag.KW_TRUE) or self.eat(Tag.KW_FALSE)): noExp4.tipo = Tag.TIPO_LOGICO else: self.sinalizaErroSintatico( " Esperado \"'ID' ou 'Constante' ou '(' \"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) return noExp4 def Exp4Linha(self): # Exp4’ -> "(" RegexExp ")" | ε if (self.eat(Tag.AP)): self.RegexExp() if (not self.eat(Tag.FP)): self.sinalizaErroSintatico("Esperado \")\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) else: return def OpUnario(self): #OpUnario -> "-" | "!" noOpUnario = No() if (self.eat(Tag.OP_INVERSOR)): noOpUnario.tipo = Tag.TIPO_LOGICO elif (self.eat(Tag.OP_NEGACAO)): noOpUnario.tipo = Tag.TIPO_INT else: self.sinalizaErroSintatico("Esperado \"'-' ou '!'\"; encontrado " + "\"" + self.token.getLexema() + "\"") sys.exit(0) return noOpUnario
class vbiPES(object): def __init__(self): self.bits=None self.ts=TS() self.line_infos=[] self.pesInfos=[] #list of currentPES dict self.currentPES={} self.pesStat=[] # [ {pts:PTS,data:[(line_idx,data_type),(line_idx,data_type)]}, # {pts:PTS,data:[(line_idx,data_type),(line_idx,data_type)]}, # {pts:PTS,data:[(line_idx,data_type),(line_idx,data_type)]} ] def find_sync(self): return self.bits.find('0x000001bd') def parse_header(self): self.packet_start_code,self.stream_id,self.pes_packet_lentgh = self.bits.readlist('hex:24,hex:8,uint:16') #use le when generating from lib... #print 'packet_start_code 0x%s' %self.packet_start_code #print 'stream_id 0x%s' %self.stream_id #print 'pes_packet_lentgh %s' %self.pes_packet_lentgh #self.pesInfos.append(pesInfos) logging.debug('packet_start_code : 0x%s' %str(self.packet_start_code)) if (self.packet_start_code == '000001') : #000001 if(self.stream_id == 'bd' ): optional_pes_header_part,self.pes_header_data_length=self.bits.readlist('hex:16,uint:8') self.currentPES={} pesInfos={} pesInfos['optional_pes_header_part']=optional_pes_header_part pesInfos['pes_header_data_length']=self.pes_header_data_length #print 'optional_pes_header_part 0x%s' %optional_pes_header_part #print 'pes_header_data_length %s' %self.pes_header_data_length if self.pes_header_data_length>0: if optional_pes_header_part=='8480': # PTS field present if self.pes_header_data_length == 5: pts_field=self.bits.read('hex:40') #5*8 pesInfos['PTS']=pts_field elif self.pes_header_data_length == 36: pts_field=self.bits.read('hex:40') stuffing=self.bits.read('hex:248') pesInfos['PTS']=pts_field else: print 'error : pes_header_data_length %d' %self.pes_header_data_length pesInfos['error']='pes header data' elif optional_pes_header_part == '8401': if self.pes_header_data_length == 36: pesInfos['PTS']=self.bits.read('hex:288') else: print 'error : pes_header_data_length' pesInfos['error']='pes_header_data_length' else: print 'error optional_pes_header_part 0x%s, skipping %s bytes...' %(str(optional_pes_header_part),str(self.pes_header_data_length)) skip=self.pes_header_data_length*8 self.bits.read('hex:%s' %str(skip)) pesInfos['error']='error optional_pes_header_part 0x%s, skipping %s bytes...' %(str(optional_pes_header_part),str(self.pes_header_data_length)) self.currentPES['header']=pesInfos return True else: logging.error('VBI PES header : stream_id=0x%s' %self.stream_id) return False else: logging.error('VBI PES header : packet_start_code=0x%s at bytes %d/%d' %(self.packet_start_code,self.bits.bytepos,(len(self.bits)/8))) return False def parsePayload(self): self.data_identifier=self.bits.read('uint:8') logging.debug('data_identifier %s' %self.data_identifier) if self.data_identifier==16: #while self.parse_teletext_data()==True: # pass self.parse_teletext_data() #return successful or not? else: logging.warning('other data_identifier : %s , skipping bytes...' %str(self.data_identifier)) skip=self.bits.read('hex:%s' %str((self.pes_packet_lentgh-2-self.pes_header_data_length-2)*8)) return self.pes_packet_lentgh-2-self.pes_header_data_length-2 def parse_teletext_data(self): lenght=self.pes_packet_lentgh-2-self.pes_header_data_length-1-1 logging.debug('%s nb bytes to parse' %str(lenght)) self.line_infos=[] while lenght>0: if (self.bits.pos+(3*8)) < len(self.bits): data_unit_id,data_unit_lenght,reserved,field_parity,line = self.bits.readlist('hex:8,uint:8,bin:2,bin:1,uint:5') if data_unit_lenght == 0: print 'Error sync !?? Aborting... lenght=%s data_unit_id=%s' %(lenght,data_unit_id) return False logging.debug('data_unit_id %s ' %data_unit_id) logging.debug('data_unit_lenght %s ' %data_unit_lenght) logging.debug('line %s ' %line) if (self.bits.pos+((data_unit_lenght-1)*8)) < len(self.bits): data=self.bits.read('hex:%s' %str((data_unit_lenght-1)*8)) self.line_infos.append( (data_unit_id,data_unit_lenght,field_parity,line,data) ) lenght-=(data_unit_lenght+2) #self.print_line_infos() #store infos else: return False else: return False self.print_line_infos() return True def print_line_infos(self): logging.debug('### new PES') #add pes packet nb infos=[] self.currentPES['payload']=[] for data_unit_id,data_unit_lenght,field_parity,line,data in self.line_infos: if data_unit_id in data_unit_info.keys(): logging.debug('* found %s on line %s '%(data_unit_info[data_unit_id],line)) line_infos={} line_infos['data_unit_id']=data_unit_id line_infos['data_unit_lenght']=data_unit_lenght #if field_parity == 0 and (data_unit_id=='02' or data_unit_id=='03'): # line+=314 line_infos['line']=line #check fo doublon? line_infos['data']=data infos.append(line_infos) self.currentPES['payload']=infos #payload image number? #print data def fromFile(self,filepath): self.bits=bitstring.ConstBitStream(filename=filepath) #def analysefromES(self,filepath=None): #self.parsePayload() def analyse(self,filepath=None): #fromPES logging.info('PES analyse') if filepath !=None: self.fromFile(filepath) self.find_sync() #while self.bits.pos+48 < len(self.bits) : #6*8+4*8 while self.parse_header() == True: size=self.parsePayload() #better to return info dict self.pesInfos.append(self.currentPES) #print 'resyncing' #self.bits.pos+=8 #print self.bits.pos #print len(self.bits) def analyseFromTS(self,filepath,pid): data = self.ts.extract(pid=pid,infilepath=filepath) logging.info('TS extraction done') self.bits=bitstring.ConstBitStream(hex=data) #with open('vbipes.bin','wb') as f: # f.write(data) self.analyse() self.computeStat() def computeStat(self): pesStat=[] for pes in self.pesInfos: stat={} if 'header' in pes.keys(): if 'PTS' in pes['header'].keys(): stat['pts']=pes['header']['PTS'] else: stat['pts']=None else: stat['pts']=None data=[] if 'payload' in pes.keys(): for line_info in pes['payload']: data.append( (line_info['line'],line_info['data_unit_id']) ) stat['data']=data pesStat.append(stat) self.pesStat=pesStat # Write functions def writeES(self,filepath): logging.warning('ES stream writing not implemented yet...') pass def writePES(self,filepath): self.ts.writePES(filepath) #or write self.bits! def writeReport(self,filepath,mode='md'): logging.info('writeReport (%s): write %s pes infos' %(mode,str(len(self.pesInfos)))) logging.debug('write into %s' %str(os.path.basename(filepath))) if mode == 'md': with open(filepath,'a') as mdfile: pesidx=0 for pes in self.pesInfos: pesidx+=1 mdfile.write('* PES %s infos \n' %str(pesidx)) mdfile.write(' \n') if 'header' in pes.keys(): for key in pes['header'].keys(): mdfile.write(' %s : %s \n'%(key,pes['header'][key])) if 'payload' in pes.keys(): for line_info in pes['payload']: mdfile.write(' found %s on line %s : %s bytes \n'%(data_unit_info[line_info['data_unit_id']],line_info['line'],line_info['data_unit_lenght'])) mdfile.write(' \n') mdfile.close() # Check functions def checkDeltaPTS(self,valueInTick): delta=[] prev_pts=self.pesStat[0]['pts'] result=False status='no PTS found' for pes in self.pesStat[1:]: try: delta.append(long(pes['pts'],base=16)-long(prev_pts,base=16)) except : pass prev_pts=pes['pts'] if len(delta): logging.debug('Delta PTS min : %s' %str(min(delta))) logging.debug('Delta PTS max : %s' %str(max(delta))) if min(delta[1:])==long(valueInTick): result=True status='Min:%s / Max:%s' %( str(min(delta[1:])),str(max(delta[1:])) ) return (result,status) def checkDataUnit(self,value): result=False status='not found' return (result,status) def checkDataLine(self,lineNb,param,value): result=False status='not found' value_list=[] pes_idx=0 for pes in self.pesInfos: pes_idx+=1 if 'payload' in pes.keys(): for line_info in pes['payload']: if line_info['line']==int(lineNb): if int(line_info[param])==int(value): #print 'found param %s:%s' %(param,line_info[param]) value_list.append(True) if len(value_list)>0: result=True status='%d/%d' %(len(value_list),pes_idx) return (result,status) def check(self,action,lineNb=None,param=None,value=None,report=None): #available_action=['line','data_unit','PTS'] if action=='line': msg='line %d check if %s=%s...' %(int(lineNb),str(param),str(value)) res=self.checkDataLine(lineNb,param,value) elif action=='data_unit': msg='check if data_unit=%s...' %(str(value)) res=self.checkDataUnit(value) elif action=='PTS': msg='check if Delta PTS=%s...' %(str(value)) res=self.checkDeltaPTS(value) else: msg='Unknown check expression %s.Skipping.' %action return False logging.info(' %s : %s' %(str(msg),str(res)) ) if report!=None: md=' %s : %s\n' %(str(msg),str(res)) mdfile=open(report,'a') # codecs.open(report,'a','utf8') mdfile.write(md) #mdfile.write(' \n') mdfile.close() return res