class Sintatico: def __init__(self): self.lex = None self.token_atual = None self.tabela_simbolo = { 'PROGRAMA': 0, 'VARIAVEIS': 1, 'INTEIRO': 2, 'REAL': 3 , 'LOGICO': 4, 'CARACTER': 5, 'SE': 6, 'SENAO': 7, 'ENQUANTO': 8, 'LEIA': 9, 'ESCREVA': 10, 'FALSO': 11, 'VERDADEIRO': 12 } self.tabela_follow = { 'PROG': [tt.FIMARQ[0]], 'DECLS': [tt.ABRECH[0]], 'LIST_DECLS': [tt.ABRECH[0]], 'D': [tt.ABRECH[0]], 'DECL_TIPO': [tt.ID[0], tt.ABRECH[0]], 'LIST_ID': [tt.FECHAPAR[0], tt.DPONTOS[0]], 'E': [tt.FECHAPAR[0], tt.DPONTOS[0]], 'TIPO': [tt.PVIRG[0]], 'C_COMP': [tt.FIMARQ[0], tt.ENQUANTO[0], tt.ESCREVA[0], tt.ID[0], tt.LEIA[0], tt.SE[0], tt.SENAO[0], tt.FECHACH[0]], 'LISTA_COMANDOS': [tt.FECHACH[0]], 'G': [tt.FECHACH[0]], 'COMANDOS': [tt.ENQUANTO[0], tt.ESCREVA[0], tt.ID[0], tt.LEIA[0], tt.SE[0], tt.FECHACH[0]], 'IF': [tt.ENQUANTO[0], tt.ESCREVA[0], tt.ID[0], tt.LEIA[0], tt.SE[0], tt.FECHACH[0]], 'H': [tt.ENQUANTO[0], tt.ESCREVA[0], tt.ID[0], tt.LEIA[0], tt.SE[0], tt.FECHACH[0]], 'WHILE': [tt.ENQUANTO[0], tt.ESCREVA[0], tt.ID[0], tt.LEIA[0], tt.SE[0], tt.FECHACH[0]], 'READ': [tt.ENQUANTO[0], tt.ESCREVA[0], tt.ID[0], tt.LEIA[0], tt.SE[0], tt.FECHACH[0]], 'ATRIB': [tt.ENQUANTO[0], tt.ESCREVA[0], tt.ID[0], tt.LEIA[0], tt.SE[0], tt.FECHACH[0]], 'WRITE': [tt.ENQUANTO[0], tt.ESCREVA[0], tt.ID[0], tt.LEIA[0], tt.SE[0], tt.FECHACH[0]], 'LIST_W': [tt.FECHAPAR[0]], 'L': [tt.FECHAPAR[0]], 'ELEM_W': [tt.FECHAPAR[0], tt.VIRG[0]], 'EXPR': [tt.FECHAPAR[0], tt.VIRG[0], tt.PVIRG[0]], 'P': [tt.FECHAPAR[0], tt.VIRG[0], tt.PVIRG[0]], 'SIMPLES': [tt.FECHAPAR[0], tt.VIRG[0], tt.PVIRG[0], tt.OPREL[0]], 'R': [tt.FECHAPAR[0], tt.VIRG[0], tt.PVIRG[0], tt.OPREL[0]], 'TERMO': [tt.FECHAPAR[0], tt.VIRG[0], tt.PVIRG[0], tt.OPAD[0], tt.OPREL[0]], 'S': [tt.FECHAPAR[0], tt.VIRG[0], tt.PVIRG[0], tt.OPAD[0], tt.OPREL[0]], 'FAT': [tt.OPAD[0], tt.OPMUL[0]], } def interprete(self, arquivo): if not self.lex is None: print('ERRO: Já existe um arquivo sendo processado.') else: self.lex = Lexico(arquivo) self.lex.abre_arquivo() self.token_atual = self.lex.get_token() self.A() self.consome( tt.FIMARQ ) self.lex.fecha_arquivo() def atual_igual(self, token): (const, msg) = token return self.token_atual.const == const def consome(self, token): if self.atual_igual( token ): self.token_atual = self.lex.get_token() if self.token_atual.const == tt.ID[0] and (self.token_atual.lexema not in self.tabela_simbolo): self.tabela_simbolo[self.token_atual.lexema] = (self.token_atual.const, self.token_atual.msg, self.token_atual.linha) else: (const, msg) = token self.erro( msg ) def erro(self, esperado): print('ERRO DE SINTAXE [linha %d]: era esperado "%s" mas veio "%s"' % (self.token_atual.linha, esperado, self.token_atual.lexema)) raise def sincroniza(self, follow): #print(follow) follow_list = self.tabela_follow[follow] while True: #print(self.token_atual.lexema) self.token_atual = self.lex.get_token() if self.token_atual.const in follow_list: # SINCRONIZOU #print(self.token_atual.lexema) break def A(self): try: self.PROG() self.consome( tt.FIMARQ ) except: quit() def PROG(self): try: self.consome( tt.PROGRAMA ) self.consome( tt.ID ) self.consome( tt.PVIRG ) self.DECLS() self.C_COMP() except: self.sincroniza('PROG') def DECLS(self): try: if self.atual_igual( tt.VARIAVEIS ): self.consome( tt.VARIAVEIS ) self.LIST_DECLS() else: pass except: self.sincroniza('DECLS') def LIST_DECLS(self): try: self.DECL_TIPO() self.D() except: self.sincroniza('LIST_DECLS') def D(self): try: if self.atual_igual( tt.ID ): self.LIST_DECLS() else: pass except: self.sincroniza('D') def DECL_TIPO(self): try: self.LIST_ID() self.consome( tt.DPONTOS ) if self.TIPO(): self.erro( 'tipo' ) self.consome( tt.PVIRG ) except: self.sincroniza('DECL_TIPO') def LIST_ID(self): try: self.consome( tt.ID ) self.E() except: self.sincroniza('LIST_ID') def E(self): try: if self.atual_igual( tt.VIRG ): self.consome( tt.VIRG ) self.LIST_ID() else: pass except: self.sincroniza('E') def TIPO(self): try: if self.atual_igual( tt.INTEIRO ): self.consome( tt.INTEIRO ) elif self.atual_igual( tt.REAL ): self.consome( tt.REAL ) elif self.atual_igual( tt.LOGICO ): self.consome( tt.LOGICO ) elif self.atual_igual( tt.CARACTER ): self.consome( tt.CARACTER ) else: return True except: self.sincroniza('TIPO') def C_COMP(self): try: self.consome( tt.ABRECH ) self.LISTA_COMANDOS() self.consome( tt.FECHACH ) except: self.sincroniza('C_COMP') def LISTA_COMANDOS(self): try: if self.COMANDOS(): self.erro( 'comando' ) self.G() except: self.sincroniza('LISTA_COMANDOS') def G(self): try: if self.atual_igual( tt.SE ) or self.atual_igual( tt.ENQUANTO ) or self.atual_igual( tt.LEIA ) or self.atual_igual( tt.ESCREVA ) or self.atual_igual( tt.ID ): self.LISTA_COMANDOS() else: pass except: self.sincroniza('G') def COMANDOS(self): try: if self.atual_igual( tt.SE ): self.IF() elif self.atual_igual( tt.ENQUANTO ): self.WHILE() elif self.atual_igual( tt.LEIA ): self.READ() elif self.atual_igual( tt.ESCREVA ): self.WRITE() elif self.atual_igual( tt.ID ): self.ATRIB() else: return True except: self.sincroniza('COMANDOS') def IF(self): try: self.consome( tt.SE ) self.consome( tt.ABREPAR ) self.EXPR() self.consome( tt.FECHAPAR ) self.C_COMP() self.H() except: self.sincroniza('IF') def H(self): try: if self.atual_igual( tt.SENAO ): self.consome( tt.SENAO ) self.C_COMP() else: pass except: self.sincroniza('H') def WHILE(self): try: self.consome( tt.ENQUANTO ) self.consome( tt.ABREPAR ) self.EXPR() self.consome( tt.FECHAPAR ) self.C_COMP() except: self.sincroniza('WHILE') def READ(self): try: self.consome( tt.LEIA ) self.consome( tt.ABREPAR ) self.LIST_ID() self.consome( tt.FECHAPAR ) self.consome( tt.PVIRG ) except: self.sincroniza('READ') def ATRIB(self): try: self.consome( tt.ID ) self.consome( tt.ATRIB ) self.EXPR() self.consome( tt.PVIRG ) except: self.sincroniza('ATRIB') def WRITE(self): try: self.consome( tt.ESCREVA ) self.consome( tt.ABREPAR ) self.LIST_W() self.consome( tt.FECHAPAR ) self.consome( tt.PVIRG ) except: self.sincroniza('WRITE') def LIST_W(self): try: if self.ELEM_W(): self.erro( 'expreção ou cadeia' ) self.L() except: self.sincroniza('LIST_W') def L(self): try: if self.atual_igual( tt.VIRG ): self.consome( tt.VIRG ) self.LIST_W() else: pass except: self.sincroniza('L') def ELEM_W(self): try: if self.atual_igual( tt.ID ) or self.atual_igual( tt.CTE ) or self.atual_igual( tt.ABREPAR ) or self.atual_igual( tt.VERDADEIRO ) or self.atual_igual( tt.FALSO ) or self.atual_igual( tt.OPNEG ): self.EXPR() elif self.atual_igual( tt.CADEIA ): self.consome( tt.CADEIA ) else: return True except: self.sincroniza('ELEM_W') def EXPR(self): try: self.SIMPLES() self.P() except: self.sincroniza('EXPR') def P(self): try: if self.atual_igual( tt.OPREL ): self.consome( tt.OPREL ) self.SIMPLES() else: pass except: self.sincroniza('P') def SIMPLES(self): try: self.TERMO() self.R() except: self.sincroniza('SIMPLES') def R(self): try: if self.atual_igual( tt.OPAD ): self.consome( tt.OPAD ) self.SIMPLES() else: pass except: self.sincroniza('R') def TERMO(self): try: if self.FAT(): self.erro( 'FAT' ) self.S() except: self.sincroniza('TERMO') def S(self): try: if self.atual_igual( tt.OPMUL ): self.consome( tt.OPMUL ) self.TERMO() else: pass except: self.sincroniza('S') def FAT(self): try: if self.atual_igual( tt.ID ): self.consome( tt.ID ) elif self.atual_igual( tt.CTE ): self.consome( tt.CTE ) elif self.atual_igual( tt.ABREPAR ): self.consome( tt.ABREPAR ) self.EXPR() self.consome( tt.FECHAPAR ) elif self.atual_igual( tt.VERDADEIRO ): self.consome( tt.VERDADEIRO ) elif self.atual_igual( tt.FALSO ): self.consome( tt.FALSO ) elif self.atual_igual( tt.OPNEG ): self.consome( tt.OPNEG ) if self.FAT(): self.erro( 'FAT' ) else: return True except: self.sincroniza('FAT')