Linguaggi Formali e Automi 2004
Esercitazioni - Violetta Lonati

In questa pagina trovate le seguenti lezioni: NOTA: è garantito il permesso di copiare, distribuire e/o modificare i materiali contenuti in questa pagina seguendo i termini della Licenza per Documentazione Libera GNU, Versione 1.1 o ogni versione successiva pubblicata dalla Free Software Foundation, con il riferimento all'Autore e alla presente nota. Una copia della licenza è reperibile a questo indirizzo.

Espressioni regolari in UNIX

Esercitazione di martedi' 11 maggio 2004 (II turno) - mercoledi' 12 maggio 2004 (I turno)


Le espressioni regolari sono usate in UNIX come formalismo per specificare linguaggi sull'alfabeto dei caratteri. Molti comandi importanti effettuano infatti elaborazioni di testi e possono essere applicati a insiemi di stringhe specificate attraverso sottoclassi di ER, oppure attraverso estensioni di ER. L'obiettivo della lezione è mostrare alcuni esempi di utilizzo di questi comandi.

Materiali disponibili:

Ricerca di pattern - Comando Grep

I seguenti comandi specificano pattern da ricercare all'interno del file lista (risultato del comando ls -l).

Find and replace - Comando Sed

Applichiamo i comandi al semplice file chiamato citta contentente questo breve testo:
1.nazione francia,città parigi
2.nazione italia,città milano
3.nazione germania,città dresda

Analizzatore lessicale - Comando Lex (o Flex)

Costruiamo un analizzatore lessicale per il linguaggio C seguendo lo schema dei lucidi.
L'esempio è tratto dalla dispensa del corso (autori: Alberto Bertoni e Beatrice Palano).
  1. Costruiamo un file tokens che elenca delle associazioni
    'espressione regolare - azione (comando in C)':
    %%
    [ \t\n]				;
    \{				printf("BEGIN\n");
    \}				printf("END\n");
    [()]				printf("%s\n",yytext);
    "//"[^\n]*[\n]			printf("rem: //\n");
    if|else				printf("key: %s\n",yytext);
    [A-Za-z][A-Za-z0-9]*		printf("var: %s\n",yytext);
    ==|\>|\<|\<=|\>=|!=		printf("opc: %s\n",yytext);
    [0-9]+(\.[0-9]+)?		printf("num: %s\n",yytext);
    [A-Za-z]+\([A-Za-z",]*\);?	printf("fun: %s\n",yytext);
    %%
    
  2. Eseguiamo il comando flex sul file 'tokens' con il comando
    flex tokens
    ottenendo come output il file lex.yy.c

  3. Compiliamo il file ottenuto con il comando
    cc lex.yy.c -lfl -o lexical
    ottenendo il file eseguibile 'lexical'.

  4. Eseguiamo 'lexical'. Se non specifichiamo l'input, possiamo inserire linee di codice che vengono interpretate una per volta. Possiamo anche eseguire lexical su un file, ad esempio sul seguente frammento di programma C:
    //frammento di un programma C
    main()
    {
    if (budget>=1999.99)
            stampa("ok");
    else
            stampa("ko");
    }
    
    ottenendo una riscrittura interna del programma che evidenzia variabili, commenti, numeri, parole chiave....

Nota: il frammento precedente e' molto semplice. Dando in input a lexical un file leggermente piu' complesso, molte cose non vengono ben interpretate dall'analizzatore lessicale. Provate ad esempio con il file acerhk.mod.c:
#include 
#include 
#include 

MODULE_INFO(vermagic, VERMAGIC_STRING);

static const char __module_depends[]
__attribute_used__
__attribute__((section(".modinfo"))) =
"depends=";
Sebbene corto, il programma precedente dà vari problemi. E' necessario quindi precisare maggiormente e estendere le specifiche del file 'tokens', ad esempio: Naturalmente bisogna poi ripetere l'esecuzione del comando lex e della compilazione in c.

Linguaggi di Markup

Esercitazione di giovedì 3 giugno 2004 (I turno) - martedì 8 giugno 2004 (II turno)

Materiali disponibili:

Esempio: sessioni di laurea




Violetta Lonati
2004-05-16