Написание лексера: алгоритм

Рейтинг: 0Ответов: 1Опубликовано: 18.04.2015

Здравствуйте! Пишу лексер. Делаю так: считываю один символ из файла, смотрю, что за символ:

switch(_symbol){
        case '.': return "[symbol: DOT]";
...
}

Но чтобы определить, ключевое ли это слово, приходится считать еще символы. Вижу, что это плохой способ. Как сделать это лучше?

Ответы

▲ 3Принят

Смотрите. Во-первых, вы не можете выяснить, найдено ли ключевое слово до тех пор, пока вы не просмотрите входящий текст до конца этого самого ключевого слова. Отсюда выплывает простой алгоритм: прочитать символы до конца слова, и поискать это слово в таблице ключевых слов.

Для поиска в таблице можно использовать простой перебор, и этого обычно достаточно, если ключевых слов разумное количество.

Но можно и сделать сложнее/эффективнее: применить алгоритм наподобие Ахо—Корасик, который эффективно умеет искать набор строк в тексте. (Для этого внутри строиться trie, префиксное дерево, о котором шло обсуждение недавно.)

Заметьте, что существует популярная утилита lex (и её open source-аналог flex), которая делает именно это: по набору ключевых слов (а также регулярных выражений, так что lex более продвинутая штука) строит нужное поисковое дерево, и выдаёт вам исходный код на C, который нужно просто подключить к проекту.