Advertisement
Guest User

Untitled

a guest
May 25th, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.47 KB | None | 0 0
  1. Yacc - Gramática reescrita
  2.  
  3. -Para casos em que uma componente é opcional, decidimos criar um novo estado e definir as possibilidades da gramatica nesse estado.
  4.  
  5. FuncDeclaration → FUNC ID LPAR [Parameters] RPAR [Type] FuncBody
  6. → function_declaration:
  7. function_header function body
  8. function_header:
  9. FUNC id_state LPAR parameters RPAR
  10. FUNC id_state LPAR parameters RPAR type
  11. Onde parameters pode ser vazio.
  12.  
  13. -Para os casos de 0 ou mais repetições, decidimos criar um novo estado em que este pode ser vazio para passar a recursividade a esquerda para recursividade à direita e remover ambiguidade.
  14.  
  15. Parameters−→ID Type {COMMA ID Type}
  16. → Parameters:
  17. parameters_decl;
  18. parameters_decl:
  19. id_state type parameters_list
  20. |
  21. ;
  22. parameters_list:
  23. COMMA id_state type parameters_list
  24. |
  25. ;
  26.  
  27. -Para os casos de ser ou uma produção ou outra, decidimos criar um estadoque pode ser as duas produções possíveis.
  28.  
  29. Statement−→PRINT LPAR (Expr | STRLIT) RPAR
  30.  
  31. str_statement:
  32. PRINT LPAR expression RPAR
  33. PRINT LPAR strlit_state RPAR
  34. ;
  35.  
  36.  
  37.  
  38. PORQUE O ID_STATE E STRLIT_STATE SÓ PARA ID E STRLIT?
  39.  
  40. MAIS ALGUM CASO WORTH MENTIONING?
  41.  
  42. Quanto aos erros, uma vez que o analisador deve incluir recuperação local de erros de sintaxe, Adicionámos um estado “error” nos locais assinalados no enunciado.
  43. AST Anotada e Tabela Simbolos
  44.  
  45. Geração Código
  46.  
  47. Para a geração de código percorremos a arvore anotada de maneira parecida a meta3 verificando os tipos de nós que encontramos e usando esses nós para criação de linhas LLVM.
  48.  
  49. Inicialmente, vamos à tabela de simbolos e declaramos todas as variáveis globais. Além disso, se encontrarmos um function declaration, declaramos as variáveis locais imediatamente.
  50.  
  51. Assign:
  52. verificamos se variável é global ou não para saber que tipo de store é que é feito (“@%s” ou “%%%s”).
  53.  
  54. FuncDecl:
  55. Imprimimos o header da funcao e os respectivos tipos dos parâmetros (“define i32 @f(i32)”)
  56. Declaramos variaveis locais.
  57. Continuamos a analisar a arvore para imprimir os nos filhos do FuncDecl que estão dentro da função.
  58. Analisamos a necessidade de ser colocado um return, e caso seja preciso (“ret %type”).
  59.  
  60. Statement:
  61. Verificamos o tipo (IF, For ,Return, Print).
  62. If:
  63. Verificamos se existe um block para Else para saber quantos Labels alocar.
  64. Após alocado espaço para os labels, e ter produzido a expressão, é feito um branch comparando a variável proveniente das expressões(“br i1 %s %%label%d, label %%label%d”).
  65. Inicializamos o label, produzimos os nós filhos deste e fazemos um branch para o nó após o if.
  66. For:
  67. Caso haja, criamos um label para a condição, um para o block do for e um para o fim do for.
  68. Branches de maneira semelhante aos ifs
  69.  
  70. Prints:
  71.  
  72. Parse Args:
  73.  
  74. Expressions:
  75. Percorremos recursivamente até folhas da arvore e retornamos ou variável temporaria ou valor primitivo. Num nó por exemplo do tipo “add”, este vai ter duas expressions provenientes da recursividade.
  76. Call:
  77. imprimimos um call para a função com respectivos parâmetros e tipos.
  78. Expression:
  79. verificamos o valor do nó para saber se é um add, sub ou outro e após verificar se é float ou não, produzimos a linha LLVM correspondente ao valor do nó.
  80. Id:
  81. verificamos se id é global ou local e produzimos linha LLVM load para essa variável com expression.
  82. Tipos especiais primitivos:
  83. 2e3 → 2.0e3 || .3 → 0.3|| Other realits || Hexa|octal → decimal
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement