Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Программная реализация отдельных автоматов




 

Каждый автомат представлен соответствующей процедурой (функцией), осуществляющей имитацию переходов от начального состояния к одному из заключительных. Разметка диаграмм Вирта, соответствующая состояниям конечного автомата, была описана ранее. Принципы программной реализации в общем случае тоже достаточно просты:

– каждому состоянию ставится в соответствие метка;

– анализируемые альтернативы проверяются условными операторами (они подходят лучше переключателей из-за того, что проверяться могут значения символов и их классы);

– если результат проверки является истиной, проводится обработка контекста, берется следующий символ и осуществляется переход на новую метку (в новое состояние);

– процесс повторяется до тех пор, пока не произойдет переход в одно заключительных состояний.

Данная реализация активно использует оператор безусловного перехода goto вследствие того, что диаграмма Вирта в общем случае является неструктурированным графом. А такие графы невозможно представить без goto, если только не осуществить соответствующие преобразования. Применение же этих преобразований может снизить наглядность исходных диаграмм и привести к их избыточности.

 

Общая структура непрямого лексического анализатора

 

В завершение всего можно привести объединенную диаграмму Вирта, определяющую взаимосвязи между отдельными, ранее представленными автоматами (см. Рисунок 5.3). На ней отражается альтернативный порядок следования разбираемых лексем с учетом приоритетов, определяемых схемой арбитража.

 

Рисунок 7.3 Объединение диаграмм Вирта для непрямого лексического анализа в соответствии с приоритетом

 

Рисунок 7.3 Объединение диаграмм Вирта для непрямого лексического анализа в соответствии с приоритетом (продолжение)


 

Рисунок 7.3 Объединение диаграмм Вирта для непрямого лексического анализа в соответствии с приоритетом (продолжение)


Рисунок 7.3 Объединение диаграмм Вирта для непрямого лексического анализа в соответствии с приоритетом (окончание)

 

В основной программе данной диаграмме соответствует функция nxl(), порождающая лексемы.

 

//----------------------------------------------------------------

// Функция, формирующая следующую лексему

// Вызывается синтаксическим анализатором

//----------------------------------------------------------------

void nxl(void) {

do {

i_lv = -1;

lv[0] = '\0';

// Фиксируем начальную позицию

oldpoz=ftell(infil)-1;

oldline=line; oldcolumn=column;

// Процесс пошел

if(si == EOF) {lc = lexEof; return;}

// Игнорируемую лексему не возвращаем

if(isSkip(si)) {nxsi(); lc = lexSkip; continue; /*return;*/}

if(id_etc()) {return;} unset();

if(string_const()) {return;} unset();

if(float1()) {return;} unset();

if(float2()) {return;} unset();

if(float3()) {return;} unset();

if(float4()) {return;} unset();

if(float5()) {return;} unset();

if(binary()) {return;} unset();

if(octal()) {return;} unset();

if(hex()) {return;} unset();

if(pdecimal()) {return;} unset();

if(decimal()) {return;} unset();

// Игнорируемую лексему не возвращаем

if(comment()) {continue; /*return;*/} unset();

// Игнорируемую лексему не возвращаем

if(isIgnore(si)) {nxsi();lc = lexIgnore;continue;/*return;*/}

if(si=='/') {nxsi(); lc = lexSlash;return;}

if(si == ';') {nxsi(); lc = lexSemicolon; return;}

if(si == ',') {nxsi(); lc = lexComma; return;}

if(si == ':') {

nxsi();

if(si == '=') {nxsi(); lc = lexAssign; return;}

} unset();

if(si==':') {nxsi(); lc = lexColon; return;}

if(si == '(') {nxsi(); lc = lexLftRndBr; return;}

if(si == ')') {nxsi(); lc = lexRghRndBr; return;}

if(si == '[') {nxsi(); lc = lexLftSqBr; return;}

if(si == ']') {nxsi(); lc = lexRghSqBr; return;}

if(si == '*') {nxsi(); lc = lexStar; return;}

if(si == '%') {nxsi(); lc = lexPercent; return;}

if(si == '+') {nxsi(); lc = lexPlus; return;}

if(si == '-') {

nxsi();

if(si == '>') {nxsi(); lc = lexArrow; return;}

} unset();

if(si=='-') {nxsi(); lc=lexMinus; return;}

if(si == '=') {nxsi(); lc = lexEQ; return;}

if(si == '!') {

nxsi();

if(si == '=') {nxsi(); lc = lexNE; return;}

} unset();

if(si == '>') {

nxsi();

if(si == '=') {nxsi(); lc = lexGE; return;}

} unset();

if(si=='>') {nxsi(); lc=lexGT; return;}

if(si == '<') {

nxsi();

if(si == '=') {nxsi(); lc = lexLE; return;}

} unset();

if(si=='<') {nxsi(); lc=lexLT; return;}

lc = lexError; er(0); nxsi();

} while (lc == lexComment || lc == lexSkip || lc == lexIgnore);

}

 

Остановимся на ряде моментов. В сканер введен цикл, который отфильтровывает лексемы, не обрабатываемые распознавателем. Это комментарии, пропуски, игнорируемые символы.

Для выполнения отката, в начале обработки лексемы запоминаются текущие позиции в файле, строке и столбце. При неудаче они восстанавливаются и происходит анализ следующей диаграммы. Функция отката unset() реализована следующим образом:

 

// откат назад при неудачной попытке распознать лексему

static void unset() {

fseek(infil, oldpoz, 0);

nxsi();

i_lv=-1;

lv[0]='\0';

poz = oldpoz;

line=oldline;

column=oldcolumn;

}

 

С реализацией отдельных диаграмм, процедурой обработки ошибок и тестовыми процедурами можно ознакомиться по представленным к конспекту лекций примерам.

 





Поделиться с друзьями:


Дата добавления: 2016-11-18; Мы поможем в написании ваших работ!; просмотров: 609 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Человек, которым вам суждено стать – это только тот человек, которым вы сами решите стать. © Ральф Уолдо Эмерсон
==> читать все изречения...

2258 - | 2106 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.007 с.