Прямой лексический анализатор DPL

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

Прямой лексический анализатор DPL - student2.ru

Рисунок 7.4 Диаграммы Вирта, используемые для построения

Прямого лексического анализатора

Прямой лексический анализатор DPL - student2.ru

Прямой лексический анализатор DPL - student2.ru

Рисунок 7.4 Диаграммы Вирта, используемые для построения

Прямого лексического анализатора (продолжение)

Прямой лексический анализатор DPL - student2.ru

Рисунок 7.4 Диаграммы Вирта, используемые для построения

Прямого лексического анализатора (окончание)

Программная реализация выглядит следующим образом:

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

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

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

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

void nxl(void) {

do {

i_lv = -1;

lv[0] = '\0';

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

else if(isSkip(si)) {nxsi(); lc = lexSkip;}

else if(isLetter(si) || si == '_'){

lv[++i_lv]=si; nxsi(); id_etc();

}

else if(isDigit(si)) {number();}

else if(isIgnore(si)) {nxsi(); lc = lexIgnore;}

else if(si == '/') {nxsi(); divcom();}

else if(si == '\"') {nxsi(); string_const();}

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

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

else if(si == ':') {

nxsi();

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

else lc = lexColon;

}

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

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

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

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

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

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

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

else if(si == '-') {

nxsi();

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

else lc = lexMinus;

}

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

else if(si == '!') {

nxsi();

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

else {lc = lexError; er(1);}

}

else if(si == '>') {

nxsi();

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

lc = lexGT;

}

else if(si == '<') {

nxsi();

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

lc = lexLT;

}

else if(si == '{') {nxsi(); prenumber();}

else if(si == '.') {lv[++i_lv]=si; nxsi(); fltnumber2();}

else {lc = lexError; er(0); nxsi();}

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

}

При взятии для анализа и транслитерации следующего символа, не надо учитывать позицию в файле.

Диаграммы Вирта, описывающие отдельные подавтоматы прямого лексического анализатора, представлены на Рисунке 7.5. Их программную реализацию проще всего изучить на прилагаемых исходных текстах.

Прямой лексический анализатор DPL - student2.ru

Рисунок 7.5 Диаграммы Вирта, описывающие отдельные крупные фрагменты правил прямого лексического анализатора

Примечание 1. Под остальными понимаются символы, не рассматриваемые непосредственно в текущей точке. В точке 1 – это не «*» и не конец файла; в точке 2 – это не «*», не конец файла и не «/».

Прямой лексический анализатор DPL - student2.ru

Рисунок 7.5 Диаграммы Вирта, описывающие отдельные крупные фрагменты правил прямого лексического анализатора (продолжение)

Прямой лексический анализатор DPL - student2.ru

Прямой лексический анализатор DPL - student2.ru

Рисунок 7.5 Диаграммы Вирта, описывающие отдельные крупные фрагменты правил прямого лексического анализатора (окончание)

Наши рекомендации