FirstVersion

This commit is contained in:
2026-05-03 21:02:34 +07:00
parent 05875d8aa2
commit 0d6b240099
12 changed files with 632 additions and 566 deletions
+153
View File
@@ -0,0 +1,153 @@
import tkinter as tk
from tkinter import scrolledtext, messagebox, filedialog
import re
class TokenManager:
def __init__(self, root):
self.root = root
self.root.title("C++ Tokenizer Manager (Pro)")
self.root.geometry("1000x900")
self.root.configure(bg="#f5f5f5")
self.tokens = []
# --- Секция 1: Ввод и Загрузка ---
top_frame = tk.Frame(root, bg="#f5f5f5")
top_frame.pack(fill=tk.X, padx=15, pady=10)
tk.Label(top_frame, text="1. Управление токенами:", font=('Arial', 10, 'bold'), bg="#f5f5f5").pack(side=tk.LEFT)
btn_load_file = tk.Button(top_frame, text="📥 Загрузить и разбить датасет (.txt)",
command=self.load_dataset_file, bg="#FF9800", fg="white", font=('Arial', 9, 'bold'))
btn_load_file.pack(side=tk.RIGHT, padx=5)
self.input_area = scrolledtext.ScrolledText(root, height=6, font=('Consolas', 10))
self.input_area.pack(padx=15, pady=5, fill=tk.X)
self.input_area.insert(tk.END, "// Вставьте старый код конструктора сюда или используйте кнопку загрузки файла...")
btn_parse = tk.Button(root, text="Извлечь токены из кода выше", command=self.parse_input, bg="#2196F3", fg="white")
btn_parse.pack(pady=5)
# --- Секция 2: Средняя часть (Добавление и Список) ---
middle_frame = tk.Frame(root, bg="#f5f5f5")
middle_frame.pack(padx=15, pady=10, fill=tk.BOTH, expand=True)
# Левая колонка: Добавление
left_col = tk.LabelFrame(middle_frame, text="Добавить вручную", padx=10, pady=10)
left_col.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))
self.new_token_entry = tk.Entry(left_col, font=('Arial', 11))
self.new_token_entry.pack(fill=tk.X, pady=5)
self.new_token_entry.bind('<Return>', lambda e: self.add_single_token())
tk.Button(left_col, text="Добавить в список", command=self.add_single_token, bg="#4CAF50", fg="white").pack(fill=tk.X, pady=5)
# Правая колонка: Просмотр
self.right_col = tk.LabelFrame(middle_frame, text="Текущий список (0 токенов)", padx=10, pady=10)
self.right_col.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
list_scroll = tk.Scrollbar(self.right_col)
list_scroll.pack(side=tk.RIGHT, fill=tk.Y)
self.token_listbox = tk.Listbox(self.right_col, font=('Arial', 10), yscrollcommand=list_scroll.set, selectmode=tk.EXTENDED)
self.token_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
list_scroll.config(command=self.token_listbox.yview)
tk.Button(self.right_col, text="Удалить выбранные", command=self.delete_selected, bg="#F44336", fg="white").pack(fill=tk.X, pady=(5,0))
# --- Секция 3: Вывод результата ---
tk.Label(root, text="3. Готовый код для C++ (token.cpp):", font=('Arial', 10, 'bold'), bg="#f5f5f5").pack(pady=(10,0))
self.output_area = scrolledtext.ScrolledText(root, height=15, bg="#fafafa", font=('Consolas', 10), fg="#2e7d32")
self.output_area.pack(padx=15, pady=5, fill=tk.X)
# Нижняя панель
bottom_frame = tk.Frame(root, bg="#f5f5f5")
bottom_frame.pack(fill=tk.X, padx=15, pady=10)
self.status_label = tk.Label(bottom_frame, text="Количество токенов: 0", font=('Arial', 11, 'bold'), bg="#f5f5f5")
self.status_label.pack(side=tk.LEFT)
tk.Button(bottom_frame, text="📋 Копировать код", command=self.copy_to_clipboard, bg="#9E9E9E", fg="white", font=('Arial', 10, 'bold')).pack(side=tk.RIGHT)
def load_dataset_file(self):
"""Открывает файл и разбивает его на токены согласно правилам"""
file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt"), ("All files", "*.*")])
if not file_path:
return
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# РЕГУЛЯРНОЕ ВЫРАЖЕНИЕ:
# [a-zA-Zа-яА-Я0-9ёЁ-]+ --> Слова (включая цифры и дефисы внутри типа "что-то")
# [^\w\s] --> Любой символ, который не буква и не пробел (знаки препинания)
pattern = r"[a-zA-Zа-яА-Я0-9ёЁ-]+|[^\w\s]"
raw_tokens = re.findall(pattern, content)
new_count = 0
for t in raw_tokens:
if t not in self.tokens:
self.tokens.append(t)
new_count += 1
self.refresh_ui()
messagebox.showinfo("Загрузка завершена", f"Всего токенов найдено: {len(raw_tokens)}\nДобавлено новых уникальных: {new_count}")
except Exception as e:
messagebox.showerror("Ошибка", f"Не удалось прочитать файл:\n{str(e)}")
def parse_input(self):
text = self.input_area.get("1.0", tk.END)
found = re.findall(r'add\("(.*?)"\);', text)
if not found:
messagebox.showwarning("Внимание", "Используйте формат add(\"слово\");")
return
added = 0
for t in found:
if t not in self.tokens:
self.tokens.append(t)
added += 1
self.refresh_ui()
def add_single_token(self):
raw_input = self.new_token_entry.get().strip()
if not raw_input: return
if raw_input not in self.tokens:
self.tokens.append(raw_input)
self.refresh_ui()
self.new_token_entry.delete(0, tk.END)
def delete_selected(self):
indices = self.token_listbox.curselection()
to_remove = [self.token_listbox.get(i) for i in indices]
for val in to_remove:
self.tokens.remove(val)
self.refresh_ui()
def refresh_ui(self):
self.token_listbox.delete(0, tk.END)
for t in self.tokens:
self.token_listbox.insert(tk.END, t)
self.right_col.config(text=f"Текущий список ({len(self.tokens)} токенов)")
self.output_area.delete("1.0", tk.END)
code = "Tokenizer() {\n"
# Группируем по 6 для красоты в C++
for i in range(0, len(self.tokens), 6):
line = self.tokens[i:i+6]
code += " " + " ".join([f'add("{t}");' for t in line]) + "\n"
code += " }"
self.output_area.insert(tk.END, code)
self.status_label.config(text=f"Количество токенов: {len(self.tokens)}")
def copy_to_clipboard(self):
self.root.clipboard_clear()
self.root.clipboard_append(self.output_area.get("1.0", tk.END))
messagebox.showinfo("ОК", "Код скопирован")
if __name__ == "__main__":
root = tk.Tk()
app = TokenManager(root)
root.mainloop()