kvs/квс_проход3.py

141 lines
5.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Третий проход КВС
- Читает AST для получения констант
- Заменяет имена констант в 'исходная_команда' на их числовые значения
- Записывает результат в колонку 'команда_со_значениями'
- Поддерживает константы в операндах (как непосредственные значения)
"""
import sys
import csv
def read_ast(ast_file):
"""Читает AST файл и извлекает константы"""
symbols = {} # имя константы -> значение
with open(ast_file, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue
parts = line.split(':')
if parts[0] == "DIRECTIVE" and len(parts) >= 4:
directive = parts[1]
if directive == '.константа':
name = parts[2]
value_str = parts[3]
if value_str.startswith('0x') or value_str.startswith('0X'):
value = int(value_str, 16)
else:
value = int(value_str)
symbols[name] = value
print(f" константа: {name} = {value}")
return symbols
def read_csv(csv_file):
"""Читает CSV файл и возвращает список записей и заголовки"""
entries = []
headers = []
with open(csv_file, 'r', encoding='utf-8') as f:
reader = csv.reader(f, delimiter=';')
headers = next(reader)
for row in reader:
entries.append(row)
return headers, entries
def substitute_constants(entries, headers, symbols):
"""Заменяет константы в исходной команде на их значения"""
try:
source_idx = headers.index('исходная_команда')
source_with_values_idx = headers.index('команда_со_значениями')
except ValueError as e:
print(f"Ошибка: не найдена нужная колонка в CSV: {e}")
sys.exit(1)
substituted_count = 0
for row in entries:
source = row[source_idx].strip()
if not source:
continue
# Копируем исходную команду
new_source = source
# Заменяем константы в команде
for name, value in symbols.items():
if name in new_source:
# Заменяем имя константы на её значение
new_source = new_source.replace(name, str(value))
# Если команда изменилась, записываем в колонку команда_со_значениями
if new_source != source:
row[source_with_values_idx] = new_source
substituted_count += 1
return substituted_count
def save_csv(csv_file, headers, entries):
"""Сохраняет обновлённый CSV файл"""
with open(csv_file, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f, delimiter=';')
writer.writerow(headers)
writer.writerows(entries)
def print_statistics(symbols_count, substituted_count, symbols):
"""Выводит статистику по заменам констант"""
print(f"\n--- Статистика замены констант ---")
print(f" Всего констант в AST: {symbols_count}")
print(f" Заменено в командах: {substituted_count}")
if symbols:
print(f"\n--- Найденные константы ---")
for name, value in sorted(symbols.items()):
print(f" {name} = {value}")
def main():
if len(sys.argv) != 3:
print("Использование: python kvs_pass3.py <аст.файл> <входной.csv>")
print(" <аст.файл> - файл с AST (например, программа.аст)")
print(" <входной.csv> - CSV файл для обновления")
sys.exit(1)
ast_file = sys.argv[1]
csv_file = sys.argv[2]
print(f"\n=== Третий проход КВС ===")
print(f"Чтение AST: {ast_file}")
# Читаем константы из AST
symbols = read_ast(ast_file)
print(f"Найдено констант: {len(symbols)}")
print(f"\nЧтение CSV: {csv_file}")
headers, entries = read_csv(csv_file)
print(f"\n--- Замена констант в командах ---")
substituted_count = substitute_constants(entries, headers, symbols)
print_statistics(len(symbols), substituted_count, symbols)
# Сохраняем результат
save_csv(csv_file, headers, entries)
print(f"\nCSV сохранен: {csv_file}")
print(f"Колонка 'команда_со_значениями' обновлена")
if __name__ == "__main__":
main()