Use a propriedade de valor do dicionário como a chave do dicionário

5

Estou criando um AST e atualmente estou introduzindo o conceito de "escopo". Ao implementar um escopo, sempre que um identificador (nome da variável) é usado, posso determinar sua declaração original.

Para o objeto de escopo, eu iria implementar um dicionário como a estrutura de dados subjacente. O dicionário seria digitado com o objeto identificador, com o valor sendo o objeto de declaração. O objeto de declaração também contém uma referência ao mesmo identificador. Então, algo como:

class Identifier() {
    string name;
}

class Declaration() {
    Type type;
    Identifier ident;
}

class Scope() {
    Dictionary<Identifier,Declaration> identifiers;
}

O que eu quero saber é, está teclando um dicionário com uma propriedade da má prática do valor correspondente da chave? Existe uma maneira melhor de fazer isso?

    
por David Poxon 26.09.2015 / 02:24
fonte

1 resposta

1

Não vejo nada de fundamentalmente errado com isso.

O fato de o Identifier ser um membro da Declaração, o tipo de valores do mapa de identificadores do seu Scope é, na maioria das vezes, coincidência.

Você também poderia ter optado, por exemplo, por:

class Identifier() {
    string name;
}

class Declaration() {
    int id;
    Type type;
    Identifier identifier;
}

class Scope() {
    Dictionary<int, Declaration> identifiers; // (map from Declaration.id to Declaration)
}

Mas, por qualquer motivo, você acabou de descobrir que usar o identificador em si como a "chave primária" para a própria declaração que o introduz era mais conveniente.

O que eu acho mais intrigante, no entanto, é por que você não optou pelo pouco mais comum (eu acredito) para esse tipo de coisa:

class Identifier() {
    string name;
}

class Declaration() {
    Type type;
    Identifier identifier;
}

class Scope() {
    int id;
    List<Declaration> identifiers; // (declared at this scope level)
    Dictionary<int, Scope> innerScopes; // (map from Scope.id to Scope, useful for representing inner scopes, be they lexical or otherwise)
    Scope parent;
    bool IsRoot => parent == null;
}

etc?

Embora minha pergunta seja tendenciosa, geralmente prefiro dissociar as informações obtidas da análise sintática (ou seja, qualquer que seja a AST que você já tenha) e a que pertence à semântica (sua classe Scope, preenchida somente depois ) - onde o "link" principal entre os dois seria sua classe Identifier (por exemplo, possivelmente unicamente chaveado / indexado pelo local físico de linha / coluna da ocorrência do identificador que o declara em primeiro lugar para este ou aquele escopo).

    
por 14.03.2018 / 05:47
fonte