Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Compylateur
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Compylateur

Posté le 08/05/2020 14:00

Bonjour à tous !

Il y a quelques temps j'ai fait un 'compilateur' qui permet d'exécuter un algorithme en langage naturel en le 'traduisant' en Python. Le code est atroce et repose sur un remplacement entre les commandes en langage naturel et les commandes en Python (à coup de dictionnaires et de tests conditionnels )… J'aimerais faire de ce projet un 'vrai' compilateur (on reste sur du Python ). Et j'ai quelques questions :

- La phase d'analyse lexicale repose pour l'instant sur une recherche et un replacement, avec un dictionnaire qui contient en clés les commandes en langage naturel, et en items, les commandes correspondantes en Python… Je me doute que ce n'est pas pertinent… En fait l'analyse lexicale est mélangée à la phase d'analyse syntaxique.

- Comment faire pour basculer du langage naturel au Python ? Faut-il forcément passer par un hard code, ou est-ce que d'autre technique plus esthétiques existent ?

- L'analyse syntaxique est un bête replace basé sur un dico… Du coup ça revient à la question précédente : comment éviter le hard code ?

- La phase sémantique… Je ne suis pas sûr d'avoir bien compris toutes les subtilités… Dans mon cas, après le remplacement bête et méchant, la syntaxe Python n'est pas bonne, du coup je passe à travers différents tests conditionnels pour avoir un 'vrai' script fonctionnel… Encore une fois le hard code à coup de if me plaît moyen…

- En derniers je refait un passage sur mon code généré et j'ajoute les alinéas. Est-ce que je devrais les gérer plus tôt (je pense à la phase d'analyse syntaxique… mais le placement des alinéas dépend du contexte du code, et sur une ligne donnée je vois pas trop comment faire…

Merci d'avance !


Précédente 1, 2, 3 ··· 10 ··· 14, 15, 16, 17, 18, 19, 20 Suivante
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 22/06/2020 16:08 | #


C'pas bête !

Ajouté le 24/06/2020 à 13:48 :
Du coup tu me conseille de commencer par quel statement ?
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 24/06/2020 13:49 | #


Il se ressemblent pas mal mais en gros tu dois définir de quoi assigner des variables et afficher des résultats. Après tu peux jouer à faire des blocs (if/else/etc) qui fonctionnent tous pareil.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 24/06/2020 13:56 | #


Ok… bon ben go pour l'assignement de variable

Dans ma tête je vois ça comme ça : on a deux types d'assignement :
- assignement 'direct' : a = 2
- assignement par l'utilisateur : a = input()

Et autre difficulté : la multitude de manière d'assigner… Du coup je pense commencer par rajouter les tokens…

Ajouté le 24/06/2020 à 14:16 :
Je suis en train de lister les différentes manières d'assigner :
… prend la valeur …
affecter à … la valeur…
… est initialisé à …
demander la valeur de … à l'utilisateur
on demande la valeur de … à l'utilisateur
saisir …
… = …

Il y en a d'autre ?

Edit :
J'ai rajouté ces tokens :
"affecter à":"AFFECT"
"prend la valeur":"TAKE"
"est initialisé à":"TAKE"
"demander la valeur de":"REQUEST"
"on demande la valeur de":"REQUEST"
"saisir":"REQUEST"
"à l'utilisateur":"USER"
"la valeur":"VALUE"


Ajouté le 24/06/2020 à 14:33 :
Du coup j'aurais une règle pour les assignement :
assignement -> AFFECT VAR VALUE expr | VAR TAKE expr | REQUEST VAR (USER)
USER est facultatif
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 24/06/2020 14:34 | #


Ça a l'air pas mal. Le facultatif est souvent noté avec un ?, par exemple "USER?" (pour ton information).
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 24/06/2020 14:37 | #


Ah ok, je savais pas bon ben du coup je vais tenter un premier jet de code
Pour l'instant le symbole = est associé au token EQUAL qui n'est utilisé nulle part, je ne sais pas comment l'utiliser ^^' l'idéal serait d'avoir l'assignement et la comparaison dessus, mais je ne sais pas comment éviter les expressions flottantes… ?

Ajouté le 24/06/2020 à 14:48 :
J'ai ça :
# --- Assignement's rules --- #

    def assignement(self):
        value = None
        if self.token_ahead.type == "AFFECT"
            self.expect()
            var = self.expect("VAR")
            self.expect("VALUE")
            value = self.expr()
        elif self.token_ahead.type == "REQUEST":
            self.expect()
            var = self.expect("VAR")
            if self.token_ahead.type == "USER": self.expect()
        elif self.token_ahead.type("VAR"):
            var = self.expect()
            self.expect("TAKE")
            value = self.expr()
        if value: return Node("Assignement", "direct", var.value, expr)
        else: return Node("Assignement", "user", var.value)

"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 24/06/2020 14:58 | #


Pour l'instant le symbole = est associé au token EQUAL qui n'est utilisé nulle part, je ne sais pas comment l'utiliser ^^' l'idéal serait d'avoir l'assignement et la comparaison dessus, mais je ne sais pas comment éviter les expressions flottantes… ?

Tu n'as que ce que tu autorises explicitement.

statement -> assignment # rien d'autre pour l'instant
assignment -> ... | VAR EQUAL expr # comme tout à l'heure

Tant que tu as pas statement -> expr, il ne sera pas possible d'avoir d'expression flottante.

Ton code a l'air pas mal, ça implémente bien la grammaire que tu as décrite. Bravo ! Tu commences à avoir les bons réflexes des parsers à descente récursive.

Tu devrais sans doute faire deux noeuds différents, assigner et demander une valeur à l'utilisateur sont des choses assez éloignées.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 24/06/2020 15:02 | #


Merci !

Okay je commence à comprendre un peu les mécaniques aussi… Mon code est buggé pour l'instant… donc faut que je le revoie xD

Le problème est comment différencier a = 2 où j'assigne 2 à a et a = 2 ou je teste si a est égal à 2… ?

Ajouté le 24/06/2020 à 15:08 :
C'est bon !

J'ai ce code :

# --- Assignement's rules --- #

    def assignement(self):
        value = None
        if self.token_ahead.type == "AFFECT":
            self.expect()
            var = self.expect("VAR")
            self.expect("VALUE")
            value = self.expr()
        elif self.token_ahead.type == "REQUEST":
            self.expect()
            var = self.expect("VAR")
            if self.token_ahead.type == "USER": self.expect()
        elif self.token_ahead.type == "VAR":
            var = self.expect()
            self.expect("TAKE")
            value = self.expr()
        if value: return Node("Assignement","", Node("Variable",var.value), value)
        else: return Node("User's request", "", Node("Variable", var.value))


Et ce résultat :
>>> compylateur("affecter à minimum la valeur min(f(a+2))")
--- Tokens ---
('AFFECT', 'affecter à')
('VAR', 'minimum')
('VALUE', 'la valeur')
('VAR', 'min')
('LPAR', '(')
('VAR', 'f')
('LPAR', '(')
('VAR', 'a')
('PLUS', '+')
('NUM', 2)
('RPAR', ')')
('RPAR', ')')


--- AST ---
Assignement :
    Variable : minimum
    Function : min
        Function : f
            Operation : +
                Variable : a
                Number : 2


Ajouté le 27/06/2020 à 16:34 :
Du coup je vais commencer à implémenter les if et dérivées… (si, alors, sinon) Juste un petit problème : cibler les actions qui sont exécutées dans le bloc conditionnel… ?

Pour la condition je pense à une grammaire : si -> IF condition

Edit : Finalement une syntaxe plus comme ça : si -> IF condition *(THEN ?) me parait mieux plusieurs THEN parce que alors et faire sont tous les deux géré comme des THEN et que la construction si … alors faire … est à peu près correcte… Par contre on peut aussi dire : si … alors, … du coup il faut gérer les virgules… ?
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 27/06/2020 16:43 | #


Tu dois utiliser la structure récursive des blocs ici. Essaie de voir si tu comprends la grammaire ci-dessous :

# Un bloc est une liste de statements (* veut dire 0 ou plus)
block -> statement*
statement -> assignment | statement_if | statement_for | statement_etc
assignment -> # comme avant
statement_if -> IF condition THEN block (ELIF condition THEN block)* (ELSE block)? END

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 27/06/2020 16:47 | #


Alors… je pense voir dans l'ensemble…

block est un bloc d'instructions.
statement est une instruction : assignement, condition, boucle itérative, boucle conditionnelle, affichage.
assigment on a déjà vu.
statement_if test conditionnel qui permet de contenir d'autre tests conditionnels grâce à la chaîne block -> statement -> statement_if
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 27/06/2020 16:53 | #


C'est à peu près ça. statement_if ne permet pas spécifquement de "contenir d'autre tests conditionnels". Il peut contenir n'importe quel code, y compris des mélanges de boucles, conditions, calculs, I/O, etc.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 27/06/2020 17:11 | #


Yep okay…

Du coup j'implémente cette grammaire (enfin… j'essaye ) et je reviens

Ajouté le 27/06/2020 à 17:37 :
J'ai déjà quelques problèmes… je ne gère pas les conditions correctement… par exemple a est égal à b n'est pas détecté comme une condition… xD

Ajouté le 27/06/2020 à 17:48 :
Alors !

J'ai ce résultat (qui m'a l'air bon ) :
>>> compylateur("si a est égal à b alors a prend la valeur b-1")
--- Tokens ---
('IF', 'si')
('VAR', 'a')
('EGA', 'est égal à')
('VAR', 'b')
('THEN', 'alors')
('VAR', 'a')
('TAKE', 'prend la valeur')
('VAR', 'b')
('MINUS', '-')
('NUM', 1)


--- AST ---
Statement : if
    Comparison : EGA
        Variable : a
        Variable : b
    Assignement :
        Variable : a
        Operation : +
            Variable : b
            Operation : -
                Number : 1


Avec ce code :
# --- Comparison and Condition's rules --- #
    
    def condition(self): return self.condition_or()

    def condition_or(self):
        elmnt_1 = self.condition_and()
        if self.token_ahead.type != "OR": return elmnt_1
        self.expect()
        elmnt_2 = self.condition_and()
        return Node("Condition", "OR", elmnt_1, elmnt_2)

    def condition_and(self):
        elmnt_1 = self.comparison_1()
        if self.token_ahead.type != "AND": return elmnt_1
        self.expect()
        elmnt_2 = self.comparison_1()
        return Node("Condition", "AND", elmnt_1, elmnt_2)

    def comparison_1(self):
        elmnt_1 = self.comparison_2()
        if self.token_ahead.type not in ("EGA", "DIF"): return elmnt_1
        comp = self.expect()
        elmnt_2 = self.comparison_2()
        return Node("Comparison", comp.type, elmnt_1, elmnt_2)
        
    def comparison_2(self):
        elmnt_1 = self.expr()
        if self.token_ahead.type not in ("SUP", "SUP_EGA", "INF", "INF_EGA"): return elmnt_1
        comp = self.expect()
        elmnt_2 = self.expr()
        return Node("Comparison", comp.type, elmnt_1, elmnt_2)

    # --- Statements's rules --- #

    def block(self): return self.statement()
        
    
    def statement(self):
        return self.assignement()

    def assignement(self):
        value = None
        if self.token_ahead.type == "AFFECT":
            self.expect()
            var = self.expect("VAR")
            self.expect("VALUE")
            value = self.expr()
        elif self.token_ahead.type == "REQUEST":
            self.expect()
            var = self.expect("VAR")
            if self.token_ahead.type == "USER": self.expect()
        elif self.token_ahead.type == "VAR":
            var = self.expect()
            self.expect("TAKE")
            value = self.expr()
        if value: return Node("Assignement","", Node("Variable",var.value), value)
        else: return Node("User's request", "", Node("Variable", var.value))

    def statement_if(self):
        self.expect("IF")
        cond_1 = self.condition()
        self.expect("THEN")
        block_1 = self.block()
        ast = Node("Statement", "if", cond_1, block_1)
        while self.token_ahead.type in ("ELIF", "ELSE"):
            type_if = self.expect()
            if type_if.type == "ELIF":
                cond_2 = self.condition()
                self.expect("THEN")
                block_2 = self.block()
                ast.add_node(Node("Statement", "elif", cond_2, block_2))
            else:
                block_2 = self.block()
                ast.add_node(Node("Statement", "else", block_2))
        return ast
            


J'aurais deux-trois questions :
- Comment détecter la présence d'un statement ? (pour block)
- Comment différencier les statements ? (pour statement)
- Est-ce que si, alors, sinon, si, sinon (pour les tokens respectifs : IF THEN ELIF ELSE c'est bon où est-ce qu'il faut prévoir plus de cas ?)
- Comment on fait pour connaitre la portée des tests conditionnels ? (et par la même occasion, on peut élargir aux autres boucles, voire même aux déclarations de fonctions )
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 27/06/2020 17:58 | #


- Comment détecter la présence d'un statement ? (pour block)
- Comment différencier les statements ? (pour statement)

Avec le lookahead.

- Est-ce que si, alors, sinon, si, sinon (pour les tokens respectifs : IF THEN ELIF ELSE c'est bon où est-ce qu'il faut prévoir plus de cas ?)

Ça c'est toi qui vois ! N'oublie pas que tu as aussi besoin d'une forme de END ou ENDIF sinon tu ne pourras pas parser (la grammaire sera ambigue).

- Comment on fait pour connaitre la portée des tests conditionnels ? (et par la même occasion, on peut élargir aux autres boucles, voire même aux déclarations de fonctions )

Quelle portée ?
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 27/06/2020 18:03 | #


Avec le lookahead.

Ah ben oui… x)

Ça c'est toi qui vois ! N'oublie pas que tu as aussi besoin d'une forme de END ou ENDIF sinon tu ne pourras pas parser (la grammaire sera ambigue).

C'est possible de rajouter des règles par la suite… je pense faire une version light avec moins de cas gérés. Justement la portée c'est l'absence de END qui m'a coincé xDD mais d'un autre côté je dois le mettre comment ? Tout à la fin de statement_if je rajoute une ligne : self.expect("END") ?
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 27/06/2020 18:05 | #


Tout à la fin de statement_if je rajoute une ligne : self.expect("END") ?

Voilà c'est ça ! Facile
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 27/06/2020 18:11 | #


Okay okay… du coup j'ai ce code
# --- Statements's rules --- #

    def block(self):
        ast = Node("Block", "")
        while self.oken_ahead.type in ("AFFECT," "REQUEST", "VAR", "IF"): ast.add_node(self.statement())
        return ast
        
    
    def statement(self):
        if self.token_ahead.type in ("AFFECT", "REQUEST", "VAR"): return self.assignement()
        elif self.token_ahead.type == "IF": return self.statement_if()

    def assignement(self):
        value = None
        if self.token_ahead.type == "AFFECT":
            self.expect()
            var = self.expect("VAR")
            self.expect("VALUE")
            value = self.expr()
        elif self.token_ahead.type == "REQUEST":
            self.expect()
            var = self.expect("VAR")
            if self.token_ahead.type == "USER": self.expect()
        elif self.token_ahead.type == "VAR":
            var = self.expect()
            self.expect("TAKE")
            value = self.expr()
        if value: return Node("Assignement","", Node("Variable",var.value), value)
        else: return Node("User's request", "", Node("Variable", var.value))

    def statement_if(self):
        self.expect("IF")
        cond_1 = self.condition()
        self.expect("THEN")
        block_1 = self.block()
        ast = Node("Statement", "if", cond_1, block_1)
        while self.token_ahead.type in ("ELIF", "ELSE"):
            type_if = self.expect()
            if type_if.type == "ELIF":
                cond_2 = self.condition()
                self.expect("THEN")
                block_2 = self.block()
                ast.add_node(Node("Statement", "elif", cond_2, block_2))
            else:
                block_2 = self.block()
                ast.add_node(Node("Statement", "else", block_2))
        self.expect("END")
        return ast


Ajouté le 27/06/2020 à 18:19 :
Du coup je vais passer aux boucles itératives

J'ai pensé à cette grammaire : statement_for -> FOR VAR INTER_ST (VAR | NUM) INTER_ED (VAR | NUM) block END
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 27/06/2020 18:29 | #


Ça a l'air pas mal, tu n'auras pas d'ambiguités.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 27/06/2020 18:30 | #


Ok, merci

Ajouté le 28/06/2020 à 14:10 :
J'ai codé les boucles itératives… j'ai ce résultat :
>>> compylateur("Pour i allant de 0 à 3, a prend la valeur i^2 fin Pour")
--- Tokens ---
('FOR', 'pour')
('VAR', 'i')
('INTER_ST', 'allant de')
('NUM', 0)
('INTER_ED', 'à')
('NUM', 3)
('COMMA', ',')
('VAR', 'a')
('TAKE', 'prend la valeur')
('VAR', 'i')
('EXP', '^')
('NUM', 2)
('END', 'fin')
('FOR', 'pour')


--- AST ---
Statement : for
    Incremented variable : i
    Start value : 0
    End value : 3
    Block :
        Assignement :
            Variable : a
            Operation : ^
                Variable : i
                Number : 2


Avec ce code :
# --- Statements's rules --- #

    def block(self):
        ast = Node("Block", "")
        while self.token_ahead.type in ("AFFECT," "REQUEST", "VAR", "IF", "FOR"): ast.add_node(self.statement())
        return ast
        
    
    def statement(self):
        if self.token_ahead.type in ("AFFECT", "REQUEST", "VAR"): return self.assignement()
        elif self.token_ahead.type == "IF": return self.statement_if()
        elif self.token_ahead.type == "FOR": return statement_for()

    def assignement(self):
        value = None
        if self.token_ahead.type == "AFFECT":
            self.expect()
            var = self.expect("VAR")
            self.expect("VALUE")
            value = self.expr()
        elif self.token_ahead.type == "REQUEST":
            self.expect()
            var = self.expect("VAR")
            if self.token_ahead.type == "USER": self.expect()
        elif self.token_ahead.type == "VAR":
            var = self.expect()
            self.expect("TAKE")
            value = self.expr()
        if value: return Node("Assignement","", Node("Variable",var.value), value)
        else: return Node("User's request", "", Node("Variable", var.value))

    def statement_if(self):
        self.expect("IF")
        cond_1 = self.condition()
        self.expect("THEN", "COMMA", "DO")
        block_1 = self.block()
        ast = Node("Statement", "if", cond_1, block_1)
        while self.token_ahead.type in ("ELIF", "ELSE"):
            type_if = self.expect()
            if type_if.type == "ELIF":
                cond_2 = self.condition()
                self.expect("THEN", "COMMA", "DO")
                block_2 = self.block()
                ast.add_node(Node("Statement", "elif", cond_2, block_2))
            else:
                block_2 = self.block()
                ast.add_node(Node("Statement", "else", block_2))
        self.expect("END")
        return ast

    def statement_for(self):
        self.expect("FOR")
        it_var = self.expect("VAR")
        self.expect("INTER_ST")
        start_value = self.expr()
        self.expect("INTER_ED")
        end_value = self.expr()
        self.expect("COMMA", "DO")
        ast = Node("Statement", "for", Node("Incremented variable", it_var.value), Node("Start value", start_value.value), Node("End value", end_value.value))
        ast.add_node(self.block())
        self.expect("END")
        return ast


Je sais pas trop comment faire l'AST pour avoir les infos sur la variable incrémentée… ? Ça me parait bancal de faire des nodes pour ça…

Edit : Autre problème que j'ai pas encore soulevé : les lignes ? Pour l'instant quand je suis sur une seule ligne c'est bon, mais à aucun moment les lignes ne sont gérées… x)
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 28/06/2020 14:39 | #


Je sais pas trop comment faire l'AST pour avoir les infos sur la variable incrémentée… ? Ça me parait bancal de faire des nodes pour ça…

Quelles infos tu veux ? Tu as le nom, ça suffit non ?

Edit : Autre problème que j'ai pas encore soulevé : les lignes ? Pour l'instant quand je suis sur une seule ligne c'est bon, mais à aucun moment les lignes ne sont gérées… x)

Il suffit d'ignorer les \n dans le lexer. Si tu veux les compter il faut s'investir un peu plus.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 28/06/2020 14:45 | #


Le nom ne suffit pas, les bornes sont utiles aussi

J'ai rien dit pour les lignes ça marche effectivement… xD

Du coup j'ai une question avant de faire les while
- Les blocks sont des blocs de statement, en sortie j'ai ça comme AST :
Block :
    Assignement :
        Variable : a
        Operation : +
            Variable : a
            Number : 1
    Assignement :
        Variable : i
        Operation : *
            Variable : a
            Operation : 1/
                Number : 2

Est-ce que c'est bon ?

Merci d'avance

Ajouté le 28/06/2020 à 15:11 :
Bon… j'ai commencé à faire des trucs de plus en plus sérieux, j'arrive maintenant à faire passer des codes avec plusieurs instructions :
>>> compylateur("Tant que a est inférieur à 5, a prend la valeur a + 1 afficher a fin tantque")
--- Tokens ---
('WHILE', 'tant que')
('VAR', 'a')
('INF', 'est inférieur à')
('NUM', 5)
('COMMA', ',')
('VAR', 'a')
('TAKE', 'prend la valeur')
('VAR', 'a')
('PLUS', '+')
('NUM', 1)
('DISPLAY', 'afficher')
('VAR', 'a')
('END_WHILE', 'fin tantque')


--- AST ---
Statement : while
    Comparison : INF
        Variable : a
        Number : 5
    Block :
        Assignement :
            Variable : a
            Operation : +
                Variable : a
                Number : 1
        Display : a


Ajouté le 28/06/2020 à 18:45 :
J'ai quelques problème :
- Comment amorcer le parser ? (j'appelle quelle règle ? J'ai pensé à block, mais la création d'un node qui ne sert à rien est dérangeant…)
- Comment gérer l'affichage proprement ? (Est-ce qu'il faut faire une règle de grammaire en plus ?)
- Où en est au niveau de l'analyse syntaxique ? (Et si on approche de la fin, à quoi sert l'analyse sémantique ? )
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Lephenixnoir En ligne Administrateur Points: 24673 Défis: 170 Message

Citer : Posté le 28/06/2020 18:52 | #


- Comment amorcer le parser ? (j'appelle quelle règle ? J'ai pensé à block, mais la création d'un node qui ne sert à rien est dérangeant…)

Oui pour l'instant c'est block. Il n'y aucun noeud qui ne serve à rien dans l'histoire !

- Comment gérer l'affichage proprement ? (Est-ce qu'il faut faire une règle de grammaire en plus ?)

L'affichage de quoi ?

- Où en est au niveau de l'analyse syntaxique ? (Et si on approche de la fin, à quoi sert l'analyse sémantique ? )

On arrive à la fin pour avoir une base sympa. L'analyse sémantique sert principalement à typer, histoire de rejeter les constructions stupides comme 2+f quand f est une fonction.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5504 Défis: 18 Message

Citer : Posté le 28/06/2020 18:54 | #


Ah ok, donc l'AST :
--- AST ---
Statement : while
    Comparison : INF
        Variable : a
        Number : 5
    Block :
        Assignement :
            Variable : a
            Operation : +
                Variable : a
                Number : 1
        Display : a

le nœud Block :… ? Fin je pensais qu'on pouvais en enlever un

Je pense à l'affichage du texte, Afficher "A = ", a

Okay ! Ça avance !
"Ce n'est pas parce que les chose sont dures que nous ne les faisons pas, c'est parce que nous ne les faisons pas qu'elles sont dures." Sénèque

Précédente 1, 2, 3 ··· 10 ··· 14, 15, 16, 17, 18, 19, 20 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 168 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd