Нынче придумался лексер для использования в скриптовых языках, который работает тупо на готовых регулярных выражениях, вообще без никаких библиотек. Просто выписываем все возможные лексемы как альтернативы в выражении, и в Перле используем встроенный в выражение код чтобы сохранить номер лексемы. Например:
$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.