Разрешение имен в «выражении пути» в компиляторе, например, «person.name» - PullRequest
0 голосов
/ 13 марта 2019

Я какое-то время ломал голову над этим и не могу понять.

У меня есть такой код на моем c-like языке:

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, и мы получаем доступ к полю «информация», которое существует, а также содержит поле 'numFriends'.

Какой общий алгоритм / подход используется для этого типа проверки ошибок в компиляторах?

1 Ответ

2 голосов
/ 13 марта 2019

Правило ввода для этого будет выглядеть примерно так: для любого идентификатора 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
    }
}
...