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 !
Citer : Posté le 13/05/2020 09:52 | #
Pour moi c'était assez clair ce qu'il demandait surtout que les langages d'algos sont souvent appelés "langage naturel" pour le distinguer du langage basic/python.
+1
Sans une formalisation du langage d'algo on peut pas dire si tu peux traiter "est égal à" en un seul token.
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 13/05/2020 09:56 | #
Pour être sûr, une fois le projet fini, cet algo :
u prend la valeur 2
n prend la valeur 0
Tant que u<A
n prend la valeur n+1
u prend la valeur 3*n^2+2
Fin Tant que
Afficher n
pourra être compilé sans problème.
Ma Grammaire avance J'ai déjà deux trois cas pour plusieurs pattern : comparaison, boucle itérative, affectation, demande utilisateur…
Le problème est que ça reste du français c'est… fin c'est entre les deux… Typiquement, je vise à compiler les algo "langage naturel" des livres de maths. Du coup c'est bien du Français, mais c'est plus rigoureux comme langage qu'un langage naturel pur et débridé…
Citer : Posté le 13/05/2020 10:00 | #
Argh mais chez moi on dit pseudo-code. Les gens qui font du langage naturel c'est du NLP xD
Citer : Posté le 13/05/2020 10:02 | #
Le but est vraiment de compiler les algos des livres de maths L'exemple de Tituya est typiquement ce que je vise
Ajouté le 13/05/2020 à 10:21 :
Mais du coup je ne sais pas trop, si c'est du langage naturel, de l'algorithme… ?
Citer : Posté le 13/05/2020 10:27 | #
Le terme approprié est pseudo-code. Vois : https://fr.wikipedia.org/wiki/Pseudo-code
Citer : Posté le 13/05/2020 10:29 | #
C'est de la sémantique tout ça
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 13/05/2020 10:39 | #
Ok, du coup Compylateur : compile le pseudo-code
Mais après l'exemple de wikipédia ne sera pas compilé… c'est trop différent de ce qu'il y a dans les livres de maths… ?
Citer : Posté le 13/05/2020 10:41 | #
L'exemple de wikipédia devrait pouvoir être compilé, c'est un langage algorithmique. Ca te fait des tokens en plus à ajouter
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 13/05/2020 10:48 | #
Il y a plein de façons d'écrire du pseudo-code. Commence par un coder une, et ensuite tu verras si tu veux/peux en rajouter.
Citer : Posté le 13/05/2020 10:50 | #
J'arrive pas a expliquer ce que je veux compiler… Le pseudo-code est trop proche de la programmation, je vise un truc plus proche du français.
Après je continue ma grammaire sur le pseudo-code des livres de maths
Ajouté le 13/05/2020 à 18:23 :
Pour le git, l'adresse : https://gitea.planet-casio.com/Shadow/Compylateur
Le fichier compylateur.py est quasiment vide, mais il contiendra le fichier final du compilateur.
Interpy.py c'était mon premier jet aussi déguelasse que fonctionnel, pour ceux qui se mette les process de compilation où je pense et qui veulent un truc qui marche quelle qu'en soit les conséquences… le fichier marche sur calculatrice.
Lexer.py est le lexer.
Ajouté le 14/05/2020 à 11:34 :
J'ai commencé à faire ma grammaire :
Généralités :
condition = comparaison
IF et WHILE sont toujours suivi d'une condition et une condition de ne peut pas être ailleurs qu'après un IF ou un WHILE
MOT COMP MOT
MOT VERBE PREP COMP PREP MOT
Définition du contenu :
MOT = variable
VERBE = 'est'
PREP = 'plus' ou 'moins'
COMP = opérateur de comparaison
PREP = 'que'
MOT PREP MOT/CHIFFRE PREP MOT/CHIFFRE
Définition du contenu :
MOT = variable
VERBE = 'allant' ou 'variant'
PREP = si pas de verbe = 'entre', sinon = 'de'
MOT/CHIFFRE = variable / valeur
PREP = 'à' ou 'jusqu'à' ou 'et' (si pas de verbe)
MOT/CHIFFRE = variable / valeur
MOT VERBE MOT MOT MOT/CHIFFRE
Définition du contenu :
VERBE = 'prend' ou 'prend' ou 'affecter'
PREP = 'la' ou 'à'
MOT = variable ou 'valeur'
MOT/CHIFFRE = variable / valeur
La variable qui est affectée est soit le premier mot de la séquence, soit entre deux PREP.
VERBE PREP MOT PREP MOT [PREP MOT]
Définition du contenu :
VERBE = 'demander' ou 'saisir'
PREP = 'la' ou 'de' ou 'à'
MOT = variable ou 'valeur' ou 'l'utilisateur'
Ajouté le 15/05/2020 à 08:56 :
J'ai quelques questions du coup :
- Est-ce que ma grammaire est correcte ? (xD j'ai l'impression d'être en CM1 à poser des questions pareilles )
- Je pensais mettre le pattern dans une chaîne de caractère et placer tous les types de tokens dans une autre. Par exemple :
('MOT', 'a')
('VERBE', 'est')
('COMP', 'égal')
('PREP', 'à')
('MOT', 'b')
devient : COM MOT VERBE COMP PREP MOT et je fait un .find() pour chercher le pattern qui m'intéresse… Est-ce que cette méthode est pertinente ?
Citer : Posté le 15/05/2020 09:27 | #
VERBE PREP MOT PREP MOT [PREP MOT]
Définition du contenu :
VERBE = 'demander' ou 'saisir'
PREP = 'la' ou 'de' ou 'à'
MOT = variable ou 'valeur' ou 'l'utilisateur'
Donc "demander de l'utilisateur" c'est correct ?
('COM', 'si')
('MOT', 'a')
('VERBE', 'est')
('COMP', 'égal')
('PREP', 'à')
('MOT', 'b')
Tu dois oublier cette histoire de catégorisation des tokens en mot/verbe/complément/etc, c'était parce que Lephé avait pas bien compris ta question.
La grammaire est du coup pas totalement correcte car pas assez stricte. Il faut faire des trucs du genre :
boucle itérative = variable ("variant de" | "allant entre") valeur ("à" | "jusqu'à" | "et") valeur
Avec des définitions récursives :
valeur = variable | constante | fonction
variable = ??
constante = chiffre | etc
fonction = ...
Tu oublies notamment 2 trucs importants :
- la définition d'une variable (grammaticalement)
- si les tokens multi-mots peuvent être séparés par un nombre indéterminé d'espaces
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 15/05/2020 09:31 | #
Du coup, il faut que je remanie le lexer ?
OKay, j'avais pas saisi la grammaire, je vais la refaire Merci !
Citer : Posté le 15/05/2020 09:38 | #
Zezombye a raison, tu peux grouper directement "prend la valeur" ou des séquences fixes comme ça en un seul token.
C'est pas top non. Utilise un vrai parser généré par un outil bien écrit, il n'y a aucune raison de faire autrement puisque tu fais du pseudo-code ^^"
Il est possible d'écrire un parser propre à la main, mais seules les grammaires LL(*) s'y prêtent, et ça nécessite de les normaliser un peu. Je te le conseille pas si c'est ta première fois !
Citer : Posté le 15/05/2020 09:38 | #
Un exemple de grammaire : https://docs.python.org/3/reference/grammar.html
Un peu indigeste mais si tu veux générer un parseur à partir de la grammaire il faudra la spécifier dans un format bien précis comme celui là.
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 15/05/2020 09:43 | #
Du coup le groupement, c'est le lexer ou le parser ?
Citer : Posté le 15/05/2020 09:44 | #
Le groupement c'est le tokeniseur ouaip.
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 15/05/2020 09:45 | #
Du coup faut que je redéfinisse ma grammaire avec plus de rigueur, et que je remanipule le lexer pour qu'il gère les groupements ?
Citer : Posté le 15/05/2020 09:49 | #
C'est ça !
Citer : Posté le 15/05/2020 09:52 | #
Niquel, ok, merci !
Ajouté le 18/05/2020 à 15:33 :
Donc la refonte du lexer pousse à l'abandon des tokens VERBE, MOT… etc, mais je met quoi à la place ?
Citer : Posté le 18/05/2020 15:58 | #
Entiers, parenthèses, noms de variables, mots-clés...
Citer : Posté le 18/05/2020 16:00 | #
Ah ok, merci !
Ajouté le 27/05/2020 à 13:42 :
J'ai bien avancé le lexer… il me reste la gestion des intervalles qui n'est pas du tout implémentée Le code est à sa première version (depuis la refonte) j'implémente les intervalles et j'essaye d'optimiser tout ça…
Je ne met pas le code ici (trop gros) par contre il est dispo sur le git : https://gitea.planet-casio.com/Shadow/Compylateur/src/branch/master/Lexer.py
Un exemple de tokens générés : sur cette ligne Si a est égal à b ou que c est supérieur ou égal à a j'obtient :
('UNDEF', 'a')
('COMP', 'est égal à')
('UNDEF', 'b')
('LOGI', 'ou que')
('UNDEF', 'c')
('COMP', 'est supérieur ou égal à')
('UNDEF', 'a')
(là je met sur différentes lignes pour la lisibilité, en pratique c'est une liste )