Может ли lex (flex) разбирать кириллицу в кодировке UTF-8? Для ответа на этот вопрос проведем небольшой эксперимент.
Создадим новый текстовый файл с именем new.ll. Откроем его в редакторе и добавим следующее содержание:
%{ #include <stdio.h> %} bom \xEF\xBB\xBF white [ \t] digit [0-9] hex_digit {digit}|[aA]|[bB]|[cC]|[dD]|[eE]|[fF] latin [a-zA-Z] cyrillic1 \xD0[\x81\x90-\xBF] cyrillic2 \xD1[\x80-\x8F\x91] cyrillic {cyrillic1}|{cyrillic2} letter {cyrillic}|{latin} %% stop|стоп { return 0;} если|if { puts("Ключевое слово 'если'"); } иначе|else { puts("Ключевое слово 'иначе'"); } цикл|do { puts("Ключевое слово 'цикл'"); } пока|while { puts("Ключевое слово 'пока'"); } для|for { puts("Ключевое слово 'для'"); } {letter}({letter}|{digit}|_)* { puts("Идентификатор"); } 0(b|д)(0|1)+ { puts("Двоичная константа"); } 0x{hex_digit}+ { puts("Шестнадцатиричная константа"); } {digit}{digit}* { puts("Целая константа"); } "=" { puts("Токен 'ПРИСВОИТЬ'"); } "+" { puts("Токен 'ПЛЮС'"); } "-" { puts("Токен 'МИНУС'"); } "*" { puts("Токен 'ЗВЕЗДОЧКА'"); } "/" { puts("Токен 'СЛЭШ'"); } "(" { puts("Токен 'Л_СКОБКА'"); } ")" { puts("Токен 'П_СКОБКА'"); } "{" { puts("Токен 'Л_ФИГ_СКОБКА'"); } "}" { puts("Токен 'П_ФИГ_СКОБКА'"); } "[" { puts("Токен 'Л_КВ_СКОБКА'"); } "]" { puts("Токен 'П_КВ_СКОБКА'"); } ";" { puts("Токен 'ТОЧКА_С_ЗАПЯТОЙ'"); } {white} { ; } \n { ; } {bom} { ; } . { puts("Неизвестный символ"); }
После сохранения, в консоли генерируем С-файл командой: flex -8 -o new.c new.ll
Если все прошло благополучно, то появится новый файл с именем new.c. Скомпилируем его командой: gcc new.c -o new -lfl
Если компилятор ругается, что не может найти библиотеку, попробуйте вместо ключа -lfl -ll. В Linux может понадобиться установить дополнительный пакет командой: sudo apt-get install libfl-dev
Справившись с этим, запускаем на исполнение: ./new Программа ждет ввода. Попробуем скормить ей текст следующего содержания:
цел следующий_символ (цел индекс)
{
симв врем = строка [индекс];
индекс = индекс +10;
0b00110011
0д1111110
0x1234abcdef
}
Лично у меня программа справилась с разбором, вернув следующий результат:
Идентификатор Идентификатор Токен 'Л_СКОБКА' Идентификатор Идентификатор Токен 'П_СКОБКА' Токен 'Л_ФИГ_СКОБКА' Идентификатор Идентификатор Токен 'ПРИСВОИТЬ' Идентификатор Токен 'Л_КВ_СКОБКА' Идентификатор Токен 'П_КВ_СКОБКА' Токен 'ТОЧКА_С_ЗАПЯТОЙ' Идентификатор Токен 'ПРИСВОИТЬ' Идентификатор Токен 'ПЛЮС' Целая константа Токен 'ТОЧКА_С_ЗАПЯТОЙ' Двоичная константа Двоичная константа Шестнадцатиричная константа Токен 'П_ФИГ_СКОБКА'
Вывод: lex (flex) может быть успешно использован для создания компилятора русского языка программирования.
Показанный пример носит иллюстративный характер и не претендует на безошибочность для всех случаев.
Отредактировано Евгений (2023-09-23 09:44:44)