Geração de Código C para Go
Esta etapa gera um arquivo Go equivalente para o subconjunto de C suportado pelo projeto. A geração final passa pelo código intermediário estruturado, e o arquivo de saída padrão é:
saida.go
Fluxo
- O Flex transforma o código C em tokens.
- O Bison valida a gramática e constrói a AST.
- A tabela de símbolos registra variáveis e escopos.
- A análise semântica preenche tipos básicos e detecta alguns erros.
- A AST é convertida para um código intermediário estruturado.
- O gerador percorre o intermediário e escreve o código Go final.
O fluxo principal fica:
C -> tokens -> AST -> semântica -> intermediário -> saida.go
O intermediário também é impresso no terminal para facilitar depuração e apresentação da etapa.
Construções traduzidas
| C | Go |
|---|---|
int x = 1; |
var x int = 1 |
x = x + 1; |
x = (x + 1) |
while (x < 3) { ... } |
for (x < 3) { ... } |
if (...) { ... } else { ... } |
if ... { ... } else { ... } |
return expr; em função comum |
return expr |
return expr; em main |
fmt.Println(expr); return |
soma(2, 3) |
soma(2, 3) |
Chamadas para funções definidas depois do ponto de uso também são aceitas, porque a análise semântica coleta as assinaturas antes de validar as chamadas.
Exemplo
Entrada C:
int soma(int a, int b) {
return a + b;
}
int main() {
int r = soma(2, 3);
return r;
}
Saída Go:
package main
import "fmt"
func soma(a int, b int) int {
return (a + b)
}
func main() {
var r int = soma(2, 3)
fmt.Println(r)
return
}
Trecho do intermediário gerado para o mesmo exemplo:
func soma int
param a int
param b int
return (a + b)
endfunc
func main int
decl r int = soma(2, 3)
return r
endfunc
Testes
Os testes de geração ficam em:
tests/codegen/inputs/
tests/codegen/expected/
Para executar:
make codegen-test
O teste compila cada entrada C, passa por AST, semântica e intermediário, captura
o saida.go gerado e compara com o Go esperado.
Limitações assumidas
O projeto não implementa C completo. Ponteiros, struct, union, typedef,
include, alocação dinâmica e biblioteca padrão de C ficam fora do escopo atual.
O objetivo é manter um subconjunto pequeno, correto e demonstrável.