Advertisement
MirandaWopps

LEX e YACC

Jun 25th, 2024 (edited)
719
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.60 KB | Source Code | 0 0
  1. #Lucas Ebrenz Fernandes Pereira  turma das 9h(Herman)  2011488
  2. import ply.lex as lex
  3. import ply.yacc as yacc
  4.  
  5. # Definindo os tokens reservados
  6. reservados = {
  7.     'INICIO': 'INICIO',
  8.     'MONITOR': 'MONITOR',
  9.     'EXECUTE': 'EXECUTE',
  10.     'TERMINO': 'TERMINO',
  11.     'ENQUANTO': 'ENQUANTO',
  12.     'FACA': 'FACA',
  13.     'FIM': 'FIM',
  14.     'IF': 'IF',
  15.     'THEN': 'THEN',
  16.     'ELSE': 'ELSE',
  17.     'ZERO': 'ZERO',
  18.     'EVAL': 'EVAL'
  19. }
  20.  
  21. tokens = [
  22.     'ID', 'NUMERO',
  23.     'MAIS', 'MENOS', 'MULTIPLICACAO', 'DIVISAO',
  24.     'IGUAL', 'VIRGULA', 'LPAREN', 'RPAREN'
  25. ] + list(reservados.values())
  26.  
  27. # Definindo as expressões regulares para tokens simples
  28. t_MAIS = r'\+'
  29. t_MENOS = r'-'
  30. t_MULTIPLICACAO = r'\*'
  31. t_DIVISAO = r'/'
  32. t_IGUAL = r'='
  33. t_VIRGULA = r','
  34. t_LPAREN = r'\('
  35. t_RPAREN = r'\)'
  36.  
  37. def t_NUMERO(t):
  38.     r'\d+'
  39.     t.value = int(t.value)
  40.     return t
  41.  
  42. def t_ID(t):
  43.     r'[a-zA-Z_][a-zA-Z_0-9]*'
  44.     t.type = reservados.get(t.value, 'ID')  # Verifica se é uma palavra reservada
  45.     return t
  46.  
  47. def t_newline(t):
  48.     r'\n+'
  49.     t.lexer.lineno += len(t.value)
  50.    
  51. t_ignore = ' \t\n' # ignora espaços e tabs
  52.  
  53. def t_error(t): # nos dizer qual caractere ilegal e se tem erro
  54.     print("Caracter ilegal: ", t.value[0])
  55.     t.lexer.skip(1)
  56.  
  57. lexer = lex.lex()
  58.  
  59. # Variáveis monitoradas
  60. monitoradas = []
  61.  
  62. # Definindo as regras de produção
  63. def p_program(p):
  64.     'program : INICIO varlist MONITOR varlist EXECUTE cmds TERMINO'
  65.     global monitoradas
  66.     monitoradas = p[4].split(', ')
  67.     p[0] = f"#include <stdio.h>\nint main(){{\nint{p[2]}; /*MONITOR: {p[4]}*/ \n {p[6]} \nreturn 0;\n}}"
  68.  
  69. def p_varlist(p):
  70.     '''
  71.    varlist : ID
  72.            | ID VIRGULA varlist
  73.    '''
  74.     if len(p) == 2:
  75.         p[0] = f" {p[1]}"
  76.     else:
  77.         p[0] = f" {p[1]}, {p[3]}"
  78.        
  79.        
  80. def p_cmds(p):
  81.     '''
  82.    cmds : cmd cmds
  83.         | cmd
  84.    '''
  85.     if len(p) == 3:
  86.         p[0] = f"{p[1]} {p[2]}"
  87.     else:
  88.         p[0] = f"{p[1]}"
  89.  
  90. def p_cmd(p):
  91.     '''
  92.    cmd : ENQUANTO ID FACA cmds FIM
  93.        | exp
  94.        | IF ID THEN cmd
  95.        | IF ID THEN cmd ELSE cmd
  96.        | EVAL LPAREN ID VIRGULA ID VIRGULA cmds RPAREN
  97.        | ZERO LPAREN ID RPAREN
  98.    '''
  99.     if p[1] == 'ENQUANTO': # ENQUANTO
  100.         p[0] = f"\n    while({p[2]}){{ {p[4]} }}" #ENQUANTO P[2]!=0 , cmds
  101.     elif p[1] == 'ZERO': #ZERO
  102.         p[0] = f"\n{p[3]} = 0; {print_monitorada(p[3])}" #P[1] ZERO, P[3] o que será zerado
  103.     elif len(p) == 2: # se o tamanho é 2, isto é, p[0] e p[1] é só um "cmd"
  104.         p[0] = f"{p[1]}"
  105.     elif p[1] == 'EVAL':# eval é como se fosse um for:
  106.         p[0] = f"\nfor(int {p[3]}, {p[5]}; {p[3]}!={p[5]}; {p[3]}--){{  {p[7]} \n}}"
  107.     elif p[1] == 'IF':
  108.         if len(p) == 5:  # IF without ELSE
  109.             p[0] = f"\n  if({p[2]}){{ {p[4]}; \n}}"
  110.         else:  # IF with ELSE
  111.             p[0] = f"\n  if({p[2]}){{ {p[4]}; \n  }} else {{ {p[6]}; \n}}"
  112.     else:
  113.         p[0] = f"{p[1]} = {p[5]}  {p[7]} {p[9]}"
  114.        
  115. def p_exp(p):
  116.     '''
  117.    exp : ID IGUAL ID MAIS ID
  118.        | ID IGUAL ID MENOS ID
  119.        | ID IGUAL ID MULTIPLICACAO ID
  120.        | ID IGUAL ID DIVISAO ID
  121.        | ID IGUAL ID
  122.        | ID IGUAL NUMERO MAIS ID
  123.        | ID IGUAL NUMERO MENOS ID
  124.        | ID IGUAL NUMERO MULTIPLICACAO ID
  125.        | ID IGUAL NUMERO DIVISAO ID
  126.        | ID IGUAL ID MAIS NUMERO
  127.        | ID IGUAL ID MENOS NUMERO
  128.        | ID IGUAL ID MULTIPLICACAO NUMERO
  129.        | ID IGUAL ID DIVISAO NUMERO
  130.        | ID IGUAL NUMERO MAIS NUMERO
  131.        | ID IGUAL NUMERO MENOS NUMERO
  132.        | ID IGUAL NUMERO MULTIPLICACAO NUMERO
  133.        | ID IGUAL NUMERO DIVISAO NUMERO
  134.        | ID IGUAL NUMERO
  135.    '''
  136.     if len(p) == 4:
  137.         p[0] = f"{p[1]} {p[2]} {p[3]}; {print_monitorada(p[1])}"
  138.     else:
  139.         p[0] = f"\n{p[1]} {p[2]} {p[3]} {p[4]} {p[5]}; {print_monitorada(p[1])}"
  140.  
  141. def p_error(p):
  142.     print("Erro de sintaxe: ", p)
  143.  
  144. def print_monitorada(var):
  145.     if var in monitoradas:
  146.         return f'printf("%d\\n", {var}); '
  147.     return ''
  148.  
  149. parser = yacc.yacc()
  150.  
  151. # Exemplo de análise sintática
  152. #result = parser.parse("INICIO a, b, c, d MONITOR x EXECUTE a = b + c b = b + c TERMINO")
  153. #result = parser.parse("INICIO X, Y MONITOR Z EXECUTE Y=2 X=5 Z = Y ENQUANTO X FACA Z = Z + 1 FIM TERMINO")
  154. #result = parser.parse("INICIO X, Y, B MONITOR Z EXECUTE X = 5 Y = 2 B = 0 EVAL(X, Y, IF B THEN Z = Z + 2 ELSE Z = Z + 1) TERMINO")
  155. #result = parser.parse("INICIO a, b, c, d MONITOR x EXECUTE a = b + c b = b + c ZERO(K) x = 3 TERMINO")
  156. result = parser.parse("INICIO X, Y, B MONITOR Z EXECUTE X = 5 Y = 2 B = 0 EVAL(X, Y, Z = Z + 2 Z = Z + 1) TERMINO")
  157. print(result)
  158.  
Tags: YACC lex
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement