Пользователь
Регистрация: 08.06.2010
Сообщений: 60
|
Лексический анализатор азбуки Морзе в виде конечного автомата
Взял код из учебника, но он почему-то не работает. Помогите, ничего понять не могу в коде
Вот цитата из учебника:
Цитата:
3.3 Реализация лексического анализатора в виде конечного автомата
Рассмотрим реализацию в виде конечного автомата лексического ана-лизатора построенного ранее.
Определим тип “входной сигнал”. Этот тип должен включать нижепри-веденные элементы.
“Точка” (dot), “тире” (dash) и “пробел” (space) для отражения входных сигналов конечного автомата.
“Другой символ” (other). Этот элемент необходим для отражения всех символов, не входящих в алфавит азбуки Морзе, но появляющихся на входе конечного автомата.
“Конец последовательности” (endf). Этот элемент необходим, так как ав-томат должен знать, когда заканчивается последовательность, которую нужно распознать как букву или как ошибочную последовательность.
type
input_signal = (dot, dash, space, other, endf)
Определяем возможные состояния конечного автомата. Согласно графу это будут состояния S0, S1, S2, а также специальное состояние S_error, ко-торое будет соответствовать ошибке, возникшей при разборе.
type
state = (S0, S1, S2, S_error)
Исходя из рисунка 13, определим функцию переходов конечного автомата. В ошибочное состояние автомат переводит любой, неожидаемый сигнал. Сигнал “Другой символ” переводит автомат в ошибочное состояние из любого состояния автомата.
const
next_state: array [dot..other, S0..S1] of state =
((S1, S_error),
(S1, S_error),
(S2, S0),
(S_error, S_error));
В рассматриваемом примере только один класс лексем, но обычно ав-томат распознает лексемы нескольких классов, поэтому введем тип “класс лексемы”. В данной реализации этот тип будет включать только одно зна-чение - “буква”.
type lexeme_class=(letter)
Реализуем работу конечного автомата, считая что глобальная переменная Entry : string содержит входную последовательность. Переменные cur_state и cur_input необходимы для хранения текущего состояния автомата и входного символа. Глобальная переменная lex_val будет содержать значение распознаваемой лексемы. В начале работы автомата эта переменная инициализируется пустой строкой, а формирование значение лексемы будет производиться при распознавании символа входной последовательности. Приведенная ниже функция возвращает класс распознанной лексемы. Работа функции заключается в переходе по состояниям конечного автомата до тех пор, пока не будет достигнуто конечное состояние или входная последовательность не разобрана полностью. Если автомат перешел в ошибочное состояние, то в системе возникает исключительная ситуация и пользователь получает сообщение об ошибке. Такое же сообщение пользователь получит, если просмотрена вся входная последовательность, а автомат не находится в конечном состоянии.
function state_machine : lexeme_class;
var cur_state:state; cur_input:input_signal;
begin
lex_val:=''; cur_state:=s0; cur_input:=recognize;
while (cur_state<>S2) and (cur_input<>endf) do
begin
cur_state:=next_state[cur_input, cur_state];
if cur_state=S_error
then raise exception.create(‘Лексическая ошибка');
if cur_state<> s2 then cur_input:=recognize;
end;
if (cur_state <> S2) and (cur_input=endf)
then raise exception.create('Лексическая ошибка')
else result:=letter;
end;
При реализации конечного автомата была использована функция recog-nize, которая возвращает следующий символ входной последовательности. Эта функция необходима, так как последовательность имеет строковый тип, а для входных символов автомата задан свой тип input_signal. Кроме того, функция формирует значение лексемы.
function recognize:input_signal;
begin
if entry=''
then result:=endf
else
begin
case entry[1] of
'.': result:=dot;
'-': result:=dash;
' ': result:=space;
else result:=other
end;
lex_val:=lex_val+entry[1];
entry:=copy(entry, 2,length(entry));
end;
end;
Теперь рассмотрим текст основной программы. Она будет состоять в вызове подпрограммы лексического анализатора до тех пор, пока не будет разобрана вся входная последовательность. В зависимости от класса рас-познанной лексемы основная программа выдает пользователю сообщение, включающее класс и значение лексемы. Будем считать, что входная после-довательность вводится пользователем через объект класса TEdit.
begin
entry:=edit1.text;
while (entry<>'') do
begin
case state_machine of
letter:showmessage('Буква'+lex_val) ;
end;
end;
end;
|
Последний раз редактировалось MrBrain; 07.11.2010 в 20:41.
|