Побудова лексичного аналізатора засобами регулярних виразів

 

Побудова лексичного аналізатора (сканера) засобами регулярних виразів можлива при використанні мов програмування з вбудованою підтримкою регулярних виразів, наприклад, C#, PHP, Python, Java, Perl, тощо. При цьому за допомогою регулярних виразів задають правила виділення лексем і ідентифікаторів з подальшим утворенням таблиці лексем і ідентифікаторів. Наприклад ідентифікатор, який починається з знаку «_» після якого іде буква після якої може зустрічатися або буква або цифра нуль або більше разів можна виділити задавши регулярний вираз: '_[a-zA-Z][a-zA-Z0-9]*'.

Побудова лексичного аналізатора засобами спеціалізованого програмного забезпечення

Побудова лексичного аналізатора (сканера) засобами генераторів лексичних аналізаторів, наприклад, інструменту і мови Lex або Flex відбувається в 3 етапи (рис.1.7).

Рис.1.7. Створення лексичного аналізатора засобами Lex або Flex.

 

Flex на вході отримує текст у вільному форматі й правила виділення лексем. На виході дає код аналізатора, в вигляді функції на мові C.

Правила задаються в вигляді регулярних виразів ліворуч і, здебільшого, коду на мові C праворуч. Правила містять три секції, відокремлені рядком «%%»:

Визначення

%%

Правила

%%

Код користувача

Визначення містять стартові значення й визначення, правила, безпосередньо самі вирази й дії, що відповідають їм, користувацький код просто включається в вивід flex. Деякі секції можуть бути відсутніми.

Функція аналізатора отримує текст на вході й виконує заданий код для кожної знайденої лексеми. Наприклад, код:

%%

username

printf("%s", getlogin());

для кожного входження username в тексті, виконає код printf("%s",getlogin()).

Дана функція виведе в потік рядок, що повертається функцією getlogin(). Тобто, кожне входження username у вхідному потоці буде замінено значенням, поверненим getlogin(). Наприклад, іменем поточного користувача.

Нижче наведено правила, відповідно до яких остаточна функція має друкувати на виході тип лексеми (if, змінна, число, унарна чи бінарна операція) та значення для деяких лексем:

 

%%

if  printf ("IF statement\n");

[a-z]+ printf ("tag, value %s\n", yytext);

{D}+ printf ("decimal number %s\n", yytext);

"++" printf ("unary op\n");

"+" printf ("binary op\n");

 

Приклад підрахунку кількості рядків і символів у тексті:

%{

int num_lines = 0, num_chars = 0;

%}

 

%%

 

\n

 ++num_lines; ++num_chars;

.

++num_chars;

%%

main()

{

yylex();

printf("# of lines = %d, # of chars = %d\n", num_lines, num_chars);

}

Далі, функцію, створену генератором можна використати з генераторами синтаксичних аналізаторів. Зазвичай flex використовують з yacc чи bison. Синтаксичний аналізатор використовує виклик функції yylex(), створеної генератором flex для пошуку наступної лексеми.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: