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, 11, 12, 13, 14, 15, 16 ··· 18, 19, 20 Suivante
Lephenixnoir Hors ligne Administrateur Points: 24574 Défis: 170 Message

Citer : Posté le 09/06/2020 14:21 | #


Ah mais ça c'est faux !
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 09/06/2020 14:25 | #


Ah ? Pourtant je fait bien : a / (b/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 09/06/2020 14:31 | #


Ah mais non !
>>> 12/3/4
1.0

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 09/06/2020 14:34 | #


Donc la priorité c'est (a/b) / c

Il faut que je fasse un while j'y retourne ! o/

Ajouté le 09/06/2020 à 14:37 :
Du coup je décompose en multipliant par les inverses : a/b/c devient a * 1/b * 1/c
>>> compylateur("a/b/c")
--- Tokens ---
('VAR', 'a')
('DIVI', '/')
('VAR', 'b')
('DIVI', '/')
('VAR', 'c')


--- AST ---
Operation : *
  Variable : a
  Operation : 1/
    Variable : b
  Operation : 1/
    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 09/06/2020 14:40 | #


Pour ton information, si tu as un symbole binaire (disons •) et que tu poses a•b•...•z = ((a•b)•...z), alors le symbole est dit associatif de gauche-à-droite.

À l'inverse, si tu poses que a•b•...•z = a•(b•(...z)), alors le symbole est dit associatif de droite-à-gauche.

Par exemple, l'exposant est associatif de droite-à-gauche, donc a**b**c = a**(b**c). Tous les autres opérateurs binaires usuels sont associatifs de gauche-à-droite, ce qui est le plus courant. Dans un parser comme celui que tu écris, qu'on appelle "à descente récursive", il faut faire des boucles pour manipuler les opérateurs qui sont associatifs de gauche-à-droite.

Ajouté le 09/06/2020 à 14:40 :
Du coup je décompose en multipliant par les inverses : a/b/c devient a * 1/b * 1/c

Oui parfait ! C'est le bon résultat !
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 09/06/2020 14:44 | #


Okay ! Merci !!

Je pense m'arrêter là pour aujourd'hui prochaine étapes les comparaisons / conditions ? ou il reste encore de l'arithmétique ?
"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 09/06/2020 15:59 | #


À part le plus unaire qui est anecdotique, il manque surtout les appels de fonctions ! Qui sont un atome, donc sans trop spoiler je te laisse réfléchir à comment les ajouter.

Sinon oui, les conditions, ça se passera quasiment pareil. Je préfère parler d'"expressions booléennes" parce que tu vas voir qu'il y aussi des opérateurs binaires (et/ou), qu'ils ont des associativités (gauche-à-droite), un opérateur unaire (non), des parenthèses...
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 09/06/2020 16:02 | #


J'ai pas trop compris le coup des appels de fonctions…

Okay pour "expression bouléennes" !
"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 09/06/2020 17:44 | #


Les appels de fonctions c'est les trucs comme f(x) !
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 09/06/2020 17:50 | #


Ah oui ! Je les avaient oubliées x)
J'ai le droit de passer par une règle en plus ?
function_call -> VAR LPAR atome RPAR
"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 09/06/2020 17:57 | #


Tu as toujours le droit de rajouter des règles dans une grammaire !

function_call -> VAR LPAR atome RPAR

Nooon ! Tu es tombé dans le piège facile !

Réfléchis bien à ce que tu as le droit de mettre entre les parenthèses.
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 09/06/2020 17:59 | #


Ah ? x)

Bon ben faut réfléchir alors ?
Je peut mettre un nombre ou une variable, mais on peut bien imaginer mettre une expression arithmétique… ?
"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 09/06/2020 18:44 | #


Bien sûr qu'on peut imaginer une expression arithmétique ! Pourquoi limiter la forme de ce que tu peux mettre dans l'argument d'une fonction ?

C'est la spécialité du Basic Casio ça, tu as le droit d'écrire List 1 ou List N (avec N=1) mais tu ne peux pas écrire List (N+1). C'est chiant au possible !

Quand tu conçois ta grammaire, demande-toi toujours : quelle est la construction la plus générale que je peux autoriser ici ?
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 09/06/2020 19:50 | #


Justement ! Ici je pense que la construction la plus générale possible c'est atome
"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 09/06/2020 19:57 | #


Faux ! atome c'est tout petit. Comme je l'ai mentionné plusieurs fois, la construction la plus générale pour les expressions arithmétique c'est somme.

Pendant que j'y suis, tu devrais vraiment avoir un symbole arith_expr -> somme pour éviter de te poser la question à chaque fois et utiliser arith_expr à tous les endroits où tu peux mettre de l'arithmétique.
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 10/06/2020 13:41 | #


Ah oui ok ! Je comprends

Pour le coup de expr c'est juste une fonction : def expr(self): return self.sum() ?
"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 10/06/2020 13:47 | #


Du coup oui, il suffit de faire ça.

Prends bien le temps de comprendre pourquoi somme est le plus général ici. Regarde comment dériver 1*a depuis atome ou depuis somme, par exemple.
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 10/06/2020 13:59 | #


somme est plus général parce que j'ai cette hiérarchie : somme -> produit -> exposant -> atome (si j'ai compris ce que je programme ? 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 10/06/2020 14:05 | #


Voilà c'est ça ! Une somme peut facilement devenir n'importe quel autre symbole arithmétique, donc c'est forcément la plus générale. atome c'est pas aussi général parce que si tu veux écrire 1*a tu es obligé de mettre des parenthèses !
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 10/06/2020 14:07 | #


Du coup il me reste à implémenter la règle : function -> VAR LPAR expr RPAR !
"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 10/06/2020 14:16 | #


Et... n'oublie pas que les fonctions peuvent avoir plusieurs arguments !
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Précédente 1, 2, 3 ··· 10, 11, 12, 13, 14, 15, 16 ··· 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 146 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