Aug. 28th, 2021

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

$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]:]


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

January 2026

S M T W T F S
     123
45678910
11121314151617
18192021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 4th, 2026 01:58 am
Powered by Dreamwidth Studios