Browse Source

Add files via upload

Nicolas T. Cuerbas 1 year ago
parent
commit
7b6c2de4af
No account linked to committer's email address
13 changed files with 2727 additions and 0 deletions
  1. 80
    0
      Geracaodecodigo.py
  2. 71
    0
      beuty.py
  3. BIN
      dicionario1.dtc
  4. BIN
      dicionario2.dtc
  5. 18
    0
      fatorial.txt
  6. 37
    0
      infixtoposfix.py
  7. 19
    0
      intermediario.s
  8. 63
    0
      lexical.py
  9. 18
    0
      main.py
  10. 48
    0
      selection.py
  11. 58
    0
      semantico.py
  12. 66
    0
      sintatico.py
  13. 2249
    0
      tabela.html

+ 80
- 0
Geracaodecodigo.py View File

@@ -0,0 +1,80 @@
1
+'''
2
+    intermediario(token, argumentos, posicao inicial que deseja converter para assembler, posição final, valor inicial das Labels dos loops, texto final)
3
+'''
4
+def intemerdiario(token,args, inicio, fim, loop,condicional, texto):
5
+    L=loop
6
+    C=condicional
7
+    i=inicio
8
+    while i < fim :
9
+        if 'inteiro' in token[i][0]:
10
+            texto.extend(variaveis(token,i))
11
+        elif 'leia' in token[i][0]:
12
+            texto.append('LEIA '+token[i+2][1])
13
+        elif 'escreva' in token[i][0]:
14
+            texto.append('ESCREVA '+ token[i+2][1])
15
+        elif 'recebe' in token[i][0]:
16
+            exp=[]
17
+            from infixtoposfix import infixToPostfix
18
+            exp.append(infixToPostfix(expressao(token, i)))
19
+            simpleexpre(exp,token[i-1][1],texto)
20
+        elif 'enquanto' in token[i][0]:
21
+            texto.append(f'_L{L}: if {token[i+2][1]}'+ (' >' if '<' in token[i+3][1] else ' <')+f' {token[i+4][1]} goto _L{L+1} ')
22
+            i=intemerdiario(token, args, i+6, fim, L+1, C, texto)
23
+            texto.append(f'_L{L+1}:')
24
+            L=L+i
25
+            C=L
26
+        elif 'se' == token[i][0]:
27
+            texto.append(f'_C{C} if {token[i+2][1]} {token[i+3][1]} {token[i+4][1]} goto _C{C+1}')
28
+            i=intemerdiario(token, args, i+6, fim, L, C+1, texto)
29
+            texto.append(f'_C{L+1}:')
30
+            C = C + i
31
+            L = C
32
+        elif '}' in token[i][1]:
33
+            return i
34
+        i=i+1
35
+
36
+    with open('intermediario.s','w') as f:
37
+        f.write('\n'.join(texto))
38
+    #print (texto)
39
+def simpleexpre(exp,var,texto):
40
+    '''
41
+    ADD dest,src1,src2	dest = src1 + src2
42
+    SUB dest,src1,src2	dest = src1 - src2
43
+    ADDI dest,src1,I	dest = src1 + I
44
+    MUL dest,src1,src2	dest = src1 × src2
45
+    DIV[U] dest,src1,src2	dest = src1/src2
46
+    '''
47
+    t=1
48
+    exp=exp[0].split()
49
+    values=[]
50
+    operador=['+','-','*','/']
51
+    for i in range(len(exp)):
52
+        if exp[i] in operador:
53
+            a = values.pop()
54
+            b = values.pop()
55
+            if i == len(exp)-1:
56
+                texto.append(f'{var} := {b} {a} {exp[i]}')
57
+            else:
58
+                texto.append(f'T{t} := {b} {a} {exp[i]}')
59
+                values.append(f'T{t}')
60
+                t+=1
61
+        else:
62
+            values.append(exp[i])
63
+    if len(values) > 0:
64
+        texto.append(f'{var} := {values[0]}')
65
+
66
+def expressao(token, i):
67
+    l=i+1
68
+    var=[]
69
+    while not('fim_linha' in token[l][0]):
70
+        var.append(token[l][1])
71
+        l+=1
72
+    return ' '.join(var)
73
+def variaveis(token,i):
74
+    l=i+1
75
+    var=[]
76
+    while not('fim_linha' in token[l][0]):
77
+        if not('virgula' in token[l][0]):
78
+            var.append('INTEIRO '+token[l][1])
79
+        l+=1
80
+    return var

+ 71
- 0
beuty.py View File

@@ -0,0 +1,71 @@
1
+def beut(tabela1, tabela2):
2
+    from bs4 import BeautifulSoup
3
+    with open('tabela.html', 'r') as file:
4
+        soup = BeautifulSoup(file, "html5lib")
5
+        soup.prettify()#reorganiza as tags
6
+
7
+        tabela_all = soup.find_all('tbody')
8
+
9
+        coluna1 = tabela_all[0].find_all('tr')
10
+        coluna2 = tabela_all[1].find_all('tr')
11
+
12
+        valores_return(coluna1, tabela1)
13
+        valores_return(coluna2, tabela2)
14
+
15
+
16
+def valores_return(colunas, tabela):
17
+
18
+    for coluna in colunas:
19
+        celula = coluna.find_all('td')
20
+        celula = [ele.text.strip() for ele in celula]
21
+        tabela.append([ele for ele in celula if ele])
22
+
23
+def separar(palavra):
24
+    numero = []
25
+    for word in palavra:
26
+        if word.isdigit():
27
+            numero += word
28
+    return (''.join(numero))
29
+
30
+def initsintatico(token, args):
31
+    import os
32
+    if not(os.path.isfile('dicionario1.dtc')and os.path.isfile('dicionario2.dtc')):
33
+        save()
34
+
35
+    from sintatico import analisadorsintatico
36
+    dict_tabela1 = load("dicionario1.dtc")
37
+    dict_tabela2 = load("dicionario2.dtc")
38
+    analisadorsintatico(dict_tabela1, dict_tabela2, token, args)
39
+
40
+def load(filename):
41
+    import pickle
42
+    file = open(filename, "rb")
43
+    return pickle.load(file)
44
+
45
+def save():
46
+    tabela1 = []
47
+    tabela2 = []
48
+    beut(tabela1, tabela2)
49
+    topo = tabela1[0]
50
+    del tabela1[0]
51
+    dict_tabela1 = {}
52
+    dict_tabela2 = {}
53
+    for linhas in tabela1:
54
+        i = 0;
55
+        for linha in linhas:
56
+            if linha.isdigit() and i <= len(topo):
57
+                dict_tabela1[(linhas[0], topo[i - 1])] = [int(linha)]
58
+            i += 1
59
+    for i in range(len(tabela2)):
60
+        if (((tabela2[i][1]).split('::= '))[1]).split(" ")[0] != 'î':
61
+            dict_tabela2[int(separar(tabela2[i][0]))] = ((((tabela2[i][1]).split('::= '))[1]).split())
62
+        else:
63
+            dict_tabela2[int(separar(tabela2[i][0]))] = []
64
+    saveFile(dict_tabela1, "dicionario1.dtc")
65
+    saveFile(dict_tabela2, "dicionario2.dtc")
66
+
67
+def saveFile(dict, filename):
68
+    import pickle
69
+    dicionario = open(filename, "wb")
70
+    pickle.dump(dict, dicionario)
71
+    dicionario.close()

BIN
dicionario1.dtc View File


BIN
dicionario2.dtc View File


+ 18
- 0
fatorial.txt View File

@@ -0,0 +1,18 @@
1
+programa
2
+inteiro var1, var2;
3
+escreva("Escreva um numero: ");
4
+leia(var1);
5
+var2 = 1;
6
+se(1<1){
7
+    enquanto(var1 > 1){
8
+        var2 = var1 / var2 * 1 + 2;
9
+        var1 = var1 - 1;
10
+     }
11
+}
12
+enquanto(2>1){
13
+    escreva("a");
14
+}
15
+escreva("fatorial de: ");
16
+escreva(var1);
17
+escreva("\n");
18
+fimprograma

+ 37
- 0
infixtoposfix.py View File

@@ -0,0 +1,37 @@
1
+'''
2
+Codigo retirado do livro: Problem Solving with Algorithms and Data Structures using Python
3
+pelo link: http://interactivepython.org/runestone/static/pythonds/BasicDS/InfixPrefixandPostfixExpressions.html
4
+e modificado por: Nicolas T. Cuerbas
5
+'''
6
+
7
+def infixToPostfix(infixexpr):
8
+    prec = {}
9
+    prec["*"] = 3
10
+    prec["/"] = 3
11
+    prec["+"] = 2
12
+    prec["-"] = 2
13
+    prec[">"] = 2
14
+    prec["<"] = 2
15
+    prec["("] = 1
16
+    opStack = []
17
+    postfixList = []
18
+    tokenList = infixexpr.split()
19
+
20
+    for token in tokenList:
21
+        if token.isidentifier() or token.isdigit():
22
+            postfixList.append(token)
23
+        elif token == '(':
24
+            opStack.extend(token)
25
+        elif token == ')':
26
+            topToken = opStack.pop()
27
+            while topToken != '(':
28
+                postfixList.append(topToken)
29
+                topToken = opStack.pop()
30
+        else:
31
+            while (not len(opStack)==0) and (prec[opStack[-1]] >= prec[token]):
32
+                  postfixList.append(opStack.pop())
33
+            opStack.extend(token)
34
+
35
+    while not (len(opStack)==0):
36
+        postfixList.append(opStack.pop())
37
+    return " ".join(postfixList)

+ 19
- 0
intermediario.s View File

@@ -0,0 +1,19 @@
1
+INTEIRO var1
2
+INTEIRO var2
3
+ESCREVA "Escreva um numero: "
4
+LEIA var1
5
+var2 := 1
6
+_C0 if 1 < 1 goto _C1
7
+_L0: if var1 < 1 goto _L1 
8
+T1 := var1 var2 /
9
+T2 := T1 1 *
10
+var2 := T2 2 +
11
+var1 := var1 1 -
12
+_L1:
13
+_C1:
14
+_L51: if 2 < 1 goto _L52 
15
+ESCREVA "a"
16
+_L52:
17
+ESCREVA "fatorial de: "
18
+ESCREVA var1
19
+ESCREVA "\n"

+ 63
- 0
lexical.py View File

@@ -0,0 +1,63 @@
1
+import collections
2
+import re
3
+def tokenize(code,args):
4
+    token = collections.namedtuple('Token', ['tipo', 'lexema', 'linha', 'coluna'])
5
+    token_especificacao = [
6
+        ('inicio'       ,r'\{'), #inicio {
7
+        ('fim'          ,r'\}'), # fim }
8
+        ('a_parentese'  ,r'\('), #parentese de abertura
9
+        ('f_parentese'  ,r'\)'), #parentese de fechamento
10
+        ('leia'         ,r'leia'), #leia
11
+        ('escreva'      ,r'escreva'), #escreva
12
+        ('se'           ,r'se'), #se
13
+        ('senao'        ,r'senao'), #senao
14
+        ('enquanto'     ,r'enquanto'), #enquanto
15
+        ('programa'     ,r'programa'), #programa
16
+        ('fimprograma'  ,r'fimprograma'), #fimprograma
17
+        ('inteiro'      ,r'inteiro'),     #variavel
18
+        ('numero'       ,r'[+-]?[0-9]+'),  # inteiro
19
+        ("fim_linha"    ,r';'), #fim de linha
20
+        ("virgula"      ,r','), # virgula
21
+        ('recebe'       ,r'='),           # recebe
22
+        ('id'           ,r'[A-Za-z]([A-Za-z0-9_])*'),    # Id
23
+        ('subtracao'    ,r'\-'),            #subtração
24
+        ('soma'         ,r'\+'),           #soma
25
+        ('multiplicacao',r'\*'),            #multiplicação
26
+        ('divisao'      ,r'/'),             #divisão
27
+        ('WS'           ,r' +'),           # espaço
28
+        ('menor'        ,r'<'),             #operadore lógico menor
29
+        ('maior'        ,r'>'),             #operador lógico maior
30
+        ('frase'        ,r'".*?"'),         #frase
31
+        ('ERRO'         ,r'.'),            # qualquer caracter não identificado
32
+        ('Linha'        ,r'\n'),	    #fim de linha
33
+    ]
34
+
35
+    token_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_especificacao)
36
+    linha = 1
37
+    linha_inicia = 0
38
+    for mo in re.finditer(token_regex, code):
39
+        tipo = mo.lastgroup
40
+        valor = mo.group(tipo)
41
+        if (tipo == 'Linha'):
42
+            linha_inicia = mo.end()
43
+            linha += 1
44
+        elif tipo == 'tab':
45
+            pass
46
+        elif tipo == 'ERRO':
47
+
48
+            from colorama import Fore, Style
49
+            t=Fore.CYAN+'########################################################'
50
+            print(t)
51
+            print(f'{valor!r} não esperado na linha {linha} e coluna {coluna}\a\a')
52
+            print(t)
53
+            print(f'Erro lexico')
54
+            args.lt=False
55
+            if valor == '"':
56
+                print(f'" de fechamento não encontrada'+Style.RESET_ALL)
57
+            else:
58
+                print(f'caracter desconhecido')
59
+                print(Style.RESET_ALL)
60
+            pass
61
+        coluna = mo.start() - linha_inicia
62
+        if (tipo != 'ERRO') and (tipo != 'Linha') and (tipo != 'WS'):
63
+            yield token(tipo, valor, linha, coluna)

+ 18
- 0
main.py View File

@@ -0,0 +1,18 @@
1
+def main():
2
+
3
+    parser = argparse.ArgumentParser(description='Compilador para uma linguagem do tipo LL(1)')
4
+    parser.add_argument("-lt", help="Mostra o LOG de Tokens e Lexemas do analisador lexico", action='store_true')
5
+    parser.add_argument("-ls", help="Mostra o Log das operações do analisador sintatico", action='store_true')
6
+    parser.add_argument("-lse", help="Mostra o Log das operações do analisador semantico", action='store_true')
7
+    parser.add_argument("-lgc", help="Mostra o Log da geração de codigo", action='store_true')
8
+    parser.add_argument("filename", type=str, help="Filename")
9
+    parser.add_argument('-tudo', help='Show all logs', action='store_true')
10
+    args=parser.parse_args()
11
+    opction(args)
12
+
13
+#executa a funcao main()
14
+if __name__ == "__main__":
15
+    import sys
16
+    import argparse
17
+    from selection import opction
18
+    main()

+ 48
- 0
selection.py View File

@@ -0,0 +1,48 @@
1
+def opction(args):
2
+    token = []
3
+    if args.tudo:
4
+        args.lt=True
5
+        args.ls=True
6
+        args.lse=True
7
+        args.lgc=True
8
+    if args.lt:
9
+        vlt(args.filename,token,args)
10
+    else:
11
+        lt(args.filename,token,args)
12
+    ls(token,args)
13
+    lse(token,args)
14
+    lgc(token,args)
15
+
16
+def vlt(filename,token,args):
17
+    from lexical import tokenize
18
+    print ('#' * 80)
19
+    file = open(filename, "r")
20
+    arquivo = file.read()
21
+    file.close()
22
+    print('{:15}'.format('Token'), '{:29}'.format('Lexema'), '{:10}'.format('Linha'), '{:10}'.format('Coluna'))
23
+    i = 0
24
+    for tok in tokenize(arquivo,args):
25
+        token.append(tok)
26
+        print('{:15}'.format(token[i][0]), '{:20.11}'.format(token[i][1]), '{:10}'.format(token[i][2]),
27
+              '{:10}'.format(token[i][3]))
28
+        i += 1
29
+def lt(filename, token, args):
30
+    from lexical import tokenize
31
+    file = open(filename, "r")
32
+    arquivo = file.read()
33
+    file.close()
34
+    for tok in tokenize(arquivo,args):
35
+        token.append(tok)
36
+def ls(token,args):
37
+    from beuty import initsintatico
38
+    initsintatico(token,args)
39
+def lse(token,args):
40
+    from semantico import semantico
41
+    semantico(token,args)
42
+def lgc(token,args):
43
+    from  Geracaodecodigo import intemerdiario
44
+    texto = []
45
+    intemerdiario(token,args,0,len(token),0,0, texto)
46
+    '''
47
+    intermediario(token, args, posicao inicial que deseja converter para assembler, posição final, valor inicial das Labels dos loops, valor inicial das Labels dos condicionais)
48
+    '''

+ 58
- 0
semantico.py View File

@@ -0,0 +1,58 @@
1
+def semantico(token, args):
2
+    Avariaveis(token, args)
3
+def divisao(token, args, lista):
4
+    linha = []
5
+    if args.lse:
6
+        print("Verificando Divisão por Zero.")
7
+
8
+def verificando(lista):
9
+    for exp in lista.values():
10
+        if 'î' not in exp:
11
+            try:
12
+                eval(''.join(exp))
13
+            except ZeroDivisionError:
14
+                from colorama import Style
15
+                Color()
16
+                print (f' Divisão por Zero {exp} '+ Style.RESET_ALL)
17
+def trocandoValores(lista,a,key):
18
+    import re
19
+    for exp in lista.keys():
20
+        if exp in a:
21
+            a=re.sub(r''+exp, (''.join(lista[exp])),''.join(a))
22
+    lista[key] = ''.join(a)
23
+
24
+def Avariaveis(token, args):
25
+    variaveis = {}
26
+    if args.lse:
27
+        print ('#' * 80)
28
+        print('Carregando Tabela de Variveis.')
29
+        print("Verificando Variaveis Duplicadas.")
30
+    for var in token:
31
+        if 'id' in var and var[2] == 2:
32
+            if var[1] not in variaveis:
33
+                variaveis[var[1]] = 'î'
34
+            else:
35
+                Color()
36
+                print(f'\'{var[1]}\' declaração duplicada: ' + reset(var))
37
+
38
+    if args.lse:
39
+        print("Variaveis declaradas: ")
40
+        for var in variaveis.items():
41
+            print(var[0])
42
+        print("Verificando Variaveis não declaradas.")
43
+
44
+    for code in token:
45
+        if 'id' in code:
46
+            if not (code[1] in variaveis):
47
+                Color();
48
+                print(f'Variavel \'{code[1]}\' não declarado: ' + reset(code))
49
+    divisao(token, args, variaveis)
50
+
51
+def Color():
52
+    from colorama import Fore, Back
53
+    print(Fore.CYAN + 'Erro semantico:')
54
+
55
+
56
+def reset(linha):
57
+    from colorama import Style
58
+    return f'linha{linha[2]} : coluna{linha[3]}' + Style.RESET_ALL

+ 66
- 0
sintatico.py View File

@@ -0,0 +1,66 @@
1
+def analisadorsintatico(dict1, dict2, programa, args):
2
+    pilha = ["<INICIO>"]#inicializa a pilha com o Não terminal inicial
3
+    if args.ls : #Se verdadeiro mostra a mensagem a seguir
4
+        print ('#'*80)
5
+        print("Foi adcionado a pilha: " + pilha[-1])
6
+        #dicionario para cada token e sua representação no código
7
+    token={"a_parentese":"(" ,"f_parentese":")", "virgula":",","inicio":"{", "fim":"}",	"fim_linha":";","id":"id","numero":"numero", "frase":"frase", 	"programa":"programa" ,"fimprograma":"fimprograma", "inteiro":"declaração", "leia":"leia" ,"escreva":"escreva", "se":"se",
8
+       "senao":"senao","enquanto":"enquanto", "menor":"<",	"maior":">", "recebe":"=", "soma":"+" ,"subtracao":"-","multiplicacao":"*", "divisao": '//'}
9
+    i=0#inicializa a posição
10
+    while i <= (len(programa)-1):
11
+        if pilha[-1] == programa[i][0]:#verifica se o topo da pilha é igual ao token na fila do programa
12
+            if args.ls:#Se verdadeiro mostra a mensagem a seguir
13
+                print("Foi despilhado: " + pilha[-1])
14
+            pilha.pop()
15
+            i += 1
16
+        else:
17
+            if (pilha[-1], programa[i][0]) in dict1:#verifica se existe <Não terminal> junto com inicio da fila forma uma chave
18
+                if dict2[dict1[pilha[-1], programa[i][0]][0]]:#Faz mesma verificação da existencia de chave e imprime na tela se args.ls for verdadeiro para o usuario
19
+                    if args.ls:
20
+                        print("Foi despilhado: " + pilha[-1])
21
+                        print("Foi empilhado: ")
22
+                        a = dict2[dict1[pilha[-1], programa[i][0]][0]]
23
+                        a.reverse()
24
+                        print(f"Expressão {dict1[pilha[-1], programa[i][0]][0]}:", a)#Retorna o numero da expressão que foi adcionado na pilha e expressão na ordem que foi empilhada
25
+                        a.reverse()
26
+
27
+                exp = dict2[dict1[pilha[-1], programa[i][0]][0]]#recebe a expressão que vai ser empilhada
28
+                if not exp:
29
+                    if args.ls: #Se verdadeiro mostra a mensagem a seguir
30
+                        print("Foi tirado da pilha: "+pilha[-1])
31
+                    pilha.pop() #desempilha o topo da pilha
32
+                else:
33
+                    pilha.pop()#desempilha o topo da pilha
34
+                    exp.reverse()#inverte a expresão antes de colocar na pilha
35
+                    pilha.extend(exp)#empilha na pilha
36
+                    exp.reverse()#inverte novamente
37
+            else:#Caso não encontre a chave
38
+                a = []
39
+                if '<' in pilha[-1]:
40
+                    dict = []
41
+                    '''
42
+                    cria uma extenção do dicionario, primeirente apresenta todos os itens e os filtra se o topo da pilha
43
+                    estiver nas chaves do dicionario 1 e os adciona
44
+                    '''
45
+                    dict.extend([ele[1] for ele in dict1 if pilha[-1] in ele])#
46
+                    #Adciona apenas os elementos filtrados
47
+                    a.extend([token[ele] for ele in dict if ele])
48
+                else:
49
+                    # se top não for um não terminal ele apenas adciona o topo da pilha
50
+                    a.extend(token[pilha[-1]])
51
+                from colorama import Fore, Style
52
+                t = Fore.CYAN +"Erro Sintatico ".upper()#imprimi bunitinho
53
+                print(t)
54
+                print(f"\'{programa[i][1]}\' inesperado linha {programa[i][2]}, coluna {programa[i][3]}")#
55
+                space = " "*int(programa[i][3])
56
+                texto = []
57
+                with open(args.filename, 'r') as f:
58
+                    for i in range(programa[i][2]):
59
+                        texto = f.readline()
60
+                print(texto+space+'^')
61
+                print(f"Era esperado: {' '.join(a)}"+Style.RESET_ALL)
62
+                args.ls = False
63
+                break
64
+    if args.ls:#Se for True imprime a mensagem
65
+        args.ls=True
66
+        print("Sintatico terminado com Sucesso")

+ 2249
- 0
tabela.html
File diff suppressed because it is too large
View File


Loading…
Cancel
Save