LexBisonLabs
.pdf11
String |
[\"]({Escape}|{AnyStrChr})*[\"] |
Identifier |
([a-zA-Z0-9])* |
SqString |
{Sq}(.)*{Sq} |
Colon |
[:] |
nl |
\n |
%% |
|
{Number} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_NUMBER; |
|
} |
{Semi} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_SEMI; |
|
} |
{Num} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_NUM; |
|
} |
{Slash} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_SLASH; |
|
} |
{Colon} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_COLON; |
|
} |
{AP_TYPE} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_TYPE_KW; |
|
} |
{AP_AGENT} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_AGENT_KW; |
|
} |
{AP_USERS} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_USERS_KW; |
|
} |
11
{AP_ASPECT}
{AP_DATABASE}
{AP_PAGE}
{AP_DEFAULT}
{AP_LASTNAME}
{AP_FIRSTNAME}
{AP_TYPE}
{AP_GROUP}
{AP_TEAM}
{AP_EXT}
{AP_TOTAL}
12
{
tmpstr = strdup(yytext); return AP_ASPECT_KW;
}
{
tmpstr = strdup(yytext); return AP_DATABASE_KW;
}
{
tmpstr = strdup(yytext); return AP_PAGE_KW;
}
{
tmpstr = strdup(yytext); return AP_DEFAULT_KW;
}
{
tmpstr = strdup(yytext); return AP_LASTNAME_KW;
}
{
tmpstr = strdup(yytext); return AP_FIRSTNAME_KW;
}
{
tmpstr = strdup(yytext); return AP_TYPE_KW;
}
{
tmpstr = strdup(yytext); return AP_GROUP_KW;
}
{
tmpstr = strdup(yytext); return AP_TEAM_KW;
}
{
tmpstr = strdup(yytext); return AP_EXT_KW;
}
{
tmpstr = strdup(yytext); return AP_TOTAL_KW;
}
12
13
{AP_RECORDS} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_RECORDS_KW; |
|
} |
{Identifier} |
{ |
|
tmpstr = strdup(yytext); |
|
return AP_IDENTIFIER; |
|
} |
{nl} |
{ |
|
/* nothing, ate new line */ |
|
} |
. |
{ |
|
/* nothing */ |
|
} |
%% |
|
В файле описания использованы константы AP_XXX, заданные во внешнем включаемом файле "tokens.h". Константы определены через директиву #define и являются числовыми константами – токенами (кодами лексем), используемыми программой. Каждому токену соотвествует ключевое слово или иная лексема, которую выделяет из исходного текста сканер. Сама лексема помещается в переменную tmpstr, где сохраняется до прочтения следующей лексемы.
6. Использование синтезированного программного кода
Если с помощью flex получен процедурный сканер, с ним может работать, например, следующая программа:
#include <stdio.h> #include <string>
extern FILE *yyin, *yyout; // referenced from flex-generated scanner
extern int yylineno; extern std::string tmpstr;
int yylex();
int main(int argc, char* argv[])
{
yyin = fopen("test.txt","r"); //yyout will ptr to stdout int iRes = 0;
while ((iRes = yylex()) > 0)
{ //read something useful from file
13
14
printf ("Read ‘%s’ (token values is %d) at
line %d\n",tmpstr.c_str(), iRes, yylineno);
}
printf ("Scanner return %d code\n",iRes); return 0;
}
Результатом ее работы при условии, что в файле “test.txt” находятся данные, описанные в приведенном выше примере, будет вывод на экран следующей информации:
Read 'Ext' (token values is 279) at line 1
Read '999' (token values is 283) at line 1
Read '7' (token values is 283) at line 1
Read ':' (token values is 262) at line 1
Read '10' (token values is 283) at line 1
Read 'AM' (token values is 284) at line 1
Read ',' (token values is 285) at line 1
Read '12' (token values is 283) at line 1
Read '/' (token values is 286) at line 1
Read '11' (token values is 283) at line 1
Read '/' (token values is 286) at line 1
Read '2003' (token values is 283) at line 1
Read 'Aspect' (token values is 257) at line 1
Read 'Page' (token values is 263) at line 1
Read '1' (token values is 283) at line 1
Read 'Users' (token values is 259) at line 2
Read 'Database' (token values is 260) at line 2
Read 'Default' (token values is 270) at line 4
Read 'Default' (token values is 270) at line 4
Read 'Ext' (token values is 279) at line 5
Read '#' (token values is 287) at line 5
Read 'Last Name' (token values is 272) at line 5
Read 'First Name' (token values is 273) at line 5
Read 'Type' (token values is 274) at line 5
Read 'Group' (token values is 275) at line 5
Read 'Team' (token values is 276) at line 5
Read '201' (token values is 283) at line 7
Read 'TEST' (token values is 284) at line 7
Read 'TEST' (token values is 284) at line 7
Read 'Agent' (token values is 258) at line 7
Read '20' (token values is 283) at line 7
Read '0' (token values is 283) at line 7
Read '202' (token values is 283) at line 8
Read 'TEST' (token values is 284) at line 8
Read 'TEST' (token values is 284) at line 8
Read 'Agent' (token values is 258) at line 8
Read '21' (token values is 283) at line 8
14
15
Read '0' (token values is 283) at line 8
Read '203' (token values is 283) at line 9
Read 'TEST' (token values is 284) at line 9
Read 'TEST' (token values is 284) at line 9
Read 'Agent' (token values is 258) at line 9
Read '23' (token values is 283) at line 9
Read '0' (token values is 283) at line 9
Read 'Total' (token values is 280) at line 11
Read 'Records' (token values is 281) at line 11
Read ':' (token values is 262) at line 11
Read '3' (token values is 283) at line 11
Scanner return 0 code
Для случая C++сканера аналогичная программа выглядит следующим образом:
#include <fstream> #include <iostream> #include <string> #include "FlexLexer.h"
std::string tmpstr; //do not used in this sample,for compile time only
int main(int argc, char* argv[])
{
if (argc < 2) {
std::cout << "USE: ccflexscan <source file>" << std::endl; return 0;
}
std::ifstream infile(argv[1]);
FlexLexer* lexer = new yyFlexLexer(&infile); int iRes = 0;
while ((iRes = lexer->yylex()) > 0)
{
std::cout << "Read " << lexer->YYText()
<<" (token value is "
<<iRes << ") at line "
<< lexer->lineno() << std::endl;
}
return 0;
}
Приведенная программа может быть скомпилированна с использованием Visual C++ 6.0. Компиляция сканера синтезированного в режиме C++ с использованием компилятора Microsoft Примечание: Visual C++ 7.1 (2003) требует некоторой модификации как поставляемого с flex файла FlexLexer.h, в котором содержится объявление класса-
15
16
сканера, так и создаваемого утилитой файла с программным кодом сканера (lex.yy.cc по умолчанию). Данная (и более новые) версия компилятора не поддерживает старого механизма потоков, существовавшего в С++ до его стандартизации (такие файлы как “iostream.h”) и требует использования новых потоковых классов, объявленных в заголовочном файле “iostream”. Новый заголовочный файл необходимо указать в FlexLexer.h. Кроме того, требуется убрать из создаваемого утилитой файла объявление class iostream, заменив его на включение нового заголовочного файла и использование директивы using namespace std;
7. Задание на выполнение лабораторной работы
Используя утилиту flex, разработать сканер для чтения текстовой таблицы с данными, выбранной по номеру варианта задания. Предусмотреть вывод лексем на стандартный выход сканера (экран). Архитектуру сканера (процедурный\объектный) выбрать произвольно. Скомпилировать действующую программу любым доступным компилятором C/C++. В отчете привести текст описания сканера вместе с протоколом тестового выполнения, созданного на основе описания программы, включая исходные данные и полученные результаты.
8. Варианты заданий |
|
|
|
|
1) |
|
|
|
|
Executed on: 10/12/2003 |
User: Alex |
|
|
|
ID |
NAME |
GRADE |
AVERAGE_SCORE |
TEACHER |
==== |
======= |
======== |
================ ========= |
|
1250 |
Alex Petroff |
10 |
B |
WES HAYDEN |
1251 |
Eric Lieb |
10 |
A |
WES HAYDEN |
1251 |
Duane Lindsley |
10 |
A |
WES HAYDEN |
1301 |
Sandra Lim |
11 |
C |
AD NEDERLOF |
2)
….
DN 1002 CPND
NAME BRIAN WALSH XPLN 27
DISPLAY_FMT FIRST,LAST VMB
VMB_COS 4
SECOND_DN THIRD_DN
VMB_STATE CONFIGURED TYPE SL1
TN 004 0 00 02 KEY 00 H MARP DES BRIAN 1 JUN 2001 (2616)
16
17
DN 1003 CPND
NAME Norris Lam XPLN 27
DISPLAY_FMT FIRST,LAST VMB
VMB_COS 4
SECOND_DN THIRD_DN
VMB_STATE CONFIGURED TYPE SL1
TN 024 0 06 14 KEY 00 H MARP DES LAM 29 JUN 2000 (2008)
DN 1004 CPND
NAME IRINA SEMENYURA XPLN 27
DISPLAY_FMT FIRST,LAST VMB
VMB_COS 4
SECOND_DN THIRD_DN
VMB_STATE CONFIGURED TYPE SL1
TN 025 0 06 14 KEY 00 H MARP DES SEMENYURA 30 JUN 2000 (2008)
3)
КВИТАНЦИЯ |
АБОНЕНТ 313-70-43 |
ПОЛУЧАТЕЛЬ: филиал "ПТС" |
|||||
№ 016 от 30.11.05 г. Номер лицевого счета ОАО "Северо-Западный Телеком" |
|
||||||
Ноябрь 2005 г. |
1002900415 |
|
|
|
|||
|
|
|
|
|
|
|
|
Информация о расчетах |
|
Сумма |
|
Начислено к оплате |
|
335-05 |
|
Остаток на счете |
|
200- |
|
Абенентская плата за декабрь |
|
200-00 |
|
Задолженность |
|
0- |
|
Итого к оплате |
|
435-05 |
|
Начислено в ноябре |
|
435- |
|
|
|
|
|
Начислено к оплате |
|
235- |
|
Просим Вас оплптить счет до 20.12.2005 г. |
|
||
17
18
4)
Сводный перечень услуг |
Кол-во |
Стоимость |
Сумма |
|
|
|
|
Абонентская плата |
- |
- |
200 |
Междугородняя связь |
25 |
17 |
425 |
Международная связь |
10 |
56 |
560 |
Итого предоставлено услуг |
|
|
1185 |
5)
АВАНСОВЫЙ ОТЧЕТ |
№ 353-05 |
22.12.05 г. |
||
Учреждение |
ГУАП |
|
|
|
Подразделение |
Кафедра 46 |
|
|
|
|
|
|
||
Подотчетное лицо |
Иванов Александр Владимирович |
|||
Должность |
Ассистент |
|
|
|
Назначение аванса |
|
командировочные расходы |
||
Наименование показателя |
|
Сумма (руб.) |
||
Предыдущий аванс : |
|
|
1000-00 |
|
Перерасход |
|
|
256-00 |
|
|
|
|
|
|
Получен аванс |
|
|
10000-00 |
|
|
|
|
|
|
Итого получено |
|
|
|
|
|
|
|
|
|
Израсходовано |
|
|
8563-50 |
|
|
|
|
|
|
Остаток |
|
|
|
|
|
|
|
|
|
18
19
6)
ПЕТРОЭЛЕКТРОСБЫТ OAO «Петербургская сбытовая компания»
Адрес Б.Морская, 69
Абонентский № |
0123456 |
|
|
|
|
|
|
Вид платежа |
Текущий платеж |
|
|
|
|
||
|
|
Дата от 15.03.2006 до 15.04.2006 |
|
||||
|
|
|
|
|
Скидка по льготе |
|
|
|
|
|
|
|
|
|
|
Показания |
|
Расход |
Тариф |
|
КВт.ч |
|
Сумма |
|
|
|
|
|
|
|
|
От 02000 |
|
543 |
1.44 |
|
100 |
|
144 |
До 02543 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Начислено |
637.92 |
долг 0.00 |
пеня 0.00 |
|
|||
7) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Каф. |
ОКОСО |
ООП |
Кол-во работ |
Кафедра |
Рецензируются |
|
Часы |
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
г/б |
контр. |
|
г/б |
контр. |
г/б |
контр. |
|
|
|
|
|
ФАКУЛЬТЕТ № 4 |
|
|
|
|
||
|
08011665 |
061800 |
7 |
0 |
42 |
7 |
0 |
21 |
0 |
|
46 |
01050365 |
351500 |
10 |
0 |
44 |
10 |
0 |
30 |
0 |
|
23010565 |
320400 |
5 |
17 |
35 |
5 |
17 |
15 |
51 |
||
|
||||||||||
|
23010565 |
320400 |
13 |
33 |
44 |
13 |
33 |
39 |
99 |
|
19
20
8)
|
|
|
|
|
Курсы |
|
|
||
|
|
Код спец. |
|
|
|
|
|
|
|
Факультет |
Каф. |
1 курс |
2 курс |
3 курс |
4 курс |
5 курс |
6 курс |
||
|
|||||||||
|
|
|
|
|
|
|
|||
|
|
|
группы |
группы |
группы |
группы |
группы |
группы |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4561 |
4461 |
4361 |
4261 |
4161 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220400 |
4562к |
4462к |
4362к |
4262к |
4162к |
|
|
|
|
|
|
|
|
|
|
||
4 |
46 |
4563к |
4463к |
4364кф |
4264к |
4164кф |
|
||
|
|
||||||||
|
|
|
|
|
|
|
|||
|
|
|
|
4265кф |
4165кф |
|
|||
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
351500 |
4566 |
4466 |
4366 |
4266 |
4166 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
061800 |
4568 |
4468 |
4368 |
|
4168 |
|
|
|
|
|
|
|
|
|
|
|
|
Лабораторная работа №2
Синтаксический анализ текстов c применением утилиты BISON
1. Синтаксический анализ и магазинные автоматы
Синтаксическим анализом называют разбор цепочек лексем входного текста с целью проверки того факта, что данная цепочка удовлетворяет правилам некоторого формального языка. Формальный язык – это подмножество цепочек в некотором алфавите. Допустимая цепочка называется предложением языка. Для выделения лексем цепочки обычно применяются методы лексического анализа, рассмотренные в предыдущей работе.
Задачу реализации синтаксического анализа приходится решать при разработке трансляторов с языков программирования в машинные коды, а также при необходимости разбора входных данных, записанных по определенным правилам в виде текстовых документов. Программный компонент-синтаксический анализатор часто является «пусковым механизмом», запускающим работу остальных компонентов программы, ответственных за обработку входных данных. Анализатор принимает или отвергает предложения языка и в процессе своей работы передает информацию о принятых предложениях в другие компоненты программной системы, такие, например, как построитель внутреннего представления данных. Таким образом, входом для синтаксического анализатора являются цепочки символов входного языка, а выходными данными являются законченные предложения того же языка, которые, в свою очередь, могут нести некоторый логический смысл, доступный другим компонентам программной системы.
Выделение синтаксического анализа в отдельную задачу позволяет применить формальные методы теории языков и упростить его реализацию путем использования существующего программного кода.
20
