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 12/05/2020 10:27 | #
Ouaip je vais commencer par écrire la grammaire c'est une bonne idée
Oui, mais je répondais pas à ton exemple c'était une réflexion plus générale sur l'utilité pour le lexer de gérer les parenthèse et co
Au niveau du langage naturel, j'ai un petit problème : les fonctions mathématiques, j'ai vu plusieurs algo où c'est juste marqué : f est une fonction mathématiques et après ils utilisent f(x) n'importe quel humain comprends que f(x) est une fonction quelconque… mais le compilo va pas aimer la blague Du coup ça fait partit des limites ou une alternative est possible ? (à la limite c'est pas non plus le plus pressé…)
Citer : Posté le 12/05/2020 10:29 | #
C'est le parseur qui a la règle "un token suivi d'un groupe de parenthèses est une fonction". Du coup je ne vois pas d'ambiguité ?
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 12/05/2020 10:30 | #
Je n'ai pas l'expression de la fonction… elle n'est pas demandée à l'utilisateur…
@Zez : Ah oui, je vois le truc (avec ton exemple)
Citer : Posté le 12/05/2020 10:35 | #
Tu peux donner un exemple d'algo qui pose problème ?
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 12/05/2020 10:40 | #
C'est le parseur qui a la règle "un token suivi d'un groupe de parenthèses est une fonction". Du coup je ne vois pas d'ambiguité ?
Ça dépend de ta grammaire. En mathématiques, il est courant de voir des expressions du style a = x(x+1). Et là x n'est pas une fonction mais une variable.
Après ça me parait compliqué pour un premier jet de traiter ces cas, donc autant s'arrêter à a = x×(x+1)
Citer : Posté le 12/05/2020 10:41 | #
Par exemple, celui-là (issu de mon bouquin de math) :
S est un nombre réel
Affecter à S la valeur 0
Pour k variant de 0 à 3
Affecter à S la valeur S + 1/4 f(k/4)
Fin Pour
Afficher S
Dans cet exo la fonction f est connue, mais l'algo, lui n'en parle pas.
Citer : Posté le 12/05/2020 10:42 | #
C'est un problème de sémantique ça, pas de syntaxe. Une étape à la fois.
Citer : Posté le 12/05/2020 10:44 | #
Oky Bon j'arrête mes digressions pour aujourd'hui : écrire la grammaire d'abord et avant tout ! \o/
Citer : Posté le 12/05/2020 10:49 | #
Putain t'as raison dark, j'avais oublié la multiplication implicite...
Mais ça reste solvable. Il faut forcer le même namespace pour fonctions et variables (donc si j'ai une fonction f je peux pas avoir une variable f). Le parseur traite toujours ça comme une fonction, mais c'est l'AST qui dit "hmm ce nom de fonction est une variable, du coup je retourne "_mult" avec comme arguments le nom de la fonction et les "arguments"".
Et oui ton exemple n'est qu'une fonction pas déclarée, aucun parseur n'est capable de traiter ça. Le parseur verra que c'est une fonction, mais l'AST voit que "f" n'est ni dans les fonctions ou variables déclarées par l'utilisateur, ni dans les fonctions built-in (genre cos, sin, etc) et donne une erreur "unknown function or variable 'f'".
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 12/05/2020 10:59 | #
Attention Zezombye tu confonds l'AST et l'analyseur sémantique. L'AST ne "fait" rien, ce n'est qu'une structure de données.
Soit dit en passant, la question de la multiplication implicite est purement sémantique :
• Dans a(b), si a est une fonction, multiplier n'a aucun sens.
• Dans a(b), si a est une valeur numérique, appeler une fonction n'a aucun sens.
Ça tombe dans la catégorie de surcharge de l'opérateur () selon le type de donnée manipulée. Mais ça, encore une fois, c'est une question pour l'analyseur sémantique.
Citer : Posté le 12/05/2020 11:04 | #
L'analyseur sémantique analyze bien l'AST ? Si oui alors oui je voulais dire l'AST
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 12/05/2020 11:11 | #
Oui mais pas que. L'analyseur sémantique utilise aussi beaucoup une autre structure de données qu'on appelle table des symboles. C'est notamment là que sont stockées les information de typage. En disant "l'AST" tout le temps tu éludes ça, et tu mets dans l'AST des informations qui n'y sont pas forcément à leur place.
Citer : Posté le 12/05/2020 13:24 | #
Oh, y'en a un qui essaye de faire Skript mais pour du python? Tu peux essayer de te baser sur ce qu'ils ont fait, le code est sur GitHub
Lien: https://www.planet-casio.com/Fr/forums/lecture_sujet.php?id=15779
Citer : Posté le 12/05/2020 20:02 | #
@Rader : le but est de faire un outil en Python qui permettent de compiler le langage naturel vers le Python. Dans un premier temps, je vais essayer de faire le projet sans utiliser de code qui ne soit pas de moi le but étant aussi pour moi de découvrir la compilation !
Je vous met le code du lexer :
verbe = {"est", "sont", "prend", "demander", "saisir", "allant", "afficher", "affecter"}
prep = {"à", "la", "le", "que", "de", "entre", "plus", "moins"}
com = {"si", "alors", "sinon", "pour", "tant", "fin"}
comp = {"supérieur", "inférieur", "égal", "différent", "grand", "petit"}
logi = {"et", "ou"}
oper = {"+", "-", "*", "/", "%", ",", "\"", "'", "(", ")", "[", "]", "{", "}"}
detect = [verbe, prep, com, comp, logi, oper]
mot = prgm_src.split(" ")
l_token, token = list(), str()
for i in mot:
for j in range(len(detect)):
if i.lower() in detect[j]: token = ["VERBE", "PREP", "COM", "COMP", "LOGI", "OPER"][j]
if i.isdigit(): token = "CHIFFRE"
elif not len(token): token = "MOT"
l_token.append((token, i))
return l_token
Si vous avez des suggestions de mots à ajouter, de classe de mots à gérer, d'optimisations… etc Je suis preneur !
Citer : Posté le 12/05/2020 20:12 | #
Je poste ici un algorithme issu de mon livre de math :
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
Manifestement, tu ne gères pas le mot "valeur", les signes ">" et "<" (ni <= et >=) ainsi que la puissance "^"
Cet algo peut être sympa comme test ! Il possède des instructions simples tout en étant assez complet !
J'ai aussi vu un autre exercice avec la syntaxe étrange d'une boucle for :
...
Fin Pour
Dans celui ci, il n'y a pas le mot "variant" étant géré
Voilà voilà !
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 12/05/2020 20:15 | #
Lephé je comprends pas l'utilité de diviser les mots en verbes/prépositions/noms, on s'en fout vu qu'au final c'est la combinaison de certains mots prédéfinis que le parseur recherche ? Savoir qu'un tel token est un verbe ou un nom je vois pas en quoi ça peut servir.
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 12/05/2020 20:21 | #
Comme je l'ai mentionné plus tôt, si tu utilises le parser pour trouver les structures de contrôle, tu ne programmes pas en langage naturel, tu programmes dans un langage classique avec des mots-clés en français.
Je crois qu'il faudrait vraiment renommer ce topic en "compilateur pseudo-code vers Python". Vous ne voyez peut-être pas le gros bagage que l'expression "programmer en langage naturel" trimballe, mais c'est assez monstrueux.
Ça fait quelques temps que je soupçonne que Shadow se moque du langage naturel et veut juste compiler du pseudo-code, mais je suis bien incapable de le dire parce qu'après 4 pages de commentaires il n'y a aucune spécification du langage...
Citer : Posté le 12/05/2020 20:29 | #
Oui c'est juste que ce langage classique est moins strict que les langages de programmation actuels (avec genre "équivaut à", "est égal à" et "égal à" pour "==") mais ça doit rester un langage relativement formel. D'ailleurs mon prof d'algo était assez strict sur sa façon d'écrire un algo.
Si c'est un langage naturel on devrait pouvoir parser des trucs comme :
On met 35 dans A et 43 dans la variable B, puis on fait A+B, et avec ça on fait le cosinus de B + le sinus de a, divisé par 2. Mais on fait ça que si a est 0, sinon c'est juste A puissance B.
Pour parser ça je me pencherais sur l'IA
Mais les algorithmes dans les cours de maths ne ressemblent pas du tout à ça, ils sont plus stricts sur la syntaxe et du coup il est possible de les parser de manière traditionnelle.
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 13/05/2020 09:23 | #
Oui, forcément, quand je dit "langage naturel", je pense langage naturel restant rigoureux (cf. les livres de maths)…
J'ai trouvé le nom du compilo du coup je vais changer.
En fait, pour être précis, le but n'est pas de compiler du langage naturel, mais du compiler un algorithme… ?
@ Tituya : Merci J'ai changé le code ! je vais faire un dépôt
Citer : Posté le 13/05/2020 09:49 | #
En fait, pour être précis, le but n'est pas de compiler du langage naturel, mais du compiler un algorithme… ?
C'est trèèès différent en fait... bon au moins le malentendu est levé ! xD
Dans ce cas tu peux être un peu plus aggressif :
• Dans ton lexer tu peux considérer "plus grand que", "supérieur à", etc. comme un seul token COMP(GT) (Greater Than pour strictement supérieur)
• Tu auras besoin des entiers, opérateurs habituels et parenthèses (imagine "Si f(x)-2 est plus grand que y")
• Dans ton parser, tu peux coder beaucoup plus de règles explicites pour les boucles, conditions, etc.
• Écris ta grammaire tout de suite !
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