Занятие 3 по курсу МПК — различия между версиями
Материал из Вики ИТ мехмата ЮФУ
Admin (обсуждение | вклад) (→Lex-файл my.lex) |
Admin (обсуждение | вклад) (→Lex-файл файл проекта,) |
||
Строка 33: | Строка 33: | ||
====Lex-файл файл проекта, ==== | ====Lex-файл файл проекта, ==== | ||
− | <source lang="csharp">%namespace | + | <source lang="csharp">%namespace SimpleScanner |
− | Alpha [a-zA- | + | Alpha [a-zA-Z_] |
− | + | Digit [0-9] | |
+ | AlphaDigit {Alpha}|{Digit} | ||
+ | INTNUM {Digit}+ | ||
REALNUM {INTNUM}\.{INTNUM} | REALNUM {INTNUM}\.{INTNUM} | ||
− | ID {Alpha} | + | ID {Alpha}{AlphaDigit}* |
%% | %% | ||
− | |||
{INTNUM} { | {INTNUM} { | ||
Console.WriteLine("IntNum "+yytext); | Console.WriteLine("IntNum "+yytext); | ||
Строка 47: | Строка 48: | ||
{REALNUM} { | {REALNUM} { | ||
− | Console.WriteLine("RealNum | + | Console.WriteLine("RealNum "+yytext); |
} | } | ||
Строка 60: | Строка 61: | ||
{ID} { | {ID} { | ||
Console.WriteLine("ID "+yytext); | Console.WriteLine("ID "+yytext); | ||
+ | } | ||
+ | |||
+ | ":" { | ||
+ | Console.WriteLine("COLON"); | ||
+ | } | ||
+ | |||
+ | ":=" { | ||
+ | Console.WriteLine("ASSIGN"); | ||
+ | } | ||
+ | |||
+ | ";" { | ||
+ | Console.WriteLine("SEMICOLON"); | ||
} | } | ||
Версия 12:00, 15 августа 2014
Разработка лексических анализаторов с помощью программы GPLex
GPLex - программа для автоматической генерации сканеров (лексических анализаторов)
Комплект для практического занятия скачиваем отсюда. Состав:
- LexProjects.sln - файл решения, содержащее проект Lex1.csproj
- Lex1.csproj - файл демонстрационного проекта для GPLex
- gplex.exe - исполняемый файл генератора сканеров
- mymain.cs - основная программа, содержащая создание сканера и сканирование всех лексем в файле
- ShiftReduceParserCode.cs - файл проекта, необходимый для работы лексического анализатора
- SimpleLex.lex - файл, содержащий правила для генерации лексического анализатора
- generateScanner.bat - командный файл. Содержит одну команду: gplex.exe /noparser SimpleLex.lex
- SimpleLex.cs - файл проекта, автоматически создаваемый при запуске generateScanner.bat
- a.txt - файл программы, подаваемой на вход сгенерированному лексеру
Компиляция проекта
- Выполняем команду gplex.exe /noparser my.lex, запустив командный файл generateScanner.bat
- При этом генерируется файл my.cs, содержащий код лексера. Ключ /noparser означает, что генерируется лексер без парсера.
- Открываем и компилируем .sln
Формат .lex-файла
Определения %% Правила %% Пользовательский код
Пользовательский код содержит описания полей и методов, включаемых в генерируемый класс Scanner.
Lex-файл файл проекта,
%namespace SimpleScanner
Alpha [a-zA-Z_]
Digit [0-9]
AlphaDigit {Alpha}|{Digit}
INTNUM {Digit}+
REALNUM {INTNUM}\.{INTNUM}
ID {Alpha}{AlphaDigit}*
%%
{INTNUM} {
Console.WriteLine("IntNum "+yytext);
}
{REALNUM} {
Console.WriteLine("RealNum "+yytext);
}
begin {
Console.WriteLine("Key: begin");
}
end {
Console.WriteLine("Key: end");
}
{ID} {
Console.WriteLine("ID "+yytext);
}
":" {
Console.WriteLine("COLON");
}
":=" {
Console.WriteLine("ASSIGN");
}
";" {
Console.WriteLine("SEMICOLON");
}
%%
// Здесь можно делать описания переменных и методов - они попадают в класс Scanner
public int Sum = 0;
Регулярные выражения, используемые в секции определений
. | один символ кроме '\n' |
* | ноль или более повторений |
+ | одно или более повторений |
? | ноль или одно повторение |
[] | класс символов, обозначающий любой символ внутри [] |
^ | при использовании внутри [] обозначает отрицание. При использовании вне [] обозначает, что шаблон начинается с начала строки |
\ | начало esc-последовательности (например, \n) |
Внутри [] можно использовать: - для задания диапазона, например [0-9] ^ в начале для задания отрицания, например [^"\n] (не кавычки и не символ перехода на новую строку)
Примеры регулярных выражений
[0-9] | |
[0-9]+ | |
[0-9]*\.[0-9]+ | \. здесь обозначает точку, т.к. просто . имеет другое значение |
[+-]?[0-9]+ | |
#.* | комментарий, начинающийся с #, после которого идет ноль или более символов до конца строки |
\"[^"\n]*["\n] | кавычка, после которой идет любое количество не кавычек и не символов перехода на новую строку, после которых идет кавычка или переход на новую строку - так может задаваться литеральная строка. Здесь вне [] кавычка предваряется \, поскольку символ " имеет самостоятельный смысл; в [] кавычку можно писать без \, поскольку внутри [] кавычка не имеет самостоятельного смысла |
[^ \n\t]+ | любой символ, не являющийся пробелом, переходом на новую строчку, табулостопом, повторяющийся 1 или более раз |
^[ \t]*\n | строка из whitespace - пробелы или знаки табуляции, начинающиеся с начала строки и повторенные ноль или более раз, после которых идет символ перехода на новую строку |
Класс Scanner
- Основной метод - int yylex() - возвращает номер следующей лексемы (токена)
- Свойства
string yytext - текст лексемы int yyline - номер строки лексемы int yycol - номер столбца лексемы int yyleng - длина лексемы
Задание
- Откомпилировать лексический анализатор и запустить его для файла a.txt
- Сделать имя файла, обрабатываемого лексическим анализатором, параметром командной строки
- Подсчитать количество, среднюю, минимальную и максимальную длину всех идентификаторов
- Найти сумму всех целых и сумму всех вещественных в файле
- Дана программа, в которой встречаются ключевые слова begin end. Определить, правильно ли они расставлены
- По данному тексту слов составить таблицу
слово список его вхождений в текст в формате (строка,столбец), (строка,столбец)