Правки по lab1

This commit is contained in:
2025-04-29 13:13:11 +03:00
parent 3963d304ec
commit 20782a2473
7 changed files with 75 additions and 40 deletions

View File

@@ -34,8 +34,15 @@ class LexemeType:
class Lexer:
def __init__(self, lexeme_types: Iterable[LexemeType]):
def __init__(
self,
lexeme_types: Iterable[LexemeType],
error_regex: str,
skip_types: Iterable[str] = [],
):
self.lexeme_types = lexeme_types
self.skip_types = skip_types
self.error_regex = re.compile(r"\s*(" + error_regex + ")")
def analyze(self, text: str) -> list[Lexem]:
lexems: list[Lexem] = []
@@ -43,16 +50,16 @@ class Lexer:
for lex_type in self.lexeme_types:
lexem, new_text = lex_type.consume(text)
if lexem:
lexems.append(lexem)
if lexem.type_name not in self.skip_types:
lexems.append(lexem)
text = new_text
break
else:
error_lexeme, text = self._consume_error(text)
lexems.append(error_lexeme)
return lexems
def _consume_error(self, text: str) -> tuple[Lexem, str]:
match = re.match(r"\s*(\S+)", text)
match = self.error_regex.match(text)
err_text = match.group(1) if match else text.strip()
print(f"Недопустимая лексема: {err_text}")
rest = text[match.end() :] if match else ""

View File

@@ -2,9 +2,8 @@ import math
import os
from typing import Callable
from prettytable import PrettyTable
from lexer import LexemeType, Lexer
from prettytable import PrettyTable
class IdentifierMapper:
@@ -35,30 +34,34 @@ def exp_form_to_complex(exp_str: str) -> str:
LEXEME_TYPES: dict[str, LexemeType] = {
# 1. Идентификаторы
"IDENTIFIER": LexemeType(
"IDENTIFIER", r"[A-Za-z_][A-Za-z_0-9]{0,15}(?![A-Za-z_0-9])", IdentifierMapper()
"IDENTIFIER", r"[A-Za-z][A-Za-z_0-9]{0,15}(?![A-Za-z_0-9])", IdentifierMapper()
),
# 2. Комплексные числа в показательной форме (на самом деле — числа в экспоненциальной форме)
"COMPLEX": LexemeType(
# "COMPLEX", r"[+-]?\d+(?:\.\d+)?E[+-]?\d+(?!E)", exp_form_to_complex
"COMPLEX",
r"[+-]?\d+(?:\.\d+)?E[+-]?\d+(?:\.\d+)?(?!E)",
r"[+-]?\d+(?:\.\d+)?E[+-]?\d+(?:\.\d+)?",
exp_form_to_complex,
),
# 3. Оператор присваивания :=
"ASSIGN": LexemeType("ASSIGN", r"\:=(?![\:=])"),
"ASSIGN": LexemeType("ASSIGN", r"\:="),
# 4. Арифметические операторы
"ARITHMETIC_OP": LexemeType("ARITHMETIC_OP", r"[+\-*/^]"),
# 5. Скобки
"PAREN": LexemeType("PAREN", r"[()]"),
# 6. Разделитель выражений |
# 5. Левая скобка
"LPAREN": LexemeType("LPAREN", r"\("),
# 6. Правая скобка
"RPAREN": LexemeType("RPAREN", r"\)"),
# 7. Разделитель выражений |
"SEPARATOR": LexemeType("SEPARATOR", r"\|"),
# 7. Комментарии от # до конца строки
# 8. Комментарии от # до конца строки
"COMMENT": LexemeType("COMMENT", r"\#.*"),
}
ERROR_REGEX = r".[^|()+\-*/^:=\s]*"
def analyze_and_print_table(code: str):
lexer = Lexer(LEXEME_TYPES.values())
lexer = Lexer(LEXEME_TYPES.values(), ERROR_REGEX, skip_types=["COMMENT"])
lexemes = lexer.analyze(code)
table = PrettyTable(["Лексема", "Тип лексемы", "Значение"])