AVISOS - Avaliação em Época Normal |
---|
Esclarecimento de dúvidas:
|
Requisitos para desenvolvimento, material de apoio e actualizações do enunciado (ver informação completa em Projecto de Compiladores):
|
Processo de avaliação (ver informação completa em Avaliação do Projecto):
|
Material de Uso Obrigatório |
---|
As bibliotecas CDK e RTS de apoio ao desenvolvimento do projecto são de uso obrigatório: |
|
A máquina virtual, fornecida para desenvolvimento do projecto, já contém todo o material de apoio. |
Uso Obrigatório: Repositório GIT |
Apenas se consideram para avaliação os projectos existentes no repositório GIT oficial. Apenas se considera para avaliação o ramo main.
Trabalhos não presentes no repositório no final do prazo têm classificação 0 (zero) (não são aceites outras formas de entrega). Não são admitidas justificações para atrasos em sincronizações do repositório. A indisponibilidade temporária do repositório, desde que inferior a 24 horas, não justifica atrasos na submissão de um trabalho. |
A linguagem zu é uma linguagem imperativa e é apresentada de forma intuitiva neste manual. São apresentadas características básicas da linguagem (tipos de dados, manipulação de nomes); convenções lexicais; estrutura/sintaxe; especificação das funções; semântica das instruções; semântica das expressões; e, finalmente, alguns exemplos.
ENUNCIADO EM PREPARAÇÃO
A linguagem é fracamente tipificada (são efectuadas algumas conversões implícitas). Existem 4 tipos de dados, todos compatíveis com a linguagem C, e com alinhamento em memória sempre a 32 bits:
Os tipos suportados por cada operador e a operação a realizar são indicados na definição das expressões.
Os nomes (identificadores) correspondem a constantes, variáveis e funções. Nos pontos que se seguem, usa-se o termo entidade para as designar indiscriminadamente, explicitando-se quando a descrição for válida apenas para um subconjunto.
O espaço de nomes global é único, pelo que um nome utilizado para designar uma entidade num dado contexto não pode ser utilizado para designar outras (ainda que de natureza diferente).
Os identificadores são visíveis desde a declaração até ao fim do alcance: ficheiro (globais) ou função (locais). A reutilização de identificadores em contextos inferiores encobre declarações em contextos superiores: redeclarações locais podem encobrir as globais até ao fim de uma função. É possível utilizar símbolos globais nos contextos das funções, mas não é possível defini-los (ver símbolos globais).
As entidades globais (declaradas fora de qualquer função), existem durante toda a execução do programa. As variáveis locais a uma função existem apenas durante a sua execução. Os argumentos formais são válidos enquanto a função está activa.
Para cada grupo de elementos lexicais (tokens), considera-se a maior sequência de caracteres constituindo um elemento válido.
São considerados separadores e não representam nenhum elemento lexical: mudança de linha ASCII LF (0x0A, \n), recuo do carreto ASCII CR (0x0D, \r), espaço ASCII SP (0x20, ) e tabulação horizontal ASCII HT (0x09, \t).
Existem dois tipos de comentários, que também funcionam como elementos separadores:
Se as sequências de início fizerem parte de uma cadeia de caracteres, não iniciam um comentário (ver definição das cadeias de caracteres).
A linguagem não tem palavras chave. Todas as palavras correspondem a identificadores.
O identificador zu, embora não reservado, corresponde à função principal.
Os seguintes elementos lexicais designam tipos em declarações (ver gramática): # (inteiro), % (real), $ (cadeia de caracteres).
Os tipos correspondentes a ponteiros são delimitados por < e por > (ver gramática).
São considerados operadores os elementos lexicais apresentados na definição das expressões.
Os seguintes elementos lexicais são delimitadores/terminadores: , (vírgula), ; (ponto e vírgula), ! e !! (operações de impressão), e ( e ) (delimitadores de expressões).
São iniciados por uma letra ou por _ (sublinhado), seguindo-se 0 (zero) ou mais letras, dígitos ou _ (sublinhado). O comprimento do nome é ilimitado e dois nomes são distintos se houver alteração de maiúscula para minúscula, ou vice-versa, de pelo menos um carácter.
São notações para valores constantes de alguns tipos da linguagem (não confundir com constantes, i.e., identificadores que designam elementos cujo valor não pode ser alterado durante a execução do programa).
Um literal inteiro é um número não negativo. Uma constante inteira pode, contudo, ser negativa: números negativos são construídos pela aplicação do operador menos unário (-) a um literal positivo.
Literais inteiros decimais são constituídos por sequências de 1 (um) ou mais dígitos de 0 a 9, em que o primeiro dígito não é 0 (zero), excepto no caso do número 0 (zero). Neste caso, é composto apenas pelo dígito 0 (zero) (em qualquer base).
Literais inteiros hexadecimais começam sempre com a sequência 0x, seguida de um ou mais digitos de 0 a 9 ou de a a f (sem distinguir maiúsculas de minúsculas). As letras de a a f representam os valores de 10 a 15 respectivamente. Exemplo: 0x07.
Se não for possível representar o literal inteiro na máquina, devido a um overflow, deverá ser gerado um erro lexical.
Os literais reais são expressos em notação científica (tal como em C). Exemplo: 12.34e-24 = 12.34 x 10-24.
Um literal sem . (ponto decimal) nem parte exponencial é do tipo inteiro.
As cadeias de caracteres são delimitadas por aspas (") e podem conter quaisquer caracteres, excepto ASCII NULL (0x00 \0). Nas cadeias, os delimitadores de comentários não têm significado especial. Se for escrito um literal que contenha \0, então a cadeia termina nessa posição. Exemplo: "ab\0xy" tem o mesmo significado que "ab".
É possível designar caracteres por sequências especiais (iniciadas por \), especialmente úteis quando não existe representação gráfica directa. As sequências especiais correspondem aos caracteres ASCII LF, CR e HT (\n, \r e \t, respectivamente), aspa (\"), barra (\\), ou a quaisquer outros especificados através de 1 ou 2 digitos hexadecimais (e.g. \0a ou apenas \a se o carácter seguinte não representar um dígito hexadecimal).
Elementos lexicais distintos que representem duas ou mais cadeias consecutivas são representadas na linguagem como uma única cadeia que resulta da concatenação. Exemplo: "ab""cd" é o mesmo que "abcd".
O único literal admissível para ponteiros é 0, indicando o ponteiro nulo.
A gramática da linguagem está resumida abaixo. Considerou-se que os elementos em tipo fixo são literais, que os parênteses curvos agrupam elementos, que elementos alternativos são separados por uma barra vertical, que elementos opcionais estão entre parênteses rectos, que os elementos que se repetem zero ou mais vezes estão entre e . Alguns elementos usados na gramática também são elementos da linguagem descrita se representados em tipo fixo (e.g., parênteses).
GRAMÁTICA A FORNECER
Algumas definições foram omitidas da gramática: tipos de dados, identificador (ver identificadores), literal (ver literais); expressão (ver expressões).
Os left-values são posições de memória que podem ser modificadas (excepto onde proibido pelo tipo de dados). Os elementos de uma expressão que podem ser utilizados como left-values encontram-se individualmente identificados na semântica das expressões.
Um ficheiro é designado por principal se contiver a função principal (a que inicia o programa).
Uma declaração de variável indica sempre um tipo de dados e um identificador.
Exemplos:
Por omissão, os símbolos são privados a um módulo, não podendo ser importados por outros módulos.
O marcador ! permite declarar um identificador como público, tornando-o acessível a partir de outros módulos.
O marcador ? (opcional para funções) permite declarar num módulo entidades definidas em outros módulos. As entidades não podem ser inicializadas numa declaração importada.
Exemplos:
Quando existe, é uma expressão que segue o sinal = ("igual"): inteira, real, ponteiro. Entidades reais podem ser inicializadas por expressões inteiras (conversão implícita). A expressão de inicialização deve ser um literal se a variável for global.
As cadeias de caracteres são (possivelmente) inicializadas com uma lista não nula de valores sem separadores. Estes valores são sempre constantes, independentemente de o identificador que as designa ser constante ou não.
Exemplos:
Os exemplos não são exaustivos e não ilustram todos os aspectos da linguagem. Podem obter-se outros na página da disciplina.
Estão disponíveis outros pacotes de testes.
Casos omissos e erros serão corrigidos em futuras versões do manual de referência.