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: 5503 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 ··· 13, 14, 15, 16, 17, 18, 19, 20 Suivante
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 19/06/2020 13:00 | #


Ah ok !
Donc pour les opérateurs logiques j'ai :
or -> and OR and
and -> not AND not
not -> comp_ega | NOT comp_ega

c'est ça ?

Pour la méthode general_comp j'ai ce code :
def general_comp(self):
        elmnt_1 = self.expr()
        comp = self.expect("SUP", "SUP_EGA", "INF", "INF_EGA")
        elmnt_2 = self.expr()
        return Node("Comparison", comp.type, elmnt_1, elmnt_2)


Edit : Finalement je me demande si c'est pas plus pratique d'avoir comme règle :
general_comp -> expr | expr (SUP | SUP_EGA | INF | INF_EGA) expr ? Comme ça, je peux simplifier la règle comp_ega en
comp_ega -> general_comp | general_comp (EGA | DIF) general_comp ?
"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 Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 19/06/2020 13:27 | #


Euh... non tu oublies un truc pour les opérateurs logiques ! Essaie d'écrire x == 2 OR y ≥ 3, tu verras tout de suite le problème.

Edit : Finalement je me demande si c'est pas plus pratique d'avoir comme règle :
general_comp -> expr | expr (SUP | SUP_EGA | INF | INF_EGA) expr ? Comme ça, je peux simplifier la règle comp_ega en
comp_ega -> general_comp | general_comp (EGA | DIF) general_comp ?

Tu peux mais oublies pas qu'il y a des questions de typage, tu peux pas écrire x+1 == (y ≤ 3).
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 19/06/2020 13:35 | #


Pour les opérateurs logiques, j'y reviendrais

Ajouté le 19/06/2020 à 13:37 :
Du coup je vais rester sur la première règle, mais j'ai du mal à voir comment intégrer les trois règles pour comp_ega ?
"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 Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 19/06/2020 13:39 | #


Ah effectivement ma version n'est pas prête pour passer à un parser LL. Ta version est bien, tu devrais l'utiliser : il faudra juste envisager de typer après l'analyse syntaxique ou à l'exécution.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 19/06/2020 13:57 | #


C'est quoi 'typer' ?

Ajouté le 19/06/2020 à 13:59 :
Sinon j'ai ce code :
def comparison(self):
        elmnt_1 = self.general_comp()
        if self.token_ahead.type not in ("EGA", "DIF"): return elmnt_1
        comp = self.expect()
        elmnt_2 = self.general_comp()
        return Node("Comparison", comp_type, elmnt_1, elmnt_2)
        
    def general_comp(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)

comparison est comp_ega
"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 Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 19/06/2020 14:14 | #


Typer c'est attribuer des types aux expressions... parce que tu peux pas comparer un entier et un booléen pour l'égalité même si tu peux tout à fait écrire n == b.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 19/06/2020 14:18 | #


Ah ok

J'ai fait quelques tests sur les comparaisons, ça marche bien je pense attaquer les conditions…
Du coup il faut que je gère l'absence d'opérateur logique sur les and et not… ? Ce qui ferait une grammaire comme ça :
or -> and OR and
and -> not | not AND not
not -> comparison | NOT comparison


Autant or et and en pseudo-code je vois comment l'écrire, autant not… ?

Ajouté le 19/06/2020 à 14:28 :
Du coup j'ai ces méthodes :
def cond_or(self):
        elmnt_1 = self.cond_and()
        if self.token_ahead.type != "OR": return elmnt_1
        self.expect()
        elmnt_2 = self.cond_and()
        return Node("Condition", "OR", elmnt_1, elmnt_2)

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

    def cond_not(self):
        if self.token_ahead.type != "NOT": return self.comparison()      
        self.expect()
        elmnt_1 = self.comparison()
        return Node("Conditon", "NOT", elmnt_1)

"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 Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 19/06/2020 14:46 | #


Du coup il faut que je gère l'absence d'opérateur logique sur les and et not… ?

Voilà c'est ça ! Une expression n'est pas obligée de contenir un opérateur de chaque niveau de priorité, il faut pouvoir sauter des étages. Tu devrais aussi avoir or -> and | and OR and et ensuite bool_expr -> or exactement comme pour somme et expr.

Le code a l'air bien
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 19/06/2020 14:51 | #


Okay, merci !
J'ai fait or -> and | and OR and. J'ai des résultats qui ont l'air pas mal :
>>> compylateur("a est égal à b et que a est égal à c")
--- Tokens ---
('VAR', 'a')
('EGA', 'est égal à')
('VAR', 'b')
('AND', 'et que')
('VAR', 'a')
('EGA', 'est égal à')
('VAR', 'c')


--- AST ---
Condition : AND
  Comparison : EGA
    Variable : a
    Variable : b
  Comparison : EGA
    Variable : a
    Variable : c

"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 Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 19/06/2020 15:21 | #


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

Citer : Posté le 19/06/2020 15:23 | #


Il me reste un problème à la con : je ne détecte pas le not dans le lexer parce que je ne sais pas comment il est noté en pesudo-code xD

Ajouté le 19/06/2020 à 17:27 :
À la limite est-ce qu'on peut ne pas mettre le not ?

Ajouté le 19/06/2020 à 17:42 :
J'ai une question : le symbole = est utilisé actuellement pour les comparaisons d'égalité. Est-ce que c'est envisageable d'avoir un token EQUAL qui pourrait servir aux assignements et aux comparaisons ? (la différence étant faite au niveau de 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 Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 19/06/2020 21:33 | #


Ta grammaire ne sera pas forcément ambiguë même si tu utilise = pour les deux usages, il te suffit d'interdire les expressions volantes (le genre qui va dans Ans en Basic Casio).
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 Message

Citer : Posté le 21/06/2020 08:11 | #


Pour moi la différence entre "=" pour l'assignement et "=" pour la comparaison devrait se résoudre dans l'AST. Le parseur sort un noeud "equal" et l'AST détermine que si ce noeud constitue une expression à part entière (en vérifiant le parent du noeud) alors c'est un assignement, sinon c'est une comparaison.
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 21/06/2020 17:35 | #


Hmm... je veux pas dire "non", mais personne ne fait ce genre de trucs, c'est du hack. Une grammaire bien écrite permet de lever l'ambiguité tout de suite. Si tu attends d'avoir ton AST pour lever l'ambiguité tu seras encore obligé de restructurer l'AST pour créer un noeud d'assignement après, autrement dit tu continues de parser après avoir finir de parser.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 22/06/2020 09:10 | #


il te suffit d'interdire les expressions volantes


Je suis pas sûr d'avoir compris ce que c'est… ?

Au niveau du lexer, je ne sais pas comment gérer les tokens comme Affecter à var la valeur 15 la variable est au milieu… je pensais renvoyer une liste de tokens comme ça :
('VAR', 'var')
('ASSI', 'Affecter à # la valeur')
('NUM', 15)

mais je ne vois pas comment le coder… ? x)

Et sinon au niveau de la grammaire, c'est quoi la prochaine étape ?
"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 Hors ligne Administrateur Points: 24574 Défis: 170 Message

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


Ah, les expressions volantes c'est... par exemple ça, en C :

int main(void)
{
    int x = 2;
    /* Expression volante, ne sert à rien */
    x+2;

    return 0;
}

Si tu autorises ce genre de trucs alors il y a une ambiguité quand tu écris x=4 entre assignment et expression booléenne volante. Si tu les interdis alors y'a pas de problème et c'est pas ambigu.

Au niveau du lexer, je ne sais pas comment gérer les tokens comme Affecter à var la valeur 15 la variable est au milieu… je pensais renvoyer une liste de tokens comme ça :

En toute rigueur tu devrais avoir un regex :

Affecter à ([a-zA-Z_][a-zA-Z_0-9]*) la valeur

de laquelle tu émets soit deux tokens comme tu avais imaginé, soit un seul token ASSIGN(<la variable>). C'est là que ton lexer montre un peu ses limites.

Au niveau de la grammaire, la prochaine étape c'est des statements... et des tests unitaires !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 22/06/2020 15:33 | #


Ah ok… Je pense que je commence à comprendre… x) Mais comment je les autorise ou pas… ?

Je ne sais comment faire des regex… ? C'est possible de refaire le lexer ?

Pour les statement, je vais y aller doucement, c'est du chinois pour l'instant… xD
"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 Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 22/06/2020 15:35 | #


Tu les autorises si dans ta grammaire il y a une règle qui permet de construire un statement à partir d'une expressions toute seule... et tu les interdis s'il n'y en a pas ! C'est aussi simple que ça.

C'est possible de refaire le lexer, après ça dépend si tu veux absolument le faire toi-même ou si tu es prêt à le générer. Tu peux faire un lexer à regex potable à la main (assez technique) mais ce sera jamais aussi propre et performant que le super-automate que te donnent les générateurs.

Les statements tu sais c'est les assignments, les if/else, les boucles, les return, tout ça.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 22/06/2020 15:40 | #


Ben refaire le lexer m'enchante pas… mais si je le repense pas comment je peux gérer les affectations Affecter à … la valeur ?

Ah ok je savais que ça s'appelle comme ça !
"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 Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 22/06/2020 15:43 | #


Bah le plus simple c'est de faire un token pour "Affecter à" et un pour "la valeur" et ensuite tu te fais une règle de grammaire :

assignment -> AFFECTER_A VAR LA_VALEUR expr

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Shadow15510 Hors ligne Administrateur Points: 5503 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

Précédente 1, 2, 3 ··· 10 ··· 13, 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 144 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