Skip to content
Snippets Groups Projects
Commit 90b16084 authored by Iori Ichinose's avatar Iori Ichinose :speech_balloon:
Browse files

support recursive commands

parent 31810603
No related branches found
No related tags found
No related merge requests found
from typing import Callable
import re
import random
class Command:
@staticmethod
def rand(m: re.Match) -> str:
left, right = int(m.group(1)), int(m.group(2))
if left > right:
left, right = right, left
return str(random.randint(left, right))
@staticmethod
def choice(m: re.Match) -> str:
words = m.group(1).split()
if words == []:
return ''
return random.choice(words)
@staticmethod
def repeat(m: re.Match) -> str:
key = m.group(1)
count = int(m.group(2))
count = 15 if count >= 15 else count
return key * count
@staticmethod
def concat(m: re.Match) -> str:
keys = m.group(1).split()
print(keys)
return ''.join(keys)
commands: dict[re.Pattern, Callable[[re.Match], str]] = {
re.compile(r'rand (\d+) (\d+)'): Command.rand,
re.compile(r'choice (.*)'): Command.choice,
re.compile(r'repeat (.*?) (\d+)'): Command.repeat,
re.compile(r'concat (.*)'): Command.concat,
}
def replace_command(text: str) -> str:
for r, handler in commands.items():
if m := r.match(text):
try:
return handler(m)
except:
pass
return text
def parse_commands(text: str) -> str:
n = len(text)
start, end = 0, n
i = 0
has_sub = False
flag = 0
while i < n:
if text[i:i+2] == '${':
has_sub = True
if flag == 0:
start = i
flag += 1
if text[i] == '}':
flag -= 1
if flag == 0:
end = i+1
i += 1
if flag != 0 or not has_sub:
return replace_command(text)
else:
return parse_commands(text[:start] +
parse_commands(text[start+2:end-1]) +
text[end:])
if __name__ == '__main__':
print(parse_commands(r'a${${choice rand concat} 1 2}?'))
......@@ -5,7 +5,7 @@ import random
from nonebot.adapters.cqhttp.message import Message, MessageSegment
from nonebot.adapters.cqhttp import Bot, Event
from .commands import parse_commands
from src.utils import CQGen
from .ask_utils import *
......@@ -23,7 +23,6 @@ class Type(Enum):
OR_NO1 = 8
OR_NO2 = 9
OR_NOT = 10
COMMAND = 11
tokens = {
......@@ -39,37 +38,6 @@ tokens = {
re.compile(r'什么'): Type.WORD,
re.compile(r'几.'): Type.R10,
re.compile(r''): Type.R10,
re.compile(r'\${(.*?)}'): Type.COMMAND,
}
class Command:
@staticmethod
def rand(m: re.Match) -> str:
left, right = int(m.group(1)), int(m.group(2))
if left > right:
left, right = right, left
return str(random.randint(left, right))
@staticmethod
def choice(m: re.Match) -> str:
words = m.group(1).split()
if words == []:
return ''
return random.choice(words)
@staticmethod
def repeat(m: re.Match) -> str:
key = m.group(1)
count = int(m.group(2))
count = 15 if count >= 15 else count
return key * count
commands: dict[re.Pattern, Callable[[re.Match], str]] = {
re.compile(r'rand (\d+) (\d+)'): Command.rand,
re.compile(r'choice (.*)'): Command.choice,
re.compile(r'repeat (.*?) (\d+)'): Command.repeat,
}
......@@ -140,16 +108,6 @@ class Parser:
def normal(self, token: str) -> str:
return token
def command_handler(self, token: str) -> str:
token = token[2:-1]
for regex, handler in commands.items():
if m := regex.match(token):
try:
return handler(m)
except:
pass
return token
handlers = {
Type.WORD: rand_word,
Type.TIME: rand_time,
......@@ -162,11 +120,11 @@ class Parser:
Type.OR_NO1: choose_no1,
Type.OR_NO2: choose_no2,
Type.OR_NOT: choose_not,
Type.COMMAND: command_handler,
Type.NORMAL: normal,
}
def parse_text(self, text: str):
text = parse_commands(text)
i, n = 0, len(text)
ret: list[Token] = []
while i < n:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment