- •Пример проектирования лексического анализатора
- •Детерминированные конечные автоматы Mi, допускающие языки l(Di), I [1,3]. Символом ‘*’ помечены финальные состояния, символом состояние “ошибки”. M1
- •Интерпретация управления сканированием входного потока
- •Простой метод вычисления декартова произведения
Интерпретация управления сканированием входного потока
Lexer:
//Init
inputStream.Open();
tokenStream. Open ();
q = 0;
s = ””;
while(true)
{
if( inputStream.Eof()) {
//текущее состояние q in Active
a =’#’;
b = [a];
f[q,b]();
//выход
tokenStream.Close();
inputStream.Close();
exit;
}
else
{
//текущее состояние q in Active и //не конец входного потока inputStream
a=inputStream.ReadChar();
b=[a];
f[q,b]();
//по (q, b) выполнить процедуру f(q,b) in P, т.е. проинтерпретировать //символ f(q,b) с помощью базисной функции f[q,b](), другими словами, //выполнить инструкцию (команду) f(q,b)
}
}
Простой метод вычисления декартова произведения
Пусть Li = L(Mi) – не пустые и -свободные регулярные языки над общим алфавитом B, допускаемые ДКА Mi = (Qi, B , gi, qi0, Fi) для всех i [1, n], n > 1. На множестве всех слов B* для целого числа k 0 однозначно определена функция firstk(w). По определению эта функция каждому слову w ставит в соответствие префикс v: v = w, если |w| < k и, если |w| > k, тогда v = x, где слово x такое, что w = xy и |x| = k, y B*.
Для любого языка L B* определено конечное множество FIRSTk(L) = {firstk(w)| w L}.
Не пустые языки L, L B* называются разделенными, если существует k > 0, что справедливо FIRSTk(L) FIRSTk(L) = .
Если не пустой и -свободный язык L допускается ДКА, то очевидно FIRST1(L) = {b| g(q0, b) Active}.
Пусть любая пара языков Li и Lj , 1 i j n, разделена при k = 1. Тогда автомат M = (Q, B , g, q0, F), изоморфный декартову произведению автоматов M1 M2 … Mn , определяется следующим образом:
Q = {q0} Active1 … Activen {qerror}; F = F1 … Fn; g(q0, b) = q, если gi(qi0, b) = q Activei , i [1, n], n > 1;
g(q0, b) = qerror для всех b (FIRST1(L1) … FIRST1(Ln));
для всех qActivei g(q, b) = qerror , если gi(q, b) = q Errori , i [1, n], n > 1;
g(qerror, b) = qerror для всех bB;
g(q, b) = q, если gi(q, b) = q , где q, q Activei , i [1, n], n > 1;
На языке диаграмм (орграфов) диаграмма переходов D автомата M конструируется, как описано ниже.
Пусть Di – диаграмма автомата Mi. Через D1-n = D1 D2 … Dn обозначим объединение диаграмм. Определим отображение : Q1 Q2 … Qn Q :
( qi0) = q0 и ( q) = qerror , где q Errori , для всех i [1, n];
( q) = q, где q Active i , для всех i [1, n];
( (q, b, q)) = (( q), b, ( q)), если (q, b, q) – дуга диаграммы D1-n.
Отображение гомоморфизм диаграмм и образ D = ( D1-n) изоморфен диаграмме автомата M.
Графически выполнить построение диаграммы D = ( D1-n) значит
отождествить (топологически) начала всех дуг (qi0, b, q) с вершиной q0 и концы всех дуг (q, b, q) с вершиной qerror при условии, что q Errori , i [1, n]. Такой метод называется «слиянием диаграмм».
В случае табличного представления автоматов Mi , i [1, n], метод построения таблицы автомата M, изоморфного автомату M1M2…Mn , подобен методу «слияния диаграмм», и хорошо подходит для программной реализации.
Пример 1. FIRST1(L1) = {a, l, u}; FIRST1(L2) = {0}; FIRST1(L3) = {s, t}. Следовательно, автомат M= M1 x M2 x M3 допускает конструирование методом «слияния диаграмм».
