Partage
  • Partager sur Facebook
  • Partager sur Twitter

Créer un type checker ou un analyseur de contexte

Sujet résolu
    11 novembre 2018 à 0:54:35

    Bonjour :)

    Je suis en train de créer un analyseur pour analyser un petit AST généré par un de mes projets, et avant de trop l'entamer, j'aimerais avoir quelques conseils concernant le type checking ou l'analyseur de contexte, c'est-à-dire savoir analyser quelque chose comme ceci par exemple : 

    type size_t = unsigned myint;
    
    size_t main(int argc, char *argv[]) {
        if (argc > 10) {
            bool test = true;
        }
        else {
            test = false;
        }
        int argc = 10;
        return argc;
    }

    Et qu'il me trouve ces erreurs : 

    • type 'myint' non définit ;
    • variable 'test' non définit dans son contexte ;
    • redéfinition de la variable 'argc' ;
    • 'main()' est du type 'size_t' mais renvoie une valeur du type 'int'.

    Par exemple.

    Je ne sais pas du tout comment m'y prendre.

    Si vous avez des idées, (concernant n'importe quel langage, c'est surtout le principe qu'il me faudrait), je suis preneur !

    Je vous remercie, bonne journée :D

    -
    Edité par Geralt de Riv 11 novembre 2018 à 0:56:46

    • Partager sur Facebook
    • Partager sur Twitter
    Le doute est le commencement de la sagesse
      12 novembre 2018 à 8:48:32

      Lu'!

      Tu définis la notion de contexte qui stocke la liste les symboles connus dans chaque catégorie (type, variable, etc), et tu maintiens une pile de contextes qui va en gros être mise à jour à chaque création/destruction d'un bloc.

      -
      Edité par Ksass`Peuk 12 novembre 2018 à 11:12:04

      • Partager sur Facebook
      • Partager sur Twitter

      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

        12 novembre 2018 à 18:03:52

        Merci pour ta réponse ;)

        Ksass`Peuk a écrit:

        Tu définis la notion de contexte qui stocke la liste les symboles connus dans chaque catégorie (type, variable, etc)

        Donc, si je comprend bien, je devrais créer quelque chose proche de :

        struct Variable {
            std::string name;
            Type type;
            Expr value;
        };
        
        std::vector<Variable> variables;
        
        struct Function {
            std::string name;
            Type type;
            Arguments arguments;
            Block body;
        };
        
        std::vector<Function> functions;
        
        struct TypeDef {
            std::string name;
            Type typeValue;
        };
        
        std::vector<TypeDef> typeDefs;

        Par exemple ?

        Et ensuite, créer une structure "contexte" : 

        struct Context {
            std::vector<Variable> variables;
            std::vector<Function> functions;
            std::vector<TypeDef> typeDefs;
        };

        Et ensuite un std::map pour sauvegarder chaque contexte :

        std::map<size_t /* Pour identifier le contexte */, Context> contexts;

        ?

        Donc par exemple, ce code : 

        bool bar = true;
        
        if (bar == true) {
            bar = false;
            int foo = 87;
        }
        
        type MyType = int;
        
        MyType test = 16;

        Pourrait être représenté comme ça dans le map :

        0 | variables = { { "bar", "bool", "true" } }
        1 | [0].variables["bar"] = "false"
        1 | variables = { { "foo", "int", "87" } }
        0 | types = { { "MyType", "float" } }
        0 | variables = { { "bar", "bool", "false" }, { "test", "MyType", "16" } }

        Par exemple ?

        Et le contexte 0 serait donc le "top-level".

        Est-ce que mes exemples sont correctes, ou faudrait-il faire autrement ?

        Merci :D

        -
        Edité par Geralt de Riv 12 novembre 2018 à 18:05:54

        • Partager sur Facebook
        • Partager sur Twitter
        Le doute est le commencement de la sagesse
          12 novembre 2018 à 18:39:52

          Je ne pense pas que distinguer variables et fonction soit vraiment intéressant, une fonction c'est juste une variable qu'on peut appliquer. Et je vois pas l'intérêt d'une map non plus. Reste sur des vectors. Le contexte en cours c'est .back(), et celui d'avant, c'est n-2, etc. Et quand ton bloc se termine, tu as juste à pop_back().

          -
          Edité par Ksass`Peuk 12 novembre 2018 à 18:40:22

          • Partager sur Facebook
          • Partager sur Twitter

          Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

            12 novembre 2018 à 22:40:56

            Ksass`Peuk a écrit:

            Je ne pense pas que distinguer variables et fonction soit vraiment intéressant, une fonction c'est juste une variable qu'on peut appliquer.

            o_O ?

            Ksass`Peuk a écrit:

            Reste sur des vectors. Le contexte en cours c'est .back(), et celui d'avant, c'est n-2, etc. Et quand ton bloc se termine, tu as juste à pop_back().

            Donc je n'ai pas besoin de sauvegarder tout les contextes ? Et c'est quoi n-2 ?

            Merci pour tout en tout cas, je comprend déjà mieux ;)

            -
            Edité par Geralt de Riv 12 novembre 2018 à 22:41:10

            • Partager sur Facebook
            • Partager sur Twitter
            Le doute est le commencement de la sagesse
              13 novembre 2018 à 8:23:17

              Geralt de Riv a écrit:

              Ksass`Peuk a écrit:

              Je ne pense pas que distinguer variables et fonction soit vraiment intéressant, une fonction c'est juste une variable qu'on peut appliquer.

              o_O ?

              let a = 42       // a: int
              let f b = b + 1  // f: int -> int
              let g c = c      // g: 'a -> 'a

              Et en général, on prendrait un type somme du genre :

              type typ = Int | Float | ... | TFun(typ * typ)

              Et du coup, une variable c'est juste un nom et un type avec une définition qui doit correspondre à ce type (définition qui devient juste une expression). Du coup, après, quand tu as :

              f 42

              Il faut juste que tu vérifies que f à un type TFun qui reçoit un Int comme premier paramètre (et qui peut potentiellement être à nouveau une fonction derrière, etc.

              Geralt de Riv a écrit:

              Donc je n'ai pas besoin de sauvegarder tout les contextes ? Et c'est quoi n-2 ?

              machin.size() - 2.

              -
              Edité par Ksass`Peuk 13 novembre 2018 à 8:46:49

              • Partager sur Facebook
              • Partager sur Twitter

              Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                13 novembre 2018 à 17:17:06

                Ok, je comprend mieux, merci :D

                Donc on a juste besoin de la définition de la fonction / variable (= nom et type), et non de son corps si je comprend bien ?

                Et est-ce la même chose pour les définitions de type, classes, enumerations, ... ?

                PS: Quel est le langage fonctionnel que tu as utilisé pour tes exemples ? Ca me fait penser à OCaml.

                -
                Edité par Geralt de Riv 13 novembre 2018 à 17:18:22

                • Partager sur Facebook
                • Partager sur Twitter
                Le doute est le commencement de la sagesse
                  13 novembre 2018 à 18:40:45

                  Geralt de Riv a écrit:

                  Donc on a juste besoin de la définition de la fonction / variable (= nom et type), et non de son corps si je comprend bien ?

                  Bah tu en auras besoin à un moment où un autre pour d'autre manipulation mais pour vérifier les types, tu n'as pas besoin de plus.

                  Geralt de Riv a écrit:

                  Et est-ce la même chose pour les définitions de type, classes, enumerations, ... ?

                  Plus précisément ?

                  Geralt de Riv a écrit:

                  PS: Quel est le langage fonctionnel que tu as utilisé pour tes exemples ? Ca me fait penser à OCaml.

                  C'est du Ocaml oui.

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                    13 novembre 2018 à 20:30:11

                    Ksass`Peuk a écrit:

                    Geralt de Riv a écrit:

                    Et est-ce la même chose pour les définitions de type, classes, enumerations, ... ?

                    Plus précisément ?

                    Et bien, par exemple :

                    using MyType = int;

                    Est-ce que l'on doit faire pareille pour la façon de sauvegarder les définitions types dans des scopes que les variables et des fonctions ?

                    Du style :

                    ThisType = { name: "MyType", realtype: "int" }

                    Même chose pour les classes et les énumérations.

                    A moins qu'il y ait une autre façon de faire ?

                    -
                    Edité par Geralt de Riv 13 novembre 2018 à 20:30:30

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Le doute est le commencement de la sagesse
                      14 novembre 2018 à 8:56:03

                      Perso, je ne vois pas de raison de distinguer vraiment type, classe et énumérations, par contre il va falloir les stocker effectivement.

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                        14 novembre 2018 à 15:45:45

                        D'accord, je vois.

                        Je reviens un peu sur les variables, est-ce que leur valeur doit aussi être sauvegardées pour le type-checking, ou simplement le type et le nom de celles-ci sont nécessaires ?

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Le doute est le commencement de la sagesse
                          14 novembre 2018 à 16:08:26

                          Non, tu n'as besoin que du type.

                          • Partager sur Facebook
                          • Partager sur Twitter

                          Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                            14 novembre 2018 à 16:20:13

                            Parfait, merci beaucoup :D

                            Je vais pouvoir avancer dans mon projet ;)

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Le doute est le commencement de la sagesse

                            Créer un type checker ou un analyseur de contexte

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown