Lekseemide leidmise kõrval peab skanner moodustama ka nn nimede tabeli (nametable), mis kirjeldab kõiki transleeritava (skaneeritava) programmi identifikaatoreid: milline on muutuja tüüp (range tüübikontrolliga keeltes), milline on muutuja praegune väärtus (või viit mäluosale, kus muutuja on salvestatud); kui transleeritavas keeles saab deklareerida konstante ja kasutatada funktsioone, siis kantakse ka need tavaliselt tabelisse, sest nende käsitlemine (näiteks) aritmeetilises avaldises sarnaneb identifikaatorite käsitlemisega; tavaliselt kasutatakse nende kõigi jaoks terminit (mitteterminali) nimi (name). Skaneerimisel genereeritakse kõigi identifikaatorite jaoks ühesugune lekseem (IDENT), vaid selle lekseemi spetsifikatsioonis olev viit nimede tabelisse võimaldab hiljem leida identifikaatori tüübi ja viida mäluosale, kus salvestatakse identifikaatori väärtus.
Nimede tabeli andmestruktuuri võib olla fikseeritud pikkusega tabel või viitadega nimistu. Tabeli kasutamisel on programmis esineda võivate muutujate arv määratud tabeli pikkusega. Viitadega nimistu kasutamisel seda kitsendust pole, kuid tabeli kasutamisega tutvumiseks on tabel (array) lihtsam, samuti on kiirem tablisse identifikaatorite lisamine ja otsimine (viitadega nimede tabeli realiseerimist on kirjeldatud peatükis "Mäluga kalkulaator").
Järgnevas on Flex-i sisendfail, mis kirjeldab ka Flex-i abil programmis esinevate identifikaatorite kogumist vektoriks (char array); siin ei genereerita veel mingit väljundit (skaneerimise tulemusena saadavat lekseemide jada), kuid arvud (täis- ja reaalarvud) muudetakse juba arvudeks (lähtetekstis on nad sümbolite jadad) ja kahesümboliline omistusmärk := asendatakse ühe lekseemiga, kusjuures ':', '=' võivad esineda ka tavaliste eraldajatena.
Identifikaatori leidmisel peab skanner kõigepealt kontrollima, kas see identifikaator juba esineb nimede tabelis. Kui esineb, peab kontroll väljastama viida tabeli reale, kus identifikaator on kirjeldatud (siin kirjeldatakse tabelis vaid identifikaatori nimi); kui ei, lisama identifikaatori tabelisse. Allpoolesitatud tekstis näitab mõlemal juhul muutuja Index, millisel tabeli real muutuja on kirjeldatud. Kuna identifikaatori esinemise kontrollis kasutatakse C-keele stringifunktsioni strcomp, tuleb programmi algul include-lausega lisada ka teek string.h, kus see funktsioon on kirjeldatud. Funktsiooni strcomp kasutamisel peab meeles pidama, et see kontrollib mitte-võrdumist (tulemus on tõene, kui võrreldavad stringid on erinevad), seega stringid on võrdsused, kuid eitus !strcomp on tõene.
%option noyywrap
%{
#include <math.h>
#include <string.h>
#include <stdio.h>
int num;
int i,j,k,Index,on,n=0;
float realnum;
char c, nimed[50][10];
/* nametable; < 50 names are allowed in a program */
%}
DIGIT [0-9]
ID [A-Za-z][A-Za-z0-9]*
OMISTUS :=
ERALDAJA ["=" ";" "<" ">" ":" "(" ")" "{" "}"]
%%
{DIGIT}+ {
num=atoi(yytext);
printf( "Täisarv: %s (%d)\n", yytext, num );
}
{DIGIT}+"."{DIGIT}* {
realnum=atof(yytext);
printf( "Reaalarv: %s (%g)\n", yytext, realnum );
}
"."{DIGIT}+ {
realnum=atof(yytext);
printf( "Reaalarv: %s (%g)\n", yytext, realnum );
}
if|then|begin|end|procedure|function|main|else {
printf( "Võtmesõna: %s\n", yytext );
}
{ID} {
/* kontrollime, kas on juba tabelis? */
on=0;
for (j=0;j<n;j++)
if (!(strcmp(nimed[j],yytext))) {on=1;Index = j;}
if (on==0) /* ei leitud */
{Index = n;
for (i=0;i < yyleng;i++ ) /* lisame tabelisse
*/
nimed[n][i] = yytext[i];
nimed[n][yyleng]=0x00;
/* 0x00 - stringi terminaator! */
n++; }
printf( "Identifikaator: %s, tabeli indeks: %d\n", yytext,Index);
};
{OMISTUS} printf("Omistamine: %s\n",yytext);
"+"|"-"|"*"|"/"|">"|"<"|"=" printf( "Operaator: %s\n", yytext );
"{"[^}\n]*"}" /* kustuta üherealised kommentaarid */
[ \t\n]+ /* kustuta tühikud */
{ERALDAJA} printf("Eraldaja: %s\n", yytext);
. printf( "Viga: %s\n", yytext );
%%
main( argc, argv )
int argc;
char **argv;
{
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
yylex();
printf("\nIdentifikaatorieid: %d\n", n);
/* trükime tabeli */
for (i=0;i < n;i++)
{
printf("%d: ",i);
k = 0;
c = nimed[i][k];
while (c != 0x00)
{printf ("%c", c);
k++;
c = nimed[i][k];
};
printf("\n");
}
}
Selle programmi testimisel failiga
if A1>B1 then C1:=0;
C2 := C1+1;
A2 := 2.4*A1;
B1 := .1;
A2 := B2-B1;
Võtmesõna: if
Identifikaator: A1, tabeli indeks: 0
Operaator: >
Identifikaator: B1, tabeli indeks: 1
Võtmesõna: then
Identifikaator: C1, tabeli indeks: 2
Omistamine: :=
Täisarv: 0 (0)
Eraldaja: ;
Identifikaator: C2, tabeli indeks: 3
Omistamine: :=
Identifikaator: C1, tabeli indeks: 2
Operaator: +
Täisarv: 1 (1)
Eraldaja: ;
Identifikaator: A2, tabeli indeks: 4
Omistamine: :=
Reaalarv: 2.4 (2.4)
Operaator: *
Identifikaator: A1, tabeli indeks: 0
Eraldaja: ;
Identifikaator: B1, tabeli indeks: 1
Omistamine: :=
Reaalarv: .1 (0.1)
Eraldaja: ;
Identifikaator: A2, tabeli indeks: 4
Omistamine: :=
Identifikaator: B2, tabeli indeks: 5
Operaator: -
Identifikaator: B1, tabeli indeks: 1
Eraldaja: ;
Identifikaatorieid: 6
0: A1
1: B1
2: C1
3: C2
4: A2
5: B2
program-definition:Tee skanner, mis teisendaks näidisprogrammi
"program" program-ident "{"
version-list
"}" "=" value
version-list:
version ";"
version ";" version-list
version:
"version" version-ident "{"
procedure-list
"}" "=" value
procedure-list:
procedure ";"
procedure ";" procedure-list
procedure:
type-ident procedure-ident "(" type-ident ")" "=" value
typedef-definition:
"typedef" declaration
const-definition:
"const" ident "=" integer
int-definition:
["unsigned"] "int" ident "=" integer
program TIMEPROG {väljundiks (define-lauseteks header-failis):
version TIMEVERS {
unsigned int TIMEGET (void) = 1;
void TIMESET (unsigned) = 2;
} = 1;
} = 44;
#define TIMEPROG 44
#define TIMEVERS 1
#define TIMEGET 1
#define TIMESET 2