Генератор лексических анализаторов Lex.

advertisement
Лекция 13
13 ноября 2015 г.
Опр. 1: Lex (и его аналоги) – генератор лексических анализаторов, который по регулярному
описанию языка генерирует код на языке C лексического анализатора.
Опр. 2: Генератор – программа, которая генерирует код другой программы (как правило, на языке
того же уровня).
Формат описания ЯП для Lex
Декларации C, заголовочные файлы и макросы lex
%%
Шаблоны и действия
%%
Функции на языке C, используемые действиями
lang.l
…
%%
…
%%
…
lex.yy.c
int yylex()
flex.exe
lex.yy.c – программа на языке C, определяющая функцию лексического анализатора yylex()
(аналог функции getNextLexem() с прошлых лекций)
Секция №1
%{
#include “header.h”
#define MAX 1000
char c;
%}
Все, что заключено в %{ … %}, без изменений
вставляется в код генератора
или
MAC ab*c
имя
значение
hello{MAC}
helloab*c
Секция №2
Регулярные
выражения
шаблон1 действие1
шаблон2 действие2
…
шаблонN действиеN
Куски кода на языке C,
вызываемые, когда
срабатывает соответствующий
шаблон
Расширенный синтаксис регулярных выражений
c
Символ c
“c”
Символ “c”, даже если это спецсимвол
\c
То же, что и “c”
[cd] Символ c или символ d
[a-z] Любой один символ из диапазона a-z
[^c] Любой символ, кроме c
.
Любой символ, кроме переноса строки
^x
Шаблон x, если он начинается с начала строки
x$
Шаблон x, если им заканчивается строка
x?
0 или 1 вхождение x
x+
Положительное замыкание шаблона x
x*
Замыкание шаблона x
xy
Конкатенация шаблонов x и y
x|y
x или y
(x)
Скобки
<S>x Шаблон x, когда lex находится в состоянии S
{X}
Имя макроса из секции №1
x{m} m повторений шаблона x
x{m,n}повторение шаблона x от m до n раз
Секция №3
int yywrap(){
return 1;
}
int main(){
while(yylex());
}
Любой вспомогательный код на C
INT [0-9]+
EXP ([eE][+-]?{INT})
%{
int i;
float f;
%}
%%
{INT}
{INT}\.{INT}?{EXP}?
.
%%
int main ()
{ yylex(); }
int yywrap ()
{ }
{sscanf
cout <<
{sscanf
cout <<
;
(yytext, “%d”, &i);
"Int" << endl;}
(yytext, “%lf”,&f);
"Float" << endl;}
INT [0-9]+
IDENT [a-zA-Z][a-zA-Z0-9]*
%{
#include <iostream>
using namespace std;
int i;
%}
%%
-?{INT}
{ sscanf_s (yytext, "%d", &i);
cout << "[num, " << i << "]" << endl; return 1; }
\'[^\']\' { cout << "[chr, " << yytext << "]" << endl; return 1; }
\"[^\"]+\" { cout << "[str, " << yytext << "]" << endl; return 1; }
if
int
char
if
else
switch
case
while
for
return
in
out
{
{
{
{
{
{
{
{
{
{
{
{
cout
cout
cout
cout
cout
cout
cout
cout
cout
cout
cout
cout
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<
"[kwif]" << endl; return 1; }
"[kwint]" << endl; return 1; }
"[kwchar]" << endl; return 1; }
"[kwif]" << endl; return 1; }
"[kwelse]" << endl; return 1; }
"[kwswitch]" << endl; return 1; }
"[kwcase]" << endl; return 1; }
"[kwwhile]" << endl; return 1; }
"[kwfor]" << endl; return 1; }
"[kwreturn]" << endl; return 1; }
"[kwin]" << endl; return 1; }
"[kwout]" << endl; return 1; }
"="
"+"
"-"
"*"
{
{
{
{
cout
cout
cout
cout
<<
<<
<<
<<
"[opassign]" << endl; return 1; }
"[opplus]" << endl; return 1; }
"[opminus]" << endl; return 1; }
"[opmult]" << endl; return 1; }
"=="
"!="
"<"
">"
"<="
"!"
"||"
"&&"
{
{
{
{
{
{
{
{
cout
cout
cout
cout
cout
cout
cout
cout
<<
<<
<<
<<
<<
<<
<<
<<
"[opeq]" << endl; return 1; }
"[opne]" << endl; return 1; }
"[oplt]" << endl; return 1; }
"[opgt]" << endl; return 1; }
"[ople]" << endl; return 1; }
"[opnot]" << endl; return 1; }
"[opor]" << endl; return 1; }
"[opand]" << endl; return 1; }
"("
")"
"{"
"}"
"["
"]"
";"
","
":"
{
{
{
{
{
{
{
{
{
cout
cout
cout
cout
cout
cout
cout
cout
cout
<<
<<
<<
<<
<<
<<
<<
<<
<<
"[lpar]" << endl; return 1; }
"[rpar]" << endl; return 1; }
"[lbrace]" << endl; return 1; }
"[rbrace]" << endl; return 1; }
"[lbracket]" << endl; return 1; }
"[rbracket]" << endl; return 1; }
"[semicolon]" << endl; return 1; }
"[comma]" << endl; return 1; }
"[colon]" << endl; return 1; }
[a-zA-Z][a-zA-Z0-9_]* { cout << "[id, " << yytext << "]" << endl;
return 1; }
[ \t\n]
;
.
;
%%
int yywrap(){
cout << "[eof]" << endl;
return 1;
}
int main(){
while(yylex());
}
Download