Bora vê
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Geracaodecodigo.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  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):
  5. if (args.lgc):
  6. print ("Gerando código intermediário")
  7. L=0
  8. C=0
  9. pilha=[]
  10. i=0
  11. texto=[]
  12. while i < len(token) :
  13. if 'inteiro' in token[i][0]:
  14. if (args.lgc):
  15. print ("Inteiro identificado:")
  16. texto.extend(variaveis(token,i))
  17. elif 'leia' in token[i][0]:
  18. if (args.lgc):
  19. print ("leia identificado:")
  20. texto.append('LEIA '+token[i+2][1])
  21. elif 'escreva' in token[i][0]:
  22. if (args.lgc):
  23. print ("escreva identificado:")
  24. texto.append('ESCREVA '+ token[i+2][1])
  25. elif 'recebe' in token[i][0]:
  26. if (args.lgc):
  27. print ("Atribuição identificada:")
  28. exp=[]
  29. from infixtoposfix import infixToPostfix
  30. exp.append(infixToPostfix(expressao(token, i)))
  31. simpleexpre(exp,token[i-1][1],texto)
  32. elif 'enquanto' in token[i][0]:
  33. if (args.lgc):
  34. print ("função enquanto identificado:")
  35. 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} ')
  36. pilha.append(f'_L{L+1}')
  37. L+=2
  38. elif 'se' == token[i][0]:
  39. if (args.lgc):
  40. print ("\'se\' identificado:")
  41. texto.append(f'_C{C}: if {token[i+2][1]}' + (' =>' if '<' in token[i+3][1] else ' <=')+f' {token[i+4][1]} goto _C{C+1}')
  42. pilha.append(f'_C{C + 1}')
  43. C += 2
  44. elif 'senao' == token[i][0]:
  45. if (args.lgc):
  46. print ("\'senao\' identificado:")
  47. pilha.append(f'{int(texto[-1].split("_C")[1].split(":")[0])-1}')
  48. elif '}' in token[i][1]:
  49. if 'L' in pilha[-1]:
  50. p= pilha.pop()
  51. texto.append(f'goto _L{int(p.split("_L")[1])-1}')
  52. texto.append(f'{p}:')
  53. elif 'C' in pilha[-1]:
  54. p = pilha.pop()
  55. texto.append(f'goto EXIT_C{int(p.split("_C")[1]) - 1}')
  56. texto.append(f'{p}:')
  57. if 'senao' not in token[i+1][0]:
  58. texto.append (f'EXIT_C{int(p.split("_C")[1])-1}:')
  59. elif pilha[-1]:
  60. texto.append(f'EXIT_C{pilha.pop()}:')
  61. #print (pilha)
  62. i=i+1
  63. with open('intermediario.s','w') as f:
  64. if (args.lgc):
  65. print ("Escrevendo no arquivo:")
  66. f.write('\n'.join(texto))
  67. def simpleexpre(exp,var,texto):
  68. '''
  69. ADD dest,src1,src2 dest = src1 + src2
  70. SUB dest,src1,src2 dest = src1 - src2
  71. ADDI dest,src1,I dest = src1 + I
  72. MUL dest,src1,src2 dest = src1 × src2
  73. DIV dest,src1,src2 dest = src1/src2
  74. '''
  75. t=1
  76. exp=exp[0].split()
  77. values=[]
  78. operador=['+','-','*','/']
  79. for i in range(len(exp)):
  80. if exp[i] in operador:
  81. a = values.pop()
  82. b = values.pop()
  83. if i == len(exp)-1:
  84. texto.append(f'{var} := {b} {a} {exp[i]}')
  85. else:
  86. texto.append(f'T{t} := {b} {a} {exp[i]}')
  87. values.append(f'T{t}')
  88. t+=1
  89. else:
  90. values.append(exp[i])
  91. if len(values) > 0:
  92. texto.append(f'{var} := {values[0]}')
  93. def expressao(token, i):
  94. l=i+1
  95. var=[]
  96. while not('fim_linha' in token[l][0]):
  97. var.append(token[l][1])
  98. l+=1
  99. return ' '.join(var)
  100. def variaveis(token,i):
  101. l=i+1
  102. var=[]
  103. while not('fim_linha' in token[l][0]):
  104. if not('virgula' in token[l][0]):
  105. var.append('INTEIRO '+token[l][1])
  106. l+=1
  107. return var
  108. def gerarcodigo(token,args):
  109. '''
  110. 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)
  111. '''
  112. intemerdiario(token, args)
  113. gerar(args)
  114. def gerar(args):
  115. nome = args.filename.split('.')[0]
  116. texto=[]
  117. if (args.lgc):
  118. print ("Gerando código final")
  119. with open('intermediario.s','r') as f:
  120. texto=f.read().splitlines()
  121. i=0
  122. final=[]
  123. db=[]
  124. msg=-1
  125. if (args.lgc):
  126. print ("Gerando cabeçalho")
  127. final.append(';flat assembler version 1.73.02')
  128. final.append(f';fasm {nome}.asm')
  129. final.append(f';ld -lc -e main -dynamic-linker /lib/ld-linux.so.2 {nome}.o -o {nome} -m elf_i386')
  130. final.append(';OS: Ubuntu 18.04.1 LTS x86_64 ')
  131. final.append(';Kernel: 4.15.0-42-generic ')
  132. final.append(';CPU: Intel i5-2520M (4) @ 3.200GHz\n')
  133. final.append(f'format ELF')
  134. final.append('public main as \'main\' ')
  135. final.append('extrn \'exit\'as exit')
  136. final.append('extrn \'printf\' as printf')
  137. final.append('extrn \'scanf\'as scanf\n')
  138. final.append('section \'.text\' executable')
  139. final.append('main:')
  140. while i < len(texto):
  141. if (args.lgc):
  142. print ("Gerando o comando escreva")
  143. if 'INTEIRO' in texto[i].split()[0]:
  144. db.append(f'{texto[i].split()[1]} dd 0')
  145. if 'ESCREVA' in texto[i].split('"')[0]:
  146. final.append(';Impressão na tela')
  147. if '"' in texto[i]:
  148. msg += 1
  149. text = texto[i].split('ESCREVA')[1]
  150. text= text.strip()
  151. text= "".join(text)
  152. text = text.replace('\"', '')
  153. if (args.lgc):
  154. print ("Gerando comandos para o escrever uma mensagem")
  155. final.append(f'push msg{msg}')
  156. final.append(f'call printf')
  157. final.append(f'add esp, 4\n')
  158. txt=text.replace('\\n', '\',10,0,\'')
  159. db.append(f'msg{msg} db \'{txt}\', 0,0')
  160. else:
  161. if (args.lgc):
  162. print ("Gerando comandos para o escrever uma variavel")
  163. expre = texto[i].split()
  164. final.append(f'push {"["+expre[1]+"]" if expre[1].isidentifier() else expre[1] }')
  165. final.append(f'push formatacao')
  166. final.append(f'call printf')
  167. final.append(f'add esp, 4\n')
  168. if 'LEIA' in texto[i].split()[0]:
  169. if (args.lgc):
  170. print ("Gerando o comando leia")
  171. final.append(';Ler do Teclado')
  172. final.append(f'push {texto[i].split()[1]}')
  173. final.append(f'push formatacao')
  174. final.append(f'call scanf')
  175. final.append(f'add esp, 8\n')
  176. if 'if' in texto[i]:
  177. '''
  178. je - jump if op1 = op2 (op1 is "equal to" op2)
  179. ja - jump if op1 > op2 (op1 is "above" op2)
  180. jb - jump if op1 < op2 (op1 is "below" op2)
  181. jae - jump if op1 >= op2 (op1 is "above or equal to" op2)
  182. jbe - jump if op1 <= op2 (op1 is "below or equal to" op2)
  183. '''
  184. if (args.lgc):
  185. print ("Comando condicional/repetição identificado")
  186. print ("Gerando os comandos condicões/repetição")
  187. expre=texto[i].split()
  188. final.append(';Label')
  189. final.append(f'{expre[0]}')
  190. #final.append(f'xor eax,eax')
  191. final.append(f'xor ebx, ebx')
  192. final.append(f'mov eax, {"["+expre[2]+"]" if expre[2].isidentifier() else expre[2] }')
  193. final.append(f'mov ebx, {"["+expre[4]+"]" if expre[4].isidentifier() else expre[4] }')
  194. final.append(f'cmp eax, ebx')
  195. final.append(f'j{"ae" if ">=" is expre[3] else "be"} {expre[6]}')
  196. if 'goto' in texto[i].split()[0]:
  197. final.append(f'jmp {texto[i].split()[1]}')
  198. if len(texto[i].split())<2:
  199. final.append(f'{texto[i]}')
  200. if len(texto[i].split())>2:
  201. if (args.lgc):
  202. print ("Comando de atribuição identificado")
  203. print ("Gerando...")
  204. if ':=' in texto[i].split()[1]:
  205. expre = texto[i].split()
  206. if len(expre)==3:
  207. if (args.lgc):
  208. print ("Comando de atribuição para com um valor")
  209. print ("Gerando...")
  210. final.append(f';Atribuição')
  211. final.append(f'mov eax,[{expre[0]}]')
  212. final.append(f'mov eax, {"["+expre[2]+"]" if expre[2].isidentifier() else expre[2] }')
  213. final.append(f'mov [{expre[0]}],eax')
  214. final.append(f'xor eax,eax\n')
  215. elif '+' is expre[4]:
  216. if (args.lgc):
  217. print ("Comando de soma")
  218. print ("Gerando...")
  219. final.append(f';Adicção')
  220. final.append(f'mov eax, {"["+expre[2]+"]" if expre[2].isidentifier() else expre[2] }')
  221. final.append(f'mov edx, {"["+expre[3]+"]" if expre[3].isidentifier() else expre[3] }')
  222. final.append(f'add eax, edx')
  223. final.append(f'mov {"["+expre[0]+"]"}, eax')
  224. final.append(f'xor eax,eax\n')
  225. elif '-' is expre[4]:
  226. if (args.lgc):
  227. print ("Comando de subtração")
  228. print ("Gerando...")
  229. final.append(f';Subtração')
  230. final.append(f'mov eax, {"["+expre[2]+"]" if expre[2].isidentifier() else expre[2] }')
  231. final.append(f'mov edx, {"["+expre[3]+"]" if expre[3].isidentifier() else expre[3] }')
  232. final.append(f'sub eax, edx')
  233. final.append(f'mov {"["+expre[0]+"]"}, eax')
  234. final.append(f'xor eax,eax\n')
  235. elif '*' is expre[4]:
  236. if (args.lgc):
  237. print ("Comando de multiplicação")
  238. print ("Gerando...")
  239. final.append(f';Multiplicação')
  240. final.append(f'mov eax, {"[" + expre[2] + "]" if expre[2].isidentifier() else expre[2] }')
  241. final.append(f'mov edx, {"[" + expre[3] + "]" if expre[3].isidentifier() else expre[3] }')
  242. final.append(f'imul eax, edx')
  243. final.append(f'mov {"[" + expre[0] + "]"}, eax')
  244. final.append(f'xor eax,eax\n')
  245. elif '/' is expre[4]:
  246. if (args.lgc):
  247. print ("Comando de divisão")
  248. print ("Gerando...")
  249. final.append(f';Divisao')
  250. final.append(f'xor edx, edx')
  251. final.append(f'mov ebx, {"[" + expre[2] + "]" if expre[2].isidentifier() else expre[2] }')
  252. final.append(f'mov eax, {"[" + expre[2] + "]" if expre[2].isidentifier() else expre[2] }')
  253. final.append(f'div ebx')
  254. final.append(f'mov {"[" + expre[0] + "]"}, eax')
  255. final.append(f'xor eax,eax\n')
  256. i+=1
  257. final.append('sair:')
  258. final.append('push 0')
  259. final.append('call exit\n')
  260. if(len(db)>0):
  261. final.append('section \'.data\' writeable')
  262. final.append('formatacao db \'%d\' , 0')
  263. final.extend(db)
  264. with open(nome+'.asm','w') as f:
  265. f.write('\n'.join(final))
  266. import os
  267. if args.lgc:
  268. print (f"Compilando arquivo fonte: {args.filename}")
  269. os.system(f'fasm {nome}.asm')
  270. os.system(f'ld -lc -e main -dynamic-linker /lib/ld-linux.so.2 {nome}.o -o {nome} -m elf_i386')
  271. if args.lgc:
  272. print (f"Arquivo executavel pronto: {nome}")
  273. print ("pronto")