class Compiler: def __init__(self, archive): self.reader = Reader(32, archive) self.row = 1 self.col = 1 self.tokens = [] self.word = '' # Monta os AFDs a partir da tabela de símbolos da linguagem def init_afds(self): self.lexers = [] for sym in LEX_RULES: lex = list(sym.keys())[0] p_type = list(sym.values())[0] self.lexers.append((Token(p_type, lex, 0, 0), Lex(sym["AFD"]))) # Percorre os AFDs para validar uma entrada def find_token(self, p_word): c_row = copy.copy(self.row) c_col = copy.copy(self.col) token = Token('#ERROR', p_word, c_row, c_col) for lex in self.lexers: if lex[1].testing(list(p_word)): token = lex[0] token.lex = p_word token.row = c_row token.colunm = c_col break return token def parse_lex(self): while self.reader.end_of_archive(): # pede um caracter do buffer char = self.reader.pull_buffer() # remove espaços em branco mas conta como coluna if char == ' ': if self.word != '': self.tokens.append(copy.copy(self.find_token(self.word))) self.col += len(self.word) self.word = '' self.col += 1 continue # identifica o tab e conta como 4 colunas if char == '\t': self.col += 4 continue # identifica quebra de linha, acrescenta a linha e zera a coluna if char == '\n': if self.word != '': self.tokens.append(copy.copy(self.find_token(self.word))) self.col += len(self.word) self.word = '' self.row += 1 self.col = 1 continue # testa os tokens usando o carcter char que veio do buffer test_char = self.find_token(char) if test_char.type == '#ERROR': print("Erro LÉXICO na linha", test_char.row, \ "coluna", test_char.colunm, \ "\nInstrução :", *test_char.lex) return None # identifica que o char é um token, grava a word anterior ao char como identificador if test_char.type != '#ERROR' and test_char.type != '#IDENTIFIER': if self.word != '': self.tokens.append(copy.copy(self.find_token(self.word))) self.col += len(self.word) self.word = '' self.word += char test_word = self.find_token(self.word) if test_word.type != '#ERROR' and test_word.type != '#IDENTIFIER': self.tokens.append(copy.copy(test_word)) self.col += len(self.word) self.word = '' def parse_syntatic(self): self.instructions = [] syntatic = SyntaticParser() token = copy.copy(self.tokens.pop(0)) sentence = [] sentence_lex = [] while self.tokens: initial_token = token sentence_lex.append(token.lex) sentence.append(token.type) new_token = copy.copy(self.tokens.pop(0)) if (token.row != new_token.row) or not self.tokens: instruction = syntatic.analyze(sentence, sentence_lex) if instruction: self.instructions.append(instruction) else: print("Erro sintático na linha", initial_token.row, \ "coluna", initial_token.colunm, \ "\nInstrução :", *sentence_lex) return None sentence.clear() sentence_lex.clear() token = new_token else: token = new_token