Пример проектирования лексического анализатора
Пусть {Li | Li 
 A* , i 
 [1,3]}– семейство из трех регулярных языков над входным алфавитом A, гдеLi – класс лексем языка Си или его ограничение (подмножество)для всехi 
 [1, 3].
Язык L1 – множество идентификаторов языка Си; L2 - множество целочисленных констант языка Си в системе счисления с основанием 8; L3 – множество «пробельных» лексем, интерпретируемых как непустые слова над алфавитом {s, t}. Символы s и t условно обозначают «пробел» и «знак табуляции» соответственно.
Входной алфавит Aпредставляют 256 символов в 8 – разрядной (байтовой) ASCII-кодировке. Числовой код символа «пробел» - 0x20 и «знака табуляции» - 0x09.
1) ЯзыкиLi индуцируют разбиения Piалфавита A,i 
 [1,3]:
P1={[_a-zA-Z], [0-9], [^_a-zA-Z]}; 
 P2={[0], [1-7], [lL], [uU], [^01-7 lL uU]},
 P3={[\x20\x09], [^\x20\x09]}.
 Абстрактные алфавиты, соответствующие разбиениям, следующие:
 B1 = {a, 9, ? },B2 = {0, 7, l, u, ? }, B3 = {s, ? },
Регулярные выражения еi представляют языки Liв соответствующих абстрактных алфавитах Bi , i 
 [1,3] :
 e1=а(а | 9)*,e2 =0(0 | 7)* (|u|l|ul|lu), e3=ss *.
2) Эквивалентные -диаграммы Di для еi ,i
[1,3]:
 e1 = а (а | 9)*;
а:

(а | 9):

 (а | 9)*:
e1 = а (а | 9)*:
-диаграммa D1
 
 
|   |  
  
  |  
 
  |  
 |   |  
 e2 = 0(0 | 7)* (|u|l|ul|lu):
-диаграммa D2

e3 = s s*:
-диаграммa D3

3) Детерминированные конечные автоматы Mi, допускающие языки
 L(Di), i 
 [1,3]. Символом ‘*’ помечены финальные состояния, символом Æ - состояние “ошибки”.
 M1
| Замыкание | q\a | a | ? | |
| [0]= {0} | Æ | Æ | ||
| [1]={1, 2, 3} * | Æ | |||
| [Æ]=Æ | Æ | Æ | Æ | |
| [{2,3}]={2,3} * | Æ | 
M2
| Замыкание | q\a | l | u | ? | ||
| [0]= {0} | Æ | Æ | Æ | Æ | ||
| [1]={1,2,3,6} * | Æ | |||||
| [Æ] =Æ | Æ | Æ | Æ | Æ | Æ | |
| [2]={2,3, 6} * | Æ | |||||
| [{4,6}]={4,6} * | Æ | Æ | Æ | Æ | ||
| [{5,6}]={5,6} * | Æ | Æ | Æ | Æ | ||
| [6]= {6} * | Æ | Æ | Æ | Æ | Æ | 
M3
| Замыкание | q\a | s | ? | 
| [0]= 0 | |||
| [1]={1, 2, 3} * | Æ | ||
| [Æ] =Æ | Æ | Æ | |
| [{2,3}]={2,3} * | Æ | 
Языки Li – не пусты, поскольку не пусты множества заключительных состоянийавтоматовMi для всехi 
 [1,3] , и -свободны,так как начальные состояния не являются заключительными;
4) Общий алфавит B = {0, 7, 9, a, l, u, s, ?}. Соответствующее разбиениеалфавита A - 
 P = {[0], [1-7], [89], [_a-km-tv-zA-KM-TV-Z], [lL], [uU], [\x20\x09], 
 [^0-9_a-zA-Z\x20\x09]}.
Элементы алфавитов связаны следующими соотношениями:
элементы B1 = {a, 9, ?} –
 a = а | l | u,
9 = 0 | 7 | 9,
? = s | ?;
элементы B2 = {0, 7, l, u, ?} –
 0 = 0,
7 = 7,
l = l,
u = u,
? = 9 | a | s | ?;
элементы B3 = {s, ?} –
s = s,
 t = t,
 ? = 0 | 7 | 9 | а | l | u | ?.
Применяя соотношения как правила подстановки к исходным выражениям, получаем регулярные выражения над общим алфавитом B:
e1 = (а | l | u)(а | l | u | 0 | 7 | 9)* ,
e2 = 0(0 | 7)* (|u|l|ul|lu),
e3 = ss*. 
 Чтобы получить регулярные выражения, определяющие языки в исходном алфавите A, необходимо заменить вхождения символов алфавита B в регулярные выражения на выражения, представляющие соответствующие классы разбиения P. Например, в языке C# выражения имеют следующие представления в формате строковых констант (литералов):
 e1 - @”([_a-km-tv-zA-KM-TV-Z] | [lL] | [uU])”+
 @”( [_a-km-tv-zA-KM-TV-Z] | [lL] | [uU] | [0] | [1-7] | [89])*” ;
 e2 - @”[0]([0] | [1-7])* ( [uU] | [lL] | [uU] [lL] | [lL] [uU])?”;
e3 - @” [\x20\x09] [\x20\x09]*”.
Диаграммы Di в алфавитах Biтакже просто преобразуются в соответствующие диаграммы над общим алфавитомB:достаточно каждую
a-дугу заменить параллельнымиb-дугами.Например, в диаграммеD1 каждая дуга (i, a, j) заменяется на (i, а | l | u, j), дуга (i, 9, j) – на (i, 0 | 7 | 9, j) и (i, ?, j) – на (i, s | t |?, j).
Приведенные к общему алфавиту B -диаграммы Di, i 
 [1,3]:
e1 = (а | l | u)(а| l | u | 0 | 7 | 9)* ;

e2 = 0(0 | 7)* (|u|l|ul|lu):
-диаграммa D2

e3 = ss* :
-диаграммa D3

Детерминированные конечные автоматы Mi , приведенные к общему алфавиту B, i 
 [1,3] .
 M1
| Замыкание | q\a | a | l | u | s | ? | |||
| [0]= {0} | Æ | Æ | Æ | Æ | Æ | ||||
| [1]={1, 2, 3 } * | Æ | Æ | |||||||
| [Æ] =Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | |
| [{2,3}]={2,3} * | Æ | Æ | 
M2
| Замыкание | q\a | a | l | u | s | ? | |||
| [0]= {0} | Æ | Æ | Æ | Æ | Æ | Æ | Æ | ||
| [1]={1,2,3,6} * | Æ | Æ | Æ | Æ | |||||
| [Æ] =Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | |
| [2]={2,3,6} * | Æ | Æ | Æ | Æ | |||||
| [{4,6}]= {4,6} * | Æ | Æ | Æ | Æ | Æ | Æ | Æ | ||
| [{5,6}]= {5,6} * | Æ | Æ | Æ | Æ | Æ | Æ | Æ | ||
| [6]= {6} * | Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | 
M3
| Замыкание | q\a | a | l | u | s | ? | |||
| [0]= 0 | Æ | Æ | Æ | Æ | Æ | Æ | Æ | ||
| [1]={1, 2, 3} * | Æ | Æ | Æ | Æ | Æ | Æ | Æ | ||
| [Æ] =Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | |
| [{2,3}]={2,3} * | Æ | Æ | Æ | Æ | Æ | Æ | Æ | 
Языки Li над общим алфавитом B так же не пусты, поскольку не пусты множества заключительных состоянийавтоматовMi для всехi 
 [1,3] , и -свободны,так как начальные состояния не являются заключительными.
Декартово произведениедвух детерминированных конечных автоматов -aвтомат M1,2= M1x M2, допускающий объединение исходных языков: L1  
 L2.
M1,2
| Вектор | q\a | a | l | u | s | ? | |||
| (0,0) | Æ | Æ | Æ | Æ | |||||
| (2,1) 2 | Æ | Æ | Æ | Æ | |||||
| (2,2)= Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | |
| (1,2) 1 | Æ | Æ | |||||||
| (2,3) 2 | Æ | Æ | Æ | Æ | |||||
| (2,4) 2 | Æ | Æ | Æ | Æ | Æ | Æ | Æ | ||
| (2,5) 2 | Æ | Æ | Æ | Æ | Æ | Æ | Æ | ||
| (3,2) 1 | Æ | Æ | |||||||
| (2,6) 2 | Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | 
5) Декартово произведениетрех детерминированных конечных автоматов -aвтомат M= M1x M2x M3, допускающий объединение исходных языков: L1  
 L2 
 L3.
M
| Вектор | q\a | a | l | u | s | ? | |||
| (0,0,0) | Æ | Æ | Æ | ||||||
| (2,1,2) 2 | Æ | Æ | Æ | Æ | |||||
| (2,2,2)= Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | |
| (1,2,2) 1 | Æ | Æ | |||||||
| (2,2,1) 3 | |||||||||
| (2,3,2) 2 | |||||||||
| (2,4,2) 2 | |||||||||
| (2,5,2) 2 | |||||||||
| (3,2,2) 1 | |||||||||
| (2,2,3) 3 | |||||||||
| (2,6,2) 2 | 
ПустьM =(Q, B , g, q0, F), где F= F1 
 F2 
 F3 , F1 = {3, 8},
 F2= {1, 5, 6, 7, 10}, F3 = {4, 8}. Соответствующие автоматы 
 (Q, B , g, q0, Fi) допускают языки Li , i 
 [1,3] .
Cемейство подмножеств {F1, F2, F3} состоит из попарно не пересекающихся множеств, следовательно семейство языков {L1, L2, L3} состоит из трех попарно не пересекающихся регулярных языков;
Автомат M¢ , построенный методом «слияния диаграмм переходов» автоматов M1,2 и M3. Автоматы M и M¢ изоморфны, поскольку их диаграммы переходов изоморфны.
 M¢
| F | q\a | a | l | u | s | ? | |||
| Æ | Æ | 9 | Æ | ||||||
| Æ | Æ | Æ | Æ | ||||||
| Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | |
| Æ | Æ | ||||||||
| Æ | Æ | Æ | Æ | ||||||
| Æ | Æ | Æ | Æ | Æ | Æ | Æ | |||
| Æ | Æ | Æ | Æ | Æ | Æ | Æ | |||
| Æ | Æ | ||||||||
| Æ | Æ | Æ | Æ | Æ | Æ | Æ | Æ | ||
| Æ | Æ | Æ | Æ | Æ | Æ | Æ | |||
| Æ | Æ | Æ | Æ | Æ | Æ | Æ | 
7) Классификация состояний и переходов. 
 По построению все состояния достижимы из начального состояния q0.
Множество «тупиковых» или состояний, сигнализирующих о лексической ошибке, - Error ={q| g*(q, x) ÏF}.
В автомате M= M1x M2x M3 множество Error = {2}, так как из q2 не достижимо ни одно финальное состояние q Î F.
Множество активных состояний -Active = Q\ Error. 
 Множество активных переходов -
 ActiveTransition = {(q, a)| q ÎActive и g(q, a) ÎActive,a Î B }.
 Множество переходов, определяющих условие распознавания лексемы класса Li , - EndLi = {(q, a)| q Î Fi и g(q, a) ÎError,a Î B }.
Символ a такой, что (q, a) Î EndLi определяет правый контекст лексемы x Î Li.Слово x переводит автомат из начального состояния в финальное состояниеqÎFi, причем q=g*(q0, x).
Переходы множества ErrorL = {(q, a)| q ÎActive \ F и g(q, a) ÎError,a Î B } определяют условия обнаружения лексической ошибки. 
 Если (q, a) ÎErrorL, тогда слово x такое, что q=g*(q0, x) переводит автомат из начального состояния вактивное не финальное состояние q, определяет допустимый собственный префикс некоторой лексемы, но
слово xa – не допустимый префикс, так как не существует слова y Î B*, что xaу Î L.
Очевидно, ActiveTransition,EndL1 ,EndL2, EndL3 ,ErrorL,-попарно не пересекающиеся множества переходов.
Семантические процедуры
Определить (классифицировать) множество P «действий» (семантических процедур)значитопределить функцию выхода
 f : Q´B¢  P,гдеB¢= B È {#}.Если f(q,a)=p Î P,тогдаp – действие, выполняемое лексическим анализатором в состоянии q Î Qпривходном символеa Î B¢.Формально символ#Ï Bслужитпризнаком конца входного потока.
 Фактически результатом проектирования является разработка модели детерминированного конечного преобразователяM =(Q, B¢, P, f, g)простого типа.
Пусть P = { pActiveTransition, pEndL1, … , pEndLn, pErrorL}. Определим очевидным образом функцию выхода:
f(q,a)=pActiveTransition, если(q,a)ÎActiveTransition;
если(q,a)ÎEndLi , то (q,#)ÎEndLi , и 
 f(q,a)=pEndLi, если(q,a)ÎEndLi , i Î [1, n];
если(q,a)ÎErrorL, то(q,#)ÎErrorL, и
f(q,a)=pErrorL, если(q,a)ÎErrorL.
Тогда программная реализация (интерпретация) преобразователя
 M =(Q, B¢, P, f, g) определяет основные действия (функции) лексического анализатора при сканировании входного потока символов алфавита B¢.
Ниже на псевдоязыке приводится в обобщенной форме одна из возможных программных интерпретаций.
Интерпретация символов выходного алфавита P.
pActiveTransition:
s = s + a; //добавить входной символ, расширить префикс некоторой //лексемы
// q1 = <q>
q = g[q,b]; // b = [a] – класс входного символа а ¹ #
// q2 = <q> и (q1, b, q2) in ActiveTransition`
return;
pEndLi , i Î [1, n]:
//(q, b) in EndLi , i Î [1, n]
//<s> = x – лексема, b = [a] и <a> = a – правый контекст
tokenStream.WriteLine(“<L”, i, “>”, s);
if (b == [#])
{
//выход
return;
}
else
{
inputStream.UnGetC(a); // вернуть символ <a> = a во входной поток
 q = 0; // переключить автомат в начальное состояние
s=””; // очистить буфер для накопления символов очередной лексемы
return;
}
pErrorL:
s = s + a;
tokenStream.WriteLine(“<ErrorL>”, s); //s=xa
if (b == [#])
{
//выход
return;
}
else
{
//skip входной символ а, доставивший лексическую ошибку
 q = 0;
s=””;
return;
}