flex (software)

Da Wikipedia, l'enciclopedia libera.

flex è un generatore automatico di scanner. Uno scanner è un programma che, dato in input uno stream di caratteri, compie delle azioni ogni volta che incontra una determinata combinazione di caratteri (token). Per questa ragione il programma generato viene anche detto tokenizer, o analizzatore lessicale. Flex è lo standard per la generazione automatica di scanner in linguaggio C. Viene utilizzato insieme a GNU Bison per generare automaticamente programmi in grado di eseguire il parsing di stream di caratteri appartenenti ad un determinato linguaggio formale. Un'applicazione tipica è quella della scrittura di compilatori: il programma scritto dall'utente è lo stream di caratteri in ingresso. Lo scanner analizza questo file riconoscendo le parole chiave ed i simboli del linguaggio, passando il proprio output al parser, il quale ha il compito di riconoscere le vere e proprie regole grammaticali del linguaggio e produrre il codice macchina corrispondente al programma iniziale, o di segnalare gli errori incontrati.

flex è l'alternativa libera a Lex

Un semplice esempio[modifica | modifica wikitesto]

codice di esempio.l:

%{
#include <stdio.h>
%}

%%
ACCENDI     {printf("Ho ricevuto il comando accendi \n");}
SPEGNI     {printf("Ho ricevuto il comando spegni \n");}

[ \t]+  /* ignora spazio bianco */
#.*             /* ignora commenti */
\n              /* ignora gli a capo */
%%

Tra i segni % iniziali si inserisce il codice che deve essere eseguito prima dello scanner. Tra i segni %% trovano posto le regole per riconoscere i token. Ciascuna regola è composta da un'espressione regolare, uno o più caratteri di tabulazione e da un blocco di codice C tra parentesi graffe. Il codice viene eseguito ogni volta che viene incontrato quanto specificato dall'espressione regolare. Quando, come nelle ultime tre regole, non viene specificato il blocco C da eseguire, i caratteri che corrispondono all'espressione regolare della regola vengono ignorati. Se una sequenza di caratteri in ingresso non soddisfa alcuna regola, essa viene restituita in output (echo).

Per compilare, in ambiente unix:

passo 1) flex esempio.l
questo genera il file lex.yy.c

passo 2) cc lex.yy.c -o esempio -lfl
questo compila lex.yy.c nell'eseguibile esempio

ora eseguendo il programma con il comando ./esempio e digitando dei caratteri, qualsiasi stringa viene ricopiata a console, ad eccezione delle parole chiave definite nelle due regole dello scanner: ogni volta che si digita ACCENDI o SPEGNI, seguiti da invio, il programma risponde con il corrispondente testo nelle printf. Questo esempio giocattolo illustra lo scopo di flex: un completo programma C per analizzare una sequenza di caratteri (o un file) è stato generato a partire da due semplici regole. Per visualizzare il programma generato da Flex digitare cat lex.yy.c Per fare analizzare un file di testo al programma digitare cat fileditesto.txt | ./esempio

Riconoscimento di pattern complessi e conflitti tra regole[modifica | modifica wikitesto]

Flex non si limita a riconoscere semplici parole, ma ciascuna regola può consistere in un'espressione regolare, permettendo così di riconoscere classi di parole. Se due espressioni regolari si trovano in conflitto, Flex sceglie quella in grado di coprire il maggior numero di caratteri:

regola 1: ABC
regola 2: [A-E]*
stringa: ABCDE

viene utilizzata la regola 2.

Se due espressioni regolari si trovano in conflitto, ed entrambe coprono lo stesso numero di caratteri nella stringa, viene utilizzata quella definita più in alto nel file:

regola 1: X[0-9]+Y[0-9]+
regola 2: [A-Z0-9]*
stringa: X45Y66

viene scelta la prima regola.

Passaggio dei token al parser[modifica | modifica wikitesto]

Per passare i token riconosciuti al parser del linguaggio, si utilizza l'istruzione C return seguita dal nome del token che si vuole passare. Per convenzione e leggibilità vengono utilizzati solo caratteri maiuscoli per i nomi dei token. Ad esempio una regola potrebbe essere:

[a-zA-Z][a-zA-Z0-9]*     {return TOKIDENTIFIER;}

che riconosce gli identificatori validi del linguaggio C.

Bibliografia[modifica | modifica wikitesto]