лексер на регулярных выражениях

Aug 28, 2021 22:15

Нынче придумался лексер для использования в скриптовых языках, который работает тупо на готовых регулярных выражениях, вообще без никаких библиотек. Просто выписываем все возможные лексемы как альтернативы в выражении, и в Перле используем встроенный в выражение код чтобы сохранить номер лексемы. Например:

$s = "++abc"; # string to tokenize $t = 0; # token ids returned here while ($s =~ s/^\s*([+][+](?{ $t=1; })|[+](?{ $t=2; })|[a-z]+(?{ $t=3; }))//) { print $s, "=", $1, "\n"; }

Он тут ищет лексемы "+", "++", и простые идентификаторы. Есть некоторый фокус в том, что если одни альтернативы являются префиксами других, то более длинные альтернативы надо писать первыми, но в остальном все легко и просто. Ну, красивше будет в расширенном синтаксисе регулярных выражений.

В Питоне встраивания кода нет, так что из распознавания выражения выходит только текст, но его можно потом перевести в код по словарю, примерно так:

import re tokens = { "++": 1, "+": 2, } # regexp can be auto-generated from reverse-ordered dict keys lex = re.compile(r'^\s*(' + r'[+][+]' + r'|[+]' + r'|[a-z]+' + r')') # the string to parse s = "++abc" m = lex.match(s) # 3 is the token id for the identifiers that are variable t = tokens[m.group(1)] if m.group(1) in tokens else 3 # consume the token from the string s = s[m.span()[1]:]

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

This entry was originally posted at https://sab123.dreamwidth.org/639376.html. Please comment there using OpenID.

кнопкодавство

Previous post Next post
Up