Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМК по СПО.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.79 Mб
Скачать

Рассмотрим примеры:

1.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<!-- saved from url=(0047)http://yacc.chat.ru/lex_demos/lex_demos_07.html -->

<HTML lang=ru>

<HEAD>

<TITLE>Yacc Lex </TITLE>

<META content="Yacc, Lex, Bison, Flex " name=keywords>

</HEAD>

<BODY bgColor=#eeff99>

<TABLE align=center border=0 cellPadding=0 cellSpacing=0 class=invsbl width=750>

<TBODY>

<TR>

<TD><IMG alt="" src="Yacc Lex/1.gif"></TD>

<TD ><IMG alt=Lex src="Yacc Lex/lex.gif"></TD>

</TR>

<TR>

<TD><IMG src="Yacc Lex /10x1.gif" width=10></TD>

</TR>

</TBODY></TABLE></BODY></HTML>

2.

<html>

<frameset cols="128,13,*,13" border=0>

<frame name="menu" src="menu.html" frameborder=0 scrolling=no>

<frame name="left" src="v.html" frameborder=0 scrolling=no>

<frameset rows="13,*,13" border=0>

<frame name="top" src="h.html" noresize frameborder=0 scrolling=no>

<frame name="body" src="index.html" frameborder=0 scrolling=yes>

</frameset>

<frame name="right" src="v.html" frameborder=0 scrolling=no>

</frameset>

</html>

Реализация компилятора для настоящего языка программирования всегда является весьма трудоемкой задачей, и поэтому давно предпринимались попытки автоматизировать этот процесс. Чаще всего объектом приложения таких усилий служили лучше всего изученные (и наиболее простые) части компилятора - сканер и парсер. Рассмотрим два инструментальных средства: Lex - предназначен для реализации сканера, Yacc - для построения парсера.

Вся необходимая дополнительная информация приводится в пунктах 11.1, 11.2, 11.3 настоящего УМК.

Рассмотрим пример выполнения лабораторной:

%{

#include <stdlib.h>

#include "Exampl.cpp.h"

#undef YY_INPUT

#define YY_INPUT(buf,result,max_size) \

{ \

int c = getc(Examplin); \

result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \

}

%}

MAIN main

%START AA MM

%%

^# {BEGIN AA;}

^[ \t]*{MAIN} {BEGIN MM;}

^[ \t]*"{" {printf("begin.");}

^[ \t]*"}" {printf("end.\n\n");}

<AA>define {printf("define.");}

<AA>include {printf("include.");}

<AA>ifdef {printf("ifdef.");}

<MM>"(" {printf("main.");}

[\n]+ {printf("\n"); BEGIN 0;}

. ;

%%

Программа содержит активные и неактивные правила. Все неактивные правила помечены, перед ними указана метка начального условия. Lex-программа управляет двумя начальными условиями, в соответствии с которыми активируются помеченные правила.

В результате работы lex мы получим лексический анализатор, который будет распознавать в Си-программе строки препроцессора Cи-компилятора, выделять функцию main, распознавать начало и конец main или других блоков {}. Лексический анализатор не выводит ничего, кроме сообщений о выделенных лексемах, при этом YACC не выполняет никакой работы.

При этом main.cpp вызывает парсер, который ничего не делает кроме вызова лексического анализатора:

#include "ExamplParser.h"

int

main(int argc, char** argv)

{

ExamplParser parser("main_example.txt");

parser.Parse();

return 0;

}

А в файле Exampl.y дожны быть помещена строчки:

rule1: {}

;

Обратите внимание, что при создании парсера ему в параметрах передается входной файл, он и определяет входной поток в lex-файле (Examplin).

В процессе распознавания символов входного потока может оказаться так, что одна цепочка символов будет удовлетворять нескольким правилам и, следовательно, возникает проблема: действие какого правила должно выполняться?

Для разрешения этого противоречия можно использовать квантование (разбиение) регулярных выражений этих правил Lex-программы на такие новые регулярные выражения, которые дадут, по возможности, однозначное распознавание лексемы. Однако, когда это не сделано, lex использует определенный детерминированный механизм разрешения такого противоречия:

  • выбирается действие того правила, которое распознает наиболее длинную последовательность символов из входного потока;

  • если несколько правил распознают последовательности символов одной длины, то выполняется действие того правила, которое записано первым в списке раздела правил Lex-программы.

Дополнительная информация по использованию лексического анализатора находится в лекциях по данному курсу и документации по Lex и Yacc.

Задания:

Требуется создать лексический анализатор для выполнения задания, который прочитает данные из входного файла, а результат работы выведет на экран.

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