скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыКурсовая работа: Однопроходный/двухпроходный транслятор с языка математических выражений на язык деревьев вывода

goto state0

state1: read c

if c = letter goto state1

if c = digit goto state1

goto state2

state2: accept string

Это техника, используемая lex. Регулярные выражения транслируются с помощью lex в компьютерную программу, которая реализует FSA. Используя следующий входной символ и текущее состояние, следующее состояние определяется с помощью индексирования в сгенерированной компьютером таблице состояний.

Теперь становится легко понять ограничения в lex. Например, lex не может быть использован.


Таблица 1. Элементарные шаблоны (Pattern Matching Primitives)

Метасимвол (Metacharacter)

Совпадения (Matches)

.

Любой символ, кроме перевода строки

\n

Символ перевода строки

*

0 или более копий предшествующих выражений

+

1 или более копий предшествующих выражений

?

0 или 1 копия предшествующих выражений

^

Начало строки

$

Конец строки

a|b

a или b

(ab)+

Одна или более копий ab (группировка, grouping)

«a+b»

литерал «a+b» (C escapes still work)

[]

Класс символов

Таблица 2. Примеры шаблонов выражений (Pattern Matching Examples)

Выражение (Expression)

Совпадения (Matches)

abc

abc

abc*

ab abc abcc abccc…

abc+

abc abcc abccc…

a(bc)+

abc abcbc abcbcbc…

a(bc)?

a abc

[abc]

Одно из: a, b, c

[a-z]

Любой символ, a-z

[a\-z]

Одно из: a, -, z

[-az]

Одно из: -, a, z

[A-Za-z0–9]+

Один или более символов алфавита или цифр

[\t\n]+

Пробельные символы

[^ab]

Все, кроме: a, b

[a^b]

Одно из: a, ^, b

[a|b]

Одно из: a, |, b

a|b

Одно из: a, b

Регулярные выражения в lex составляются из метасимволов (Таблица 1). Примеры совпадения шаблонов показаны в таблице 2. При использовании класса символов, обычные операторы теряют свое назначение.

Следующие два оператора разрешены в классе символов: дефис («–», hyphen) и циркумфлекс («^», circumflex). При использовании между двумя символами дефиса, представляется диапазон символов. Циркумфлекс, при использовании его как первого символа, отрицает выражение. Если два шаблона совпадают с некоторой строкой, используется наиболее шаблон, по которому найдена наиболее длинная строка, в случае, если длина одинакова, используется первый шаблон.

… definitions…

%%

… rules…

%%

… subroutines…

Входные данные lex делятся на 3 секции, с символами%%, разделяющими секции. Это проиллюстрировано в примере. Первый пример – это наименьший возможный файл lex:

%%

Входные данные копируются выходные по одному символу за раз. Первый разделитель%% требуется всегда, так как всегда должна быть секция правил. Если не специфицировать ни одного правила, тогда действие по умолчанию – совпадение всего и копирование в выходные данные. По умолчанию для входных и выходных данных используются stdin и stdout, соответственно. Вот некоторый пример, с использованием кода по умолчанию:

%%

/* Совпадение всего, кроме символа новой строки */

ECHO;

/* Совпадение символа перевода строки */

\n ECHO;

%%

int yywrap(void) {

return 1;

}

int main(void) {

yylex();

return 0;

}

Два шаблона специфицированы в секции правил. Каждый шаблон должен начинаться в первом столбце, то есть должен следовать за пробельным символом. Опциональное действие ассоциируется с шаблоном. Действие может быть единичным выражением на языке C или множественным, заключенным в скобки. Все, не начинающееся с первого столбца, дословно копируется в генерируемый C файл. Можно использовать это для спецификации комментариев в lex файле. В этом примере есть 2 выражения:

«.» и «\n» с действием ECHO, ассоциированным с каждым шаблоном. Несколько макросов и переменных определены в lex. ECHO – это макрос, который пишет код, совпадающий с шаблоном. Это действие по умолчанию для каждой несовпадающей строки. Обычно ECHO определяется как

#define ECHO fwrite (yytext, yyleng, 1, yyout)

Переменная yytext – указатель на совпавшую строку (оканчивающийся NULL-символом), и yyleng – длина совпавшей строки. Выражение yyout является выходным файлом и по умолчанию является stdout. Функция yywrap вызывается lex, когда входные данные закончились. Возвращает 1, если закончено, 0 если требуется дальнейшая обработка. Каждая программа на C требует main функцию. В этом случае просто вызывается yylex,

Основная точка входа для lex. Некоторые реализации lex включают копии main и yywrap в библиотеку, устраняя необходимость явно определять их. Поэтому первый пример, наименьшая программа lex правильно функционирует.

Name

Function

int yylex(void)

Вызывается для запуска лексического анализатора, возвращает токен

char *yytext

Указатель на совпавшую строку

yyleng

Длина совпавшей строки

yylval

Значение, ассоциируемое с токеном

int yywrap(void)

Wrapup – обертка возвращает 1 если завершена, 0 – если не завершено

FILE *yyout

Выходной файл

FILE *yyin

Входной файл

INITIAL

Исходное условие старта

BEGIN

Условие переключающее условие старта

ECHO

Записать совпавшую строку

Следующий пример присоединяет слева номер линии для каждой линии в файле. Некоторые реализации lex предопределяют вычисление yylineno. Входной файл для lex – это yyin, и является по умолчанию stdin.

%{

int yylineno;

%}

%%

^(.*)\n printf («%4d\t % s», ++yylineno, yytext);

%%

int main (int argc, char *argv[]) {

yyin = fopen (argv[1], «r»);

yylex();

fclose(yyin);

}

Секции определений состоят из замен, кода и начальных состояний. Код в секциях определения просто копируется в начало генерируемого C файла, при этом код должен быть в скобках%{» и «%}». Замены облегчаются правилами совпадения шаблонов. Например, можно определить цифры и символы:

digit [0–9]

letter [A-Za-z]

%{

int count;

%}

%%

/* match identifier */

{letter} ({letter}|{digit})* count++;

%%

int main(void) {

yylex();

printf («number of identifiers =%d\n», count);

return 0;

}

Пробел должен разделять терм и ассоциируемое выражение. Ссылки на подстановки в секциях правил окружены скобками ({letter}), чтобы различать их с символами. Когда происходит совпадение в секции правил, ассоциируемый C код выполняется. Вот программа, которая считает количество символов, слов и линий в файле (подобная команде wc в Unix):

%{

int nchar, nword, nline;

%}

%%

\n {nline++; nchar++;}

[^ \t\n]+ {nword++, nchar += yyleng;}

{nchar++;}

%%

int main(void) {

yylex();

printf («%d\t % d\t % d\n», nchar, nword, nline);

return 0;

}

Реализация lex в Unix

В целом подсистема LEX для систем UNIX включает следующие файлы:

/usr/ccs/bin/lex;

lex.yy.c;

/usr/ccs/lib/lex/ncform;

/usr/lib/libl.a;

/usr/lib/libl.so.

В каталоге /usr/ccs/lib/lex имеется файл-заготовка ncform, который LEX используется для построения ЛА. Этот файл является уже готовой программой лексического анализа. Но в нем не определены действия, которые необходимо выполнять при распознавании лексем, отсутствуют и сами лексемы, не сформированы рабочие массивы и т.д. С помощью команды lex файл ncform достраивается. В результате мы получаем файл со стандартным именем lex.yy.c. Если LEX-программа размещена в файле program.l, то для получения ЛА с именем program необходимо выполнить следующий набор команд:

lex program.l

cc lex.yy.c – ll – o program

Если имя входного файла для команды lex не указано, то будет использоваться файл стандартного ввода. Флаг – ll требуется для подключения /usr/ccs/lib/libl.a – библиотеки LEX. Если необходимо получить самостоятельную программу, как в данном случае, подключение библиотеки обязательно, поскольку из нее подключается главная функция main. В противном случае, если имеется необходимость включить ЛА в качестве функции в другую программу (например, в программу синтаксического анализа), эту библиотеку необходимо вызвать уже при сборке. Тогда, если main определен в вызывающей ЛА программе, редактор связей не будет подключать раздел main из библиотеки LEX.

Общий формат вызова команды lex:

lex [-ctvn – V – Q [y|n]] [file]

Флаги:

– c – включает фазу генерации Си-файла (устанавливается по умолчанию);

– t – поместить результат в стандартный файл вывода, а не в файл lex.yy.c;

– v – вывести размеры внутренних таблиц;

– n – не выводить размеры таблиц (устанавливается по умолчанию);

– V – вывести информацию о версии LEX в стандартный файл ошибок;

– Q – вывести (Qy) либо не выводить (Qn, устанавливается по умолчанию) информацию о версии в файл lex.yy.c.

YACC – Yet Another Compiler Compiler

Грамматики для yacc описываются с помощью Формы Бэкуса-Наура (Backus Naur Form, BNF)

Эту технику была ввели John Backus и Peter Naur и использовали ее, чтобы описать ALGOL60. Грамматика BNF может быть использована для описания контекстно-свободных языков. Большинство конструкций современного программирования могут быть представлены в BNF.

Например, грамматика для выражения, которое умножает и складывает числа может быть представлена следующим образом:

E -> E + E

E -> E * E

E -> id

Были специфицированы 3 правила продукции. Термы, которые могут быть с левой стороны правил продукции(lhs) продукции, такие как E (expression), являются нетерминальными символами. Термы, такие как id (identifier) являются терминальными символами (токенами, возвращаемыми lex) и могут быть только с правой стороны правил продукции(rhs).

Страницы: 1, 2, 3, 4


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.