#java #compiler-construction #semantic-analysis
#java #компилятор-построение #семантический анализ
Вопрос:
Я некоторое время ломал голову над этим и не могу в этом разобраться.
У меня есть какой-то подобный код на моем c-подобном языке:
struct PersonInfo {
int numFriends;
int favColour;
}
struct Person {
PersonInfo info;
string firstName;
string lastName;
};
Person john;
john.info.numFriends; // <- specifically this part here!
Как я могу проверить, что выражение пути ‘john.info.numFriends’ является
правильно, т. е. все символы существуют. джон существует, джон является экземпляром
структуры Person, и мы получаем доступ к существующему полю ‘info’,
а также содержит поле ‘numFriends’.
Какой общий алгоритм / подход используется для выполнения такого типа проверки ошибок в компиляторах?
Комментарии:
1. Способ, которым Python (по общему признанию, как интерпретируемый язык, а не скомпилированный) делает это, заключается в том, что каждый раз, когда библиотека или модуль загружаются в память, им присваивается словарь ключевых слов для ссылок. Я полагаю, что проверка этого была бы такой: (1) посмотрите на
Person
‘s dict (2) есть ли у него ключinfo
? (3) Посмотрите наPersonInfo
‘s dict (4) есть ли у него ключnumFriends
? Итак, в принципе, просто рекурсивно проверьте, существует ли ссылка. Есть ли причина, по которой здесь не сработало бы?2. @GreenCloakGuy Это имеет смысл, я просто не могу уловить суть помещения этого в код. У меня есть таблица символов, но все, что она делает, это сообщает мне, существует ли символ, например ‘john’. Я предполагаю, что мне нужно было бы сохранить тип ‘john’ (Person) рядом с символом? Кроме того, вы знаете, какая терминология для этого? Разрешение символов для a … выражение оператора dot?
Ответ №1:
Правило ввода для этого будет выглядеть примерно так: Для любого идентификатора memberName
и любого выражения exp
: Если exp
это выражение типа, T
где T
это структура с именем элемента memberName
, то выражение exp.memberName
правильно типизировано и имеет тип T.memberName
. В противном случае выражение неверно типизировано.
С точки зрения реализации, это не сильно отличается от реализации других частей средства проверки типов: Вы повторяете подвыражение, проверяете, имеет ли оно соответствующий тип, выдаете ошибку типа, если нет, и возвращаете правильный тип в противном случае. Единственное, что следует учитывать, это то, что вам нужно отслеживать, какие типы структур определяют, какие члены. Код может выглядеть примерно так:
TypeInfo visitDotExpression(MemberAccess exp) {
TypeInfo leftType = visit(exp.leftOperand);
if (leftType.isStructType()) {
if (leftType.memberTypes.containsKey(exp.memberName)) {
return leftType.memberTypes.get(exp.memberName);
} else {
// produce a type error because the struct doesn't have a member
// with the given name
}
} else {
// Produce a type error because left operand of `.` is not a struct
}
}