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, 4, 5 ··· 10 ··· 18, 19, 20 Suivante
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 10/05/2020 17:46 | #


Mais la liste de token ne peut pas seule suffire… Comment je sais quelle variable à quel nom ? Comment je peux afficher du texte ?

Concrètement mon lexer doit associer à chaque mot du code source un token… ? Mais pour le nom des variables par exemple ?

@Zez : Ouaip, c'est pas bête comme idée, d'autant plus qu'à ce niveau les mots sont assez répétitifs
"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: 24575 Défis: 170 Message

Citer : Posté le 10/05/2020 17:49 | #


Shadow15510 a écrit :
Mais la liste de token ne peut pas seule suffire… Comment je sais quelle variable à quel nom ? Comment je peux afficher du texte ?

Oui ben ça c'est l'analyse syntaxique et l'analyse sémantique. Chaque chose en son temps.

Concrètement mon lexer doit associer à chaque mot du code source un token… ? Mais pour le nom des variables par exemple ?

Dans ton cas, contrairement aux langages de programmation habituels, tu peux difficilement distinguer un nom de variable d'un autre mot. Il faut donc deviner selon le contexte. Et ça, le parser sait faire. En fait, seul le parser sait le faire correctement.
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/05/2020 17:55 | #


Oui… mais si l'analyse syntaxique se base uniquement sur les tokens… et que j'ai une perte d'info énorme entre le code source et mes tokens… ? J'arrive pas à voir comment trouver le moyen de sauver toutes les infos…

Par exemple si j'ai a prend la valeur 0, afficher a
avec mes tokens j'obtiens au mieux :
TOKEN(VAR)
TOKEN(AFFECT)
TOKEN(VALEUR)
TOKEN(N_LIGNE)
TOKEN(AFFICH)
TOKEN(VAR)

Mais sans savoir à quoi correspond TOKEN(VAR) et TOKEN(VALUE)… ? Vu que le parser ne prend que les tokens… ?
"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: 24575 Défis: 170 Message

Citer : Posté le 10/05/2020 17:59 | #


Un token peut avoir des données attachées. En sortie de ton lexer, tu pourrais avoir un truc aussi peu analysé que ça (si tu veux faire la version propre avec verbe/sujet/complément/etc) :

TOKEN(MOT, "a")
TOKEN(VERBE, "prendre", PRÉSENT, 3)
TOKEN(PRÉPOSITION, "la")
TOKEN(NOM, "valeur")
TOKEN(ENTIER, 0)
TOKEN(VIRGULE)
TOKEN(VERBE, "afficher", INFINITIF)
TOKEN(MOT, "a")

Bon ce serait un peu long par cette route-là mais tu vois l'idée je pense. Et oui j'ai arrondi les angles, "a" serait peut-être perçu comme la conjugaison du verbe avoir, ce qui complique un peu le truc.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 10/05/2020 18:01 | #


Heum désolé de vous embêter a cause de mon niveau mais qu'est-ce qu'un "TOKEN" ?
Kikoodx Hors ligne Ancien labélisateur Points: 3039 Défis: 11 Message

Citer : Posté le 10/05/2020 18:03 | #


Lephé' l'avait expliqué dans un message sur le topic de BBC (pas la chaîne)
https://www.planet-casio.com/Fr/forums/topic16286-1-better-basic-casio-un-langage-intermediaire-pour-le-peuple.html#175772
ouais ouais
Lephenixnoir En ligne Administrateur Points: 24575 Défis: 170 Message

Citer : Posté le 10/05/2020 18:03 | #


C'est un "mot" du langage, essentiellement.
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 10/05/2020 18:03 | #


Limite je partirais sur :
["a", "prend la valeur", "0", ",", "afficher", "a"]
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Shadow15510 Hors ligne Administrateur Points: 5503 Défis: 18 Message

Citer : Posté le 10/05/2020 18:05 | #


Donc il est impératif que mon lexer sache comment est foutue la phrase…

Mais du coup en quoi ça diffère de ma version… ? Sinon qu'elle est encore moins analysée… ?

Connaitre la conjugaison des verbes ça va être délicat…

@Disperseur : un token est un jeton qui est associé à chaque mot du programme par le 'lexer' (l'algo qui effectue l'analyse lexicale). Cela permet d'avoir la structure du programme

@Zez : C'est pas bête, mais c'est encore plus basique… et ça ne m'avance pas à grand chose… ?
"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: 24575 Défis: 170 Message

Citer : Posté le 10/05/2020 18:07 | #


Donc il est impératif que mon lexer sache comment est foutue la phrase…

Non, un lexer ne fait que comprendre les mots, il ne doit pas comprendre les phrases. Quand je dis "verbe", c'est que le mot est lexicalement un verbe (quand tu le regardes tout seul), pas son rôle dans la phrase. C'est le genre d'un mot, pas son rôle dans la phrase. C'est le parser qui comprend la phrase.

La différence avec ta version, c'est que l'analyse elle part dans la grammaire du parser, et donc elle est faite correctement.
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/05/2020 18:11 | #


Okay, du coup mon code est pas trop mauvais, pour un parser… ?

Et pour le lexer, savoir si le mot est un verbe et pourvoir remonter jusqu'à l'infinitif… c'est hard… x) Perso, je vois pas comment faire, j'ai une envie de tout hard coder, mais à ce rythme, Odyssée sera fini avant…

Ajouté le 10/05/2020 à 18:17 :
Ou alors il faut cibler tout les verbes susceptibles d'apparaitre…
"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: 24575 Défis: 170 Message

Citer : Posté le 10/05/2020 18:19 | #


Ton code mélange un peu le lexer et le parser, et puisque c'est ta première fois, y'a peu de chances que ça passe à l'échelle quand tu vas vouloir enrichir ta syntaxe. ^^"

T'es pas obligé de prendre la route chiante avec la conjugaison et tout le bordel. Tu peux hardcoder. Mais tu verras vite que tu ne programmeras pas en langage naturel, tu programmeras dans un langage de programmation classique dans lequel les mots-clés et la ponctuation seront remplacés par des mots français, des lieurs et des prépositions.
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/05/2020 18:23 | #


Okay…

Ben disons que je voudrais m'approcher du langage naturel par exemple mon premier code (déguelasse) marche avec 95% des algos de mon bouquin de math (en recopiant bêtement l'algo)… Donc forcément ça reste un peu restrictif et il faut être rigoureux, mais je pense que compiler le langage naturel, c'est pas possible x)

J'aimerais savoir si c'est possible de ne pas hardcoder, tout en n'utilisant que mon propre code… ? (donc un truc à peu près à mon niveau quoi x) )

Pour reprendre la liste de Zez, comment je sais qu'après le prend, il faut encore prendre deux mots, jusqu'à valeur… ?
"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: 24575 Défis: 170 Message

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


Le lexique français est immense, supporter cette richesse aura forcément un prix. De même, la grammaire est immense et ambiguë, et supporter ça aura un prix. À toi de voir à quel distance tu veux aller sur ces deux axes.

J'aimerais savoir si c'est possible de ne pas hardcoder, tout en n'utilisant que mon propre code… ? (donc un truc à peu près à mon niveau quoi x) )

Tu peux faire des choses intéressantes sur la grammaire avec un parser correct (et tu ne peux pas l'écrire la main), mais sur le lexique tu vas sans doute galérer parce que la sémantique de chaque mot est difficile à représenter.

Pour reprendre la liste de Zez, comment je sais qu'après le prend, il faut encore prendre deux mots, jusqu'à valeur… ?

Le parser. Ta grammaire peut par exemple dire :
assignment :=
  VAR prend la valeur VALEUR
| assigner VALEUR à VAR
| stocker VALEUR dans VAR

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 10/05/2020 18:27 | #


Quand je dis "verbe", c'est que le mot est lexicalement un verbe (quand tu le regardes tout seul), pas son rôle dans la phrase.


C'est impossible ça, par exemple "si a a la valeur 3", comment tu sais qui est la variable et qui est le verbe

Ou alors il faut cibler tout les verbes susceptibles d'apparaitre…


Dans tous les cas il faudra faire ça, tu peux pas parser un langage sans en avoir une spécification claire.

Et du coup ton tokenizeur devra être dépendant du contexte. Par exemple dans "si a a la valeur 3":

- Il voit le token "si", du coup il sait que c'est une condition, il attend une variable.
- Il prend comme token le prochain mot (une variable ne pouvant pas avoir d'espace). Du coup il a le token "a". Optionnellement il affecte un type "variable" à ce token (et un type "condition_begin" au token "si"), à voir si c'est pas plutôt le job du parseur.
- La grammaire du langage spécifie qu'après une variable dans une condition, il doit y avoir un des opérateurs "a la valeur", "est égal à", "n'est pas égal à", etc. Du coup le tokenizeur regarde si un de ces opérateurs est présent, c'est le cas alors il ajoute un token "a la valeur".


Cette approche va être chaude dans certains cas, par exemple si "est égal à" et "égal à" sont possibles, alors il faut bien que le tokenizeur reconnaisse la variable "est" dans "si a + est égal à 3". Ou alors tu blackliste certains noms de variables comme le font la plupart des langages.

Je pense qu'avant de progresser il faudrait déjà définir une spécification du "langage naturel", avec beaucoup d'exemples et de cas spéciaux, et après seulement on pourra faire l'architecture du compilateur.
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Lephenixnoir En ligne Administrateur Points: 24575 Défis: 170 Message

Citer : Posté le 10/05/2020 18:31 | #


Zezombye a écrit :
C'est impossible ça, par exemple "si a a la valeur 3", comment tu sais qui est la variable et qui est le verbe

Auto-citation :
Lephenixnoir a écrit :
Et oui j'ai arrondi les angles, "a" serait peut-être perçu comme la conjugaison du verbe avoir, ce qui complique un peu le truc.

La réponse est "bien sûr que c'est possible", la contextualisation doit être faite dans le parser. D'abord tu gardes les deux dans le même état "MOT". Et ensuite ta grammaire dit :

condition := /* plein de cas ... */ | VAR a la valeur VALEUR
VAR := MOT

Dans ce cas n'importe quel mot peut être promu en nom de variable pourvu que ce soit ce que le contexte propose.

Et du coup ton tokenizeur devra être dépendant du contexte.

Red flag énorme. Cette option ne peut pas être une option correcte. Ça ne marchera jamais, tu finiras pas réimplementer le parser dans ton lexer. Ça c'est impossible pour le coup.

Pour votre culture : https://en.wikipedia.org/wiki/Lexer_hack

Je pense qu'avant de progresser il faudrait déjà définir une spécification du "langage naturel", avec beaucoup d'exemples et de cas spéciaux, et après seulement on pourra faire l'architecture du compilateur.

Enfin un brin d'intuition !
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/05/2020 19:59 | #


si a a la valeur 3 on peut se référer au fait que généralement, la condition est de la forme EXPR COMPARAISON EXPR (EXPR pouvant être une variable ou un calcul… ?) Mais là c'est le rôle du parser si j'ai suivi… ?

Je pense virer tout mon lexer existant et repartir sur une bonne base pour vraiment ne faire que des tokens comme c'est noté dans l'article :
left parenthesis
identifier 'A'
right parenthesis
operator '*'
identifier 'B'


Avec du coup la 'classe' du mot et le mot en lui même
"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: 24575 Défis: 170 Message

Citer : Posté le 10/05/2020 20:04 | #


Mais là c'est le rôle du parser si j'ai suivi… ?

Oui, le lexer c'est juste un truc braindead qui groupe les lettre en mots. À la limite tu peux considérer que "plus grand que" est un seul mot si tu y tiens, mais vraiment rien de plus. Tous les objets compliqués comme les expressions arithmétiques, la formation des if/for/etc, et essentiellement tout ce qui est constitué de plusieurs mots indépendants est du ressort du 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 11/05/2020 08:44 | #


Mais du coup j'ai une question… Tu as dit plus haut que mon système TOKEN(EXPR, a) pour désigner la variable a est pas propre, pourtant avec le système de wikipédia : identifier 'A' ils stockent aussi des infos… ? Du coup est-ce qu'il faut que je continue plutôt sur (EXPR, a) ou plutôt sur (classe_du_token, valeur) ?
"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: 24575 Défis: 170 Message

Citer : Posté le 11/05/2020 08:46 | #


Le problème n'est pas le fait d'ajouter des données, c'est le fait d'avoir une notion d'expression dans le lexer. Une expression c'est composé de différents objets mis ensemble avec des opérateurs. C'est le parser qui se démerde. Le lexer se contente de dire "ça c'est un nombre entier", "ça c'est un nom de variable" et ensuite le parser se débrouille.
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 11/05/2020 08:52 | #


Ah ok du coup la méthode : TOKEN(classe_du_token, valeur) est bien… ? Imaginons que le lexer me renvoie ça :
TOKEN(COM, 'if')
TOKEN(MOT, 'a')
TOKEN(VERBE, 'est')
TOKEN(COMP, 'supérieur')
TOKEN(PREP, 'à')
TOKEN(CHIFFRE, '12')


Ce serait bien ? Et si dans le code il se base sur le fait d'avoir un TOKEN(COM, 'if') pour savoir que a est un mot et non un verbe, c'est bon… ?
"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, 4, 5 ··· 10 ··· 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 230 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