2 pontos por GN⁺ 2024-11-09 | 1 comentários | Compartilhar no WhatsApp

Macros

  • As macros do Rust são usadas para eliminar duplicação de código e reduzir repetição.
  • Os nós de instrução do sqleibniz precisam implementar o trait Node, o que causa muita duplicação de código.
  • É possível usar macros para automatizar a definição de structs e a implementação do trait Node.

Macro para eliminar duplicação de código

  • A macro define structs, adiciona comentários de documentação e implementa funções que satisfazem o trait Node.
  • A macro pode adicionar vários campos por meio de definições repetitivas de metavariáveis.

Testes

  • Em Rust, é possível implementar uma abordagem semelhante aos testes baseados em tabela do Go.
  • As macros test_group_pass_assert! e test_group_fail! podem ser usadas para testar vários pares de entrada e saída esperada.

Testes do parser

  • No módulo do parser, macros semelhantes também são usadas para testar os resultados de instruções SQL.
  • A função sql_stmt_prefix é usada para testar a instrução SQL EXPLAIN.

Desvantagens das macros

  • O rust-analyzer não funciona bem dentro de macros, e a documentação é insuficiente.

Correspondência de caracteres

  • A macro matches! do Rust permite comparar caracteres com facilidade.
  • Há um exemplo de como verificar se um determinado caractere é um número do SQLite.

Correspondência de tokens

  • Depois que o lexer converte um fluxo de caracteres em um fluxo de tokens, o parser o utiliza para gerar a árvore sintática.
  • A instrução match é usada para reconhecer tipos de token.

Exibição de erros

  • O tratamento de erros fornece mensagens claras para o usuário.

Recursos opcionais

  • O tipo Option do Rust pode ser usado para verificar se um valor existe, avaliar condições ou fornecer um valor padrão.
  • Métodos como is_some_and, map e map_or melhoram a legibilidade do código.

Iteradores

  • Os iteradores do Rust são usados para filtrar caracteres e processá-los de acordo com as regras de análise numérica do SQLite.

1 comentários

 
GN⁺ 2024-11-09
Comentários no Hacker News
  • Teve dificuldades para usar Rust por causa do borrow checker e da complexidade da gestão de memória. Gostava dos elementos de programação funcional (FP) de Rust, mas decidiu procurar outra linguagem. Descobriu OCaml e ficou satisfeito

  • Parece haver pouca experiência com Rust e com ideias de PL. Acha que seria mais simples definir a AST como um tipo de dado algébrico. Macros funcionam de forma diferente na maioria das linguagens, mas são usadas principalmente para remover duplicação de código e reduzir repetição

  • Um parser escrito em Haskell se destaca pela simplicidade e legibilidade. Pode ser lido quase como BNF, com pouquíssimo procedimento técnico, permitindo focar na gramática real

  • Tem experiência escrevendo parsers em Ragel, Go, Java, C++, C. Escrever um parser JSON em C pode ser mais simples do que o código em Rust. A infraestrutura de parsers evoluiu até chegar a um ponto em que é possível criar parsers em eBNF

  • Escreveu um disassembler e um emulador de eBPF em Rust e acha que Rust é adequado para tarefas de parsing. Porém, usar macros parece diferente de trabalhar dentro da própria linguagem

  • Gosta da palestra de Rob Pike sobre varredura léxica em Go. É uma abordagem didática e elegante

  • É possível usar uma biblioteca de parser combinators para implantar parsers de protocolo de alto desempenho em ambientes embarcados. A mesma biblioteca pode ser usada para escrever um parser de protocolo embarcado

  • Ao escrever um parser AST completo em Rust, achou difícil expressar a hierarquia de tipos concretos da AST. Teve que usar truques estranhos de tipos e macros

  • Fazer parsing da sintaxe do sqlite é uma tarefa difícil. sqlite é uma fonte inspiradora. Os diagramas railroad são muito úteis, e o gerador de parser Lemon não recebe reconhecimento suficiente

  • Linguagens com tipos de dados algébricos são adequadas para fazer parsing da sintaxe do sqlite. Typescript também pode ser uma boa escolha. Escreveu uma introdução simples sobre como escrever parsers em Rust