Processamento de Linguagens (LEI - 3ºano)
Este ficha prática contem exercícios para serem resolvidos nas aulas teórico-práticas com vista a sedimentar os conhecimentos relativos a:
Para introduzir a ferramenta de geração de programas FLex baseada em especificações com Expressões Regulares, e para ilustrar a importância do uso de autómatos deterministas reactivos como suporte à construção de programas eficientes, propõem-se alguns exercícios, para resolver dentro ou fora da aula, que visam a criação de programas autónomos para filtrar textos (FT).
Suponha que ao fim de cada entrevista um Repórter produz um texto com as perguntas e respostas, distinguindo umas das outras porque as perguntas começam com 'EU:', no início da linha, e as respostas começam com 'ELE:', também no início da linha.
Nesse contexto, pretende-se desenvolver um FT para processar os questionários que:
Quando se retiram apontamentos, ou de uma forma geral, se tem de escrever muito depressa, é hábito usar abreviaturas que correspondam a uma ou mais palavras vulgares e longas.
Suponha que criou esse costume e resolveu inserir nos seus textos as ditas abreviaturas (2 ou mais letras) precedidas pelo carácter '\'. Por exemplo: '\qq' (qualquer), ou '\mb' (muito bom), ou ainda '\sse' (se e só se).\
Desenvolva então as seguintes alíneas:
Construa um Filtro de Texto que adicione todos os números dum texto e que, no final, imprima a sua soma (no ficheiro de saída não deve aparecer nenhum caracter do texto de entrada).
Evolua o seu processador no sentido de:
Como sabe um Documento XML é um texto vulgar semeado de anotações, ou marcas, que são identificadores especiais (designados por elementos XML) intercalados entre os caracteres '<' e '>'. Num documento XML bem formado, a cada marca de abertura corresponderá uma marca de fecho, que tem o mesmo identificador, mas que começa por '</' terminando na mesma em '>'.
Desenvolva um filtro de texto (FT) que receba um documento XML e:
Os Emails escritos à moda PRH caracterizam-se por terem todas as palavras começadas por letras minúsculas, à exceção dos nomes próprios e siglas.
Desenvolva, então:
Construa um programa em Lex que apresente todas as palavras e números do texto fonte, indicando o número da linha onde se encontram (numa segunda versão indique também em que coluna da linha é iniciada a palavra ou o número).
Um número misto é constituído por uma parte inteira e uma fração própria (numerador é inferior ao denominador). Exemplos: 5 3/4, 1 2/3, 100 27/35.
Especifique um processador em lex que responda às seguintes alíneas:
Normalmente, um programa/processador que converte uma sequência de carateres numa sequência de símbolos/tokens é designado por tokenizer.
Neste exercício deverás especificar um programa em C que usará um processador gerado pelo flex para reconhecer os vários símbolos da linguagem e indicar na saída a respetiva sequência de símbolos.
Os símbolos a reconhecer pertencem à linguagem duma calculadora aritmética simples e são:
O teu programa deverá aceitar frases do tipo:
23+(4*76)
e gerar:
INT OP AP INT OP INT FP
O objetivo deste exercício é aprenderes a integrar o código gerado pelo flex numa aplicação em C.
Pretende-se que utilize a ferramenta flex para implementar uma máquina de es- tados que modele a interacção dum utilizador com um telefone numa cabine pública.
O telefone reage aos seguintes comandos:
Como extra pode ainda detalhar como é que é devolvido o troco: quantas moedas e de que espécie compõem o troco.
A seguir apresenta-se uma possível interacção exemplo.
LEVANTAR maq: "Introduza moedas." MOEDA 10c, 30c, 50c, 2e. maq: "30c - moeda inválida; saldo = 2e60c" T=601181818 maq: "Os números vermelhos estão proibidos!" T=253604470 maq: "saldo = 2e35c" POUSAR maq: "troco=2e35c; Volte sempre!" ou maq: "troco= 1x2e, 1x20c, 1x10c, 1x5c; Volte sempre!"
Um programador para controlo dum sistema de iluminação de jardim, depois de ligado à corrente, pode ser de novo desligado, ou então aceita dois comandos: manual ou automatico.
Em modo manual pode ser colocado em on (as luzes ficam a partir daí e até novo comando ligadas), ou em off (as luzes são desligadas e assim permanecem).
Em modo automático requer, ainda, mais duas indicações, a hora (0 a 24) a que deve ser ligado e o número de horas que deve permanecer ligado; fica, então, em stand-by até que receba um sinal para acender as luzes, mantendo as luzes acesas até ter recebido um número de impulsos de relógio igual ao número de horas para que foi programado.
Considerando que o sistema a modelar pode ser encarado como uma máquina de Transição de Estados, desenhe o autómato determinista reativo que modela o sistema e utilize a sua imaginação para o implementar em C com a ajuda do Lex.
Uma das variantes do conhecido jogo das setas (em que se lançam pequenas flechas contra um alvo circular dividido em sectores iguais marcados com pontos de 1 a 20) é designada por jogo dos 36: um jogador ganha quando, ao fim de lançar várias setas, conseguir acumular exactamente 36 pontos; perderá logo que a soma ultrapasse esse valor. Contudo só contam os pontos quando uma seta atingir um dos seguintes sectores: 19, 17, 20, 16, 10, 6, 12; cada vez que uma seta caia noutro sector, com pontos diferentes destes, a jogada não conta, é ignorada.
Pretende-se, então, desenvolver um programa eficiente que vá recebendo os pontos obtidos por um jogador e determine se este deve continuar a jogar, ou se deve parar por já ter ganho, ou por ter perdido. Considerando que o sistema a modelar pode ser encarado como uma Máquina de Transição de Estados, desenhe o autómato determinista reactivo que modela o sistema e implemente-o com a ferramenta flex do Unix.
Numa galáxia distante, num planeta muito diferente do nosso, cada utilizador dum computador tem um identificador que segue o seguinte formato:
Dada uma lista de nomes de utilizadores, um por linha, verifica quais são válidos.
Para esses, imprime "VALIDO" numa linha. Para os outros casos imprime "INVALIDO".
Exemplo de input:
_0898989811abced_ _abce _09090909abcD0
Exemplo de output:
VALIDO INVALIDO INVALIDO
Dada uma lista de endereços IP, IPv4 ou IPv6, supostamente válidos, especifica um filtro que identifica o tipo de endereço IP ou acusa um erro.
Os endereços IPv4 foram os primeiros endereços a serem usados na Internet e eram constituídos por 4 bytes. O formato normal é "A.B.C.D" em que A, B, C e D são inteiros compreendidos entre 0 e 255 inclusive.
O IPv4 limitava o número de endereços a um número baixo para as necessidades de hoje em dia e assim surgiu o IPv6. Com 128 bits, veio permitir um maior espaço de endereçamento. Os 128 bits dum endereço IPv6 são representados em 8 grupos de 16 bits cada um. Cada grupo é representado por 4 dígitos hexadecimais e cada grupo é separado do seguinte por ':'. Por exemplo: "2001:0db8:0000:0000:0000:ff00:0042:8329". Os zeros à esquerda podem ser omitidos. Um endereço contendo "...:0:..." ou "...:5:..." é idêntico a "...:0000:..." ou "...:0005:....".
Exemplo de input:
Esta é uma linha de lixo. 121.18.19.20 2001:0db8:0000:0000:0000:ff00:0042:8329 epl.di.uminho.pt 193.136.19.129
Exemplo de output:
Erro IPv4 IPv6 Erro
Dada uma lista de pares de coordenadas, latitude e longitude, supostamente válidos, especifica um filtro que faz a sua verificação atendendo aos seguintes requisitos:
Exemplo de input:
(75, 180) (+90.0, -147.45) (77.11112223331, 149.99999999) (+90, +180) (90, 180) (-90.00000, -180.0000) (75, 280) (+190.0, -147.45) (77.11112223331, 249.99999999) (+90, +180.2) (90., 180.) (-090.00000, -180.0000)
Exemplo de output:
Válido Válido Válido Válido Válido Válido Inválido Inválido Inválido Inválido Inválido Inválido
Num país algures, as matrículas seguem os seguintes requisitos:
Especifique um programa em flex que apanhe e contabilize as matrículas num texto.