Aprendendo compiladores fazendo um - Parte 2

Aprendendo compiladores fazendo um - Parte 2

Vídeo dessa talk: https://youtu.be/q9T6Y2ZjE54
Vídeo da Parte 1: https://youtu.be/t77ThZNCJGY
Vídeo da demonstração do compilador: https://youtu.be/BAS0EZ0Yg6g

Aprender mais sobre compiladores é uma excelente forma de desmitificar o que acontece no momento entre iniciar a build do código e obter o output. Isso é ótimo para se tornar um melhor desenvolver e expandir seus horizontes; desse modo é possível entender mais sobre o funcionamento de ferramentas como Babel e máquinas virtuais, assim como outras áreas, como otimização e engenharia reversa.

Nessa segunda parte da talk "Aprendendo compiladores fazendo um" vamos adentrar bem mais no código de como o Macro Compiler funciona. Veremos todas as etapas de compilação, como as gramáticas, parser combinator, análise semântica, tratamento de erros, otimização, geração de código e testes! Assim clarificando como um compilador pode ser implementado.

Repositório do compilador de EventMacro: https://github.com/macabeus/macro-compiler

F380535da59d6cdd5754e2e31bda8a0e?s=128

Bruno Macabeus

September 04, 2018
Tweet

Transcript

  1. 3.

    “The language or notation we are using to express or

    record our thoughts, are the major factors determining what we can think or express at all!” Edsger W. Dijkstra
  2. 5.
  3. 6.
  4. 7.
  5. 8.
  6. 9.
  7. 14.

    Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL É uma

    forma muito simples de representar a gramática de uma linguagem.
  8. 15.

    Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL move prontera

    30 42 move 30 42 É uma forma muito simples de representar a gramática de uma linguagem. Regexp (regular expression) é um exemplo
  9. 16.

    Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL /move (?:(\w+)

    )?(\d+) (\d+)/ move prontera 30 42 move 30 42 É uma forma muito simples de representar a gramática de uma linguagem. Regexp (regular expression) é um exemplo
  10. 17.

    Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL Uma das

    limitações é não ser possível especificar uma sequência arbitrária de comandos. Por conta disso, não é possível descrever uma sequência aninhada de blocos de comandos
  11. 18.

    Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL { evil_query(id:

    42) { complex_field {
 complex_field { field } } } } Uma das limitações é não ser possível especificar uma sequência arbitrária de comandos. Por conta disso, não é possível descrever uma sequência aninhada de blocos de comandos
  12. 19.

    Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL { evil_query(id:

    42) { complex_field {
 complex_field { field } } } } Uma das limitações é não ser possível especificar uma sequência arbitrária de comandos. Por conta disso, não é possível descrever uma sequência aninhada de blocos de comandos
  13. 20.

    Uma eDSL é uma biblioteca com interface da qual mimetiza

    uma linguagem de programação, isto é, apresenta palavras primitivas e a possibilidade combiná-las para construir rotinas Context-free Grammars Parsing Expression Grammar eDSL Regular Grammars
  14. 21.

    Pode-se embutir em uma linguagem uma outra linguagem cuja finalidade

    dela é especificar gramáticas Context-free Grammars Parsing Expression Grammar eDSL Regular Grammars
  15. 22.

    Context-free Grammars Parsing Expression Grammar eDSL Regular Grammars sequence([
 ignore(string("move")),


    ignore(spaces()),
 
 many(letter()),
 skip(spaces()),
 
 integer(),
 ignore(spaces()),
 
 integer()
 ]) Pode-se embutir em uma linguagem uma outra linguagem cuja finalidade dela é especificar gramáticas
  16. 23.

    Define um conjunto de símbolos e as respectivas transformações válidas

    de cada um. Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL
  17. 24.

    Define um conjunto de símbolos e as respectivas transformações válidas

    de cada um. Um exemplo de CFG (Context-free Grammars) é o BNF (Backus–Naur Form): Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL <vowel> :== "a" | "e" | "i" | "o" | "u" <digit> :== "0" | "1" | "2" | "3" | "4" |
 "5" | "6" | "7" | "8" | "9" <character> :== <vowel> | <digit> <text> :== <character> | <text> <character>
  18. 25.

    Define um conjunto de símbolos e as respectivas transformações válidas

    de cada um. Um exemplo de CFG (Context-free Grammars) é o BNF (Backus–Naur Form): Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL <vowel> :== "a" | "e" | "i" | "o" | "u" <digit> :== "0" | "1" | "2" | "3" | "4" |
 "5" | "6" | "7" | "8" | "9" <character> :== <vowel> | <digit> <text> :== <character> | <text> <character> ei9 zyp
  19. 26.

    Similar ao CFG. Também define um conjunto de símbolos e

    as respectivas transformações. Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL
  20. 27.

    Similar ao CFG. Também define um conjunto de símbolos e

    as respectivas transformações. Exemplo de PEG (Parsing Expression Grammar): Context-free Grammars Parsing Expression Grammar Regular Grammars eDSL vowel ← 'a' / 'e' / 'i' / 'o' / 'u' digit ← [0-9] character ← vowel / digit text ← character+
  21. 30.

    Parsing Expression Grammar Regular Grammars eDSL Context-free Grammars As principais

    diferenças entre CFG e PEG são:
 - notação <vowel> :== "a" | "e" | "i" | "o" | "u" <digit> :== "0" | "1" | "2" | "3" | "4" |
 "5" | "6" | "7" | "8" | "9" <character> :== <vowel> | <digit> <text> :== <character> | <text> <character> vowel ← 'a' / 'e' / 'i' / 'o' / 'u' digit ← [0-9] character ← vowel / digit text ← character+
  22. 31.

    Parsing Expression Grammar Regular Grammars eDSL Context-free Grammars As principais

    diferenças entre CFG e PEG são:
 - notação - interpretação das regras
  23. 32.

    Parsing Expression Grammar Regular Grammars eDSL Context-free Grammars As principais

    diferenças entre CFG e PEG são:
 - notação - interpretação das regras CFG Regra A
 Regra B
 Regra C CFG Regra B
 Regra C
 Regra A = PEG Regra A
 Regra B
 Regra C PEG Regra B
 Regra C
 Regra A ≠
  24. 33.

    Parsing Expression Grammar Regular Grammars eDSL Context-free Grammars As principais

    diferenças entre CFG e PEG são:
 - notação - interpretação das regras CFG Regra A
 Regra B
 Regra C CFG Regra B
 Regra C
 Regra A = PEG Regra A
 Regra B
 Regra C PEG Regra B
 Regra C
 Regra A ≠ “Hmm.. posso usar tanto A ou B… Então devo usar qual?”
  25. 34.

    Parsing Expression Grammar Regular Grammars eDSL Context-free Grammars As principais

    diferenças entre CFG e PEG são:
 - notação - interpretação das regras CFG Regra A
 Regra B
 Regra C CFG Regra B
 Regra C
 Regra A = PEG Regra A
 Regra B
 Regra C PEG Regra B
 Regra C
 Regra A ≠ Sei lá! Sei lá! “Hmm.. posso usar tanto A ou B… Então devo usar qual?”
  26. 35.

    Parsing Expression Grammar Regular Grammars eDSL Context-free Grammars As principais

    diferenças entre CFG e PEG são:
 - notação - interpretação das regras CFG Regra A
 Regra B
 Regra C CFG Regra B
 Regra C
 Regra A = PEG Regra A
 Regra B
 Regra C PEG Regra B
 Regra C
 Regra A ≠ Sei lá! Use B,
 veio
 antes! Sei lá! Use A,
 veio
 antes! “Hmm.. posso usar tanto A ou B… Então devo usar qual?”
  27. 49.
  28. 50.
  29. 58.
  30. 59.
  31. 60.
  32. 61.
  33. 62.
  34. 75.
  35. 77.
  36. 78.
  37. 79.
  38. 80.
  39. 81.
  40. 82.
  41. 83.
  42. 86.

    Em alguns momentos, pode ser que a sua gramática seja

    recursiva. &rand(0, 5) ScalarValue
  43. 108.
  44. 111.

    A symbols table é importante para tornar mais acessível as

    informações da AST para as demais etapas de compilação
  45. 112.
  46. 113.
  47. 114.
  48. 115.
  49. 116.
  50. 117.
  51. 118.
  52. 119.
  53. 120.
  54. 121.
  55. 122.
  56. 123.
  57. 124.
  58. 125.
  59. 126.
  60. 127.
  61. 128.
  62. 129.
  63. 133.

    read macros: [ "foo", "bar" ] write macros: [ "foo"

    ] difference: [ "bar" ] Devemos disparar um erro
 devido a leitura de "bar" !
  64. 153.

    Erro semântico macro example { $never_read_var = &rand(1, 4) #

    warning log number: $never_written_var # fatal error }
  65. 158.
  66. 159.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: $foo log bar: $bar log name: $name $name = pagarme log name: $name }
  67. 160.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: $foo log bar: $bar log name: $name $name = pagarme log name: $name } ➡
  68. 161.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: $foo log bar: $bar log name: $name $name = pagarme log name: $name } macro setVars { $foo = value $bar = &rand(1, 4) } macro example { $name = macabeus call setVars log foo: value log bar: $bar log name: macabeus $name = pagarme log name: pagarme } ➡
  69. 162.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: $foo log bar: $bar log name: $name $name = pagarme log name: $name } macro setVars { $foo = value $bar = &rand(1, 4) } macro example { $name = macabeus call setVars log foo: value log bar: $bar log name: macabeus $name = pagarme log name: pagarme } ➡
  70. 163.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: log bar: log name: $name = pagarme log name: } Contexto das últimas
 variáveis na macro Contexto das variáveis na seta setVars
 $foo: value
 $bar: is nondeterministic
 example
 $name: pagarme $foo $bar $name
  71. 164.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: log bar: log name: $name = pagarme log name: } Contexto das últimas
 variáveis na macro Contexto das variáveis na seta setVars
 $foo: value
 $bar: is nondeterministic
 example
 $name: pagarme $foo $bar $name $name
  72. 165.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: log bar: log name: $name = pagarme log name: } Contexto das últimas
 variáveis na macro Contexto das variáveis na seta setVars
 $foo: value
 $bar: is nondeterministic
 example
 $name: pagarme $name: macabeus $foo $bar $name $name
  73. 166.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: log bar: log name: $name = pagarme log name: } Contexto das últimas
 variáveis na macro Contexto das variáveis na seta setVars
 $foo: value
 $bar: is nondeterministic
 example
 $name: pagarme $name: macabeus $foo: value
 $bar: is nondeterministic $foo $bar $name $name
  74. 167.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: log bar: log name: $name = pagarme log name: } Contexto das últimas
 variáveis na macro Contexto das variáveis na seta setVars
 $foo: value
 $bar: is nondeterministic
 example
 $name: pagarme $name: macabeus $foo: value
 $bar: is nondeterministic $bar $name value $name
  75. 168.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: log bar: log name: $name = pagarme log name: } Contexto das últimas
 variáveis na macro Contexto das variáveis na seta setVars
 $foo: value
 $bar: is nondeterministic
 example
 $name: pagarme $name: macabeus $foo: value
 $bar: is nondeterministic $bar $name value $name
  76. 169.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: log bar: log name: $name = pagarme log name: } Contexto das últimas
 variáveis na macro Contexto das variáveis na seta setVars
 $foo: value
 $bar: is nondeterministic
 example
 $name: pagarme $name: macabeus $foo: value
 $bar: is nondeterministic $bar value macabeus $name
  77. 170.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: log bar: log name: $name = pagarme log name: } Contexto das últimas
 variáveis na macro Contexto das variáveis na seta setVars
 $foo: value
 $bar: is nondeterministic
 example
 $name: pagarme $foo: value
 $bar: is nondeterministic $name: pagarme $bar value macabeus $name
  78. 171.

    macro setVars { $foo = value $bar = &rand(1, 4)

    } macro example { $name = macabeus call setVars log foo: log bar: log name: $name = pagarme log name: } Contexto das últimas
 variáveis na macro Contexto das variáveis na seta setVars
 $foo: value
 $bar: is nondeterministic
 example
 $name: pagarme $foo: value
 $bar: is nondeterministic $name: pagarme $bar value macabeus pagarme
  79. 180.

    header body footer [
 "push",
 "@values",
 ",",
 [ "f", "o",

    "o" ], ";" ] [
 "push",
 "@values",
 ",", "f", "o", "o", ";" ]
  80. 184.

    header body footer encontrar quais variáveis são escritas para declará-las


    encontrar os módulos do OpenKore que precisa importar
  81. 185.

    header body footer encontrar quais variáveis são escritas para declará-las


    encontrar os módulos do OpenKore que precisa importar
  82. 186.

    header body footer encontrar quais variáveis são escritas para declará-las


    encontrar os módulos do OpenKore que precisa importar
  83. 187.

    header body footer encontrar quais variáveis são escritas para declará-las


    encontrar os módulos do OpenKore que precisa importar
  84. 188.

    header body footer encontrar quais variáveis são escritas para declará-las


    encontrar os módulos do OpenKore que precisa importar
  85. 191.

    header body footer gerar boilerplate
 encontrar quais variáveis são escritas

    para declará-las
 encontrar os módulos do OpenKore que precisa importar
 ✏ encontrar quais macros são escritas para tornar chamáveis
  86. 210.

    Functional test E2e test Testo as otimizações checando a AST…

    porém, o importante é verificar se a semântica está preservada. 
 Verificar se está gerando uma AST equivalente garante trivialmente que a semântica é preservada
  87. 225.

    Agradecimentos ao Pedro Castilho por ter me ajudado pra caralho

    em desenvolver o compilador e essa talk
  88. 226.

    Para aprender mais - Material bem didática sobre como funciona

    parser funciona http://theorangeduck.com/page/you-could- have-invented-parser-combinators - Para ver mais possibilidades de fazer interprocess communication no Elixir https://youtu.be/ZrBhuP6OrFI - Manual foda sobre parser https://tomassetti.me/guide- parsing-algorithms-terminology/ - Lib em Ruby de parser generator com PEG, a Parslet
  89. 229.