Семантический анализатор j8b
Архитектурный обзор
Семантический анализатор реализован как многоуровневая система проверок, интегрированная в процесс компиляции.
Основные этапы семантического анализа:
- Предварительный анализ (preAnalyze) - базовая валидация узлов AST
- Декларация символов (declare) - построение символьной таблицы
- Детальный анализ (postAnalyze) - проверка типов и семантических правил
Детализация компонентов
Иерархическая система с несколькими типами областей:
ClassScope
MethodScope
BlockScope
Базовый класс Symbol
- Содержит: имя, тип, модификаторы (final, static)
- Базовый класс для всех символов программы
MethodSymbol
InterfaceSymbol
Класс VarType
Типизация выражений
Ключевые алгоритмы
1. Разрешение символов
// Пример из ClassScope
public Symbol resolve(String name) {
// 1. Проверка полей
if (fields.containsKey(name)) return fields.get(name);
// 2. Проверка методов
if (methods.containsKey(name)) return methods.get(name).get(0);
// 3. Рекурсивный поиск в родительской области
if (parent != null) return parent.resolve(name);
return null; // Символ не найден
}
2. Проверка перегрузки методов
// Из ClassScope.addMethod()
String newSignature = newSymbol.getSignature();
for (MethodSymbol existingMethod : methodsWithSameName) {
if (newSignature.equals(existingMethod.getSignature())) {
throw new SemanticException("Duplicate method signature");
}
// Проверка конфликтов при наследовании
if (newSymbol.getType() == existingMethod.getType() &&
newSymbol.getParameterTypes().equals(existingMethod.getParameterTypes())) {
throw new SemanticException("Method conflicts with inherited method");
}
}
3. Проверка реализации интерфейсов
// Из ClassNode.checkInterfaceImplementation()
for (MethodSymbol interfaceMethod : interfaceMethods) {
boolean implemented = false;
for (MethodSymbol classMethod : classMethods) {
if (interfaceMethod.getSignature().equals(classMethod.getSignature())) {
implemented = true;
break;
}
}
if (!implemented) {
markError("Method " + interfaceMethod.getName() + " not implemented");
}
}
Примеры семантических проверок
1. Контроль типов в операциях
int x = 10;
string s = "text";
bool b = x + s; // Ошибка: несовместимые типы
Анализатор выявит ошибку через механизм isCompatibleWith()
в VarType.
2. Проверка областей видимости
class Test {
private int x;
void method() {
int y = x; // OK
}
}
class Other {
void test() {
Test t = new Test();
int z = t.x; // Ошибка: доступ к private полю
}
}
3. Контроль final переменных
final int MAX = 100;
MAX = 200; // Ошибка: изменение final переменной
Проверяется в postAnalyze()
соответствующих узлов AST.
Обработка ошибок и предупреждений
Система сообщений включает:
- ErrorMessage - критические ошибки компиляции
- WarningMessage - некритические предупреждения
- SourcePosition - точное место ошибки в коде
Пример обработки ошибки
// Из FieldNode.postAnalyze()
if (isFinal() && initializer == null) {
markError("Final field must be initialized");
}
// Базовый метод в AstNode
public ErrorMessage markError(String text) {
ErrorMessage msg = new ErrorMessage(text, getSP());
getMessageContainer().add(msg);
return msg;
}
Рекомендации по улучшению
- Контроль переопределения методов (
@Override
аналог)
- Проверка на переполнение для числовых операций
- Анализ потоков данных для final переменных
← Назад к главной странице