O nome do compilador corresponde sempre ao nome da linguagem. O processo envolve três etapas: compilação do código fonte, compilação do código gerado (pelo nasm) e ligação dos módulos binários no executável final (incluindo a librts.a).
Assumindo a distribuição do Compact na directoria actual e a directoria "examples" com os programas de teste, as seguintes acções seriam necessárias para compilar o exemplo 1 (ex1.cpt):
./compact examples/ex1.cpt
yasm -felf examples/ex1.asm
ld -o examples/ex1 examples/ex1.o -lrts
Os vários comandos podem diferir nos parâmetros exactos (dependendo do ambiente). Por exemplo, se a librts.a não estiver numa localização conhecida pelo "ld", então é necessário dar o comando da seguinte forma:
ld -o examples/ex1 examples/ex1.o -L$HOME/compiladores/root/usr/lib -lrts
Compilação de um programa Compact para Produzir outra Saída
O nome do compilador corresponde sempre ao nome da linguagem. O processo de produção (tradução) de uma outra linguagem (C, XML, etc.) a partir do original Compact é semelhante ao descrito para a compilação para produção de um executável (nesse caso, a tradução é de Compact para ASM).
Assumindo a distribuição do Compact na directoria actual e a directoria "examples"com os programas de teste, as seguintes acções seriam necessárias para traduzir o exemplo 1 (ex1.cpt) para XML:
./compact examples/ex1.cpt -target xml
Neste caso, a saída do compilador é o ficheiro ex1.xml. Resultados semelhantes seriam obtidos para os outros "targets". Um comando equivalente ao anterior é o seguinte:
./compact examples/ex1.cpt -o examples/ex1.xml
Compilação do Compact: doxygen
Q: Quando tento compilar o Compact, o make produz um erro ao tentar executar o programa "doxygen". O que estou a fazer mal?
R: O programa "doxygen" é utilizado para gerar documentação automaticamente a partir do código (à la Javadoc). É um programa livremente distribuído e está contido em muitas distribuições Linux, assim como para outras plataformas.
Produção de Executáveis (incompatibilidades)
Q: Ao executar o "ld" com os ficheiros criados com o compilador e usando as opções -L$HOME/compiladores/root/usr/lib -lrts, aparece a seguinte mensagem de erro:
ld: skipping incompatible .../compiladores/root/usr/lib/librts.a when searching for -lrts
ld: cannot find -lrts
R: Este erro ocorre devido a incompatibilidade entre formatos binários (entre os módulos do programa e a biblioteca), tipicamente, entre 32 bits e 64 bits. A solução é utilizar apenas uma arquitectura (note-se que o "nasm" apenas suporta binários de 32 bits) ou, se possível, passar ao "ld" as opções de compilação em 32 bits (consultar manual).
Produção de um Executável
Q: Na produção de um executável Compact depois de realizadas as fases de compilação e geração de módulo binário ( .o), devo produzir o executável com o comando " gcc examples/ex1.o -o ex1"?
R: O GCC, tal como invocado acima, só serve para produzir executáveis baseados em C, já que o comando não é mais que uma chamada ao ld em que é passada a libc como argumento:
ld -o examples/ex1.o -o ex1 -lc
No caso do Compact (ou de outro compilador semelhante), o que se deve fazer é:
ld -o examples/ex1.o -o ex1 -lrts
Q: Na especificação YACC do Compact, o que é o %prec? E o que quer dizer %nonassoc IFX (no .l não é reconhecido nenhum token chamado IFX)?
R: %prec é uma definição de precedência de operadores; %nonassoc indica que um operador não é associativo. Estas directivas permitem ao parser tomar decisões relativamente a situações em que a gramática seria ambígua. Quando a gramática não é ambígua, as directivas são simplesmente ignoradas. IFX é um token utilizado pelo parser para resolução de uma potencial ambiguidade na gramática do Compact.
Token UMINUS
Q: O que é? Não é detectado pelo Flex.
R: O token UMINUS é um token definido na especificação YACC do Compact. É utilizado para definir a precedência dos operadores unários representados pelos tokens '-' e '+' (esses, sim, reconhecidos pelo analisador lexical).