Je souhaite crée mon langage est est déjat fait la partie Lexicale. Mai je doit maintenant choisir comment implémenté l’analyse de syntax. Voici mon code actuel (Ceci est une démo pour montré le concept):
#include <stdio.h>
enum type{
Ident,
OEF,
Virgule,
Egual,
LParent,
RParent,
LParagra,
RParagra,
Value
}type;
#define SizeTableau 200
int main()
{
int t=0;
int thing[SizeTableau]={Ident,Egual,Value,Ident,Ident,LParent,RParent,LParagra,LParagra,RParagra,RParagra,Ident,Egual,Value,OEF};
do
{
if(thing[t]==Ident)
{
t++;
printf("\nIdent");
if(thing[t]==Ident)
{
printf(": est un Type\nIdent: est une foncion");
t++;
if(thing[t]==LParent)
{
t++;
printf("\nLParent");
if(thing[t]==RParent)
{
t++;
printf("\nRParent");
}
}
}
else if(thing[t]==Egual)
{
printf(": Est Une variable\nEgual");
t++;
if(thing[t]==Value)
{
printf("\nValue");
t++;
}
}
}
else if(thing[t]==LParagra)
{
t++;
printf("\nLParagra");
}
else if(thing[t]==RParagra)
{
t++;
printf("\nRParagra");
}
else if(thing[t]==OEF)
{
t=0;
printf("\nOEF");
}
else
{
printf("\nSyntax Error");
t++;
}
if(t>=SizeTableau)
t=0;
}while(t);
return 0;
}
Pensé vous que cette implémentation pose un problème est avais vous des suggestion?
En faite c'est que ce n'est qu'une démo ici pour le concepts. Il faut bien pensé que le programme est divisé en réalité en plusieurs partie. La première partie divise le code source en plusieurs jeton appeler "Token"; ce sont les différent mots clée variable fonction etc.... En fonction du langage, ces jeton sont identifier par ces fameuse constante. La démo n'est ici que pour une preuve de concept.
Pour en dire plus, il faudrait avoir une description précise de la syntaxe voulue.
- Edité par michelbillaud il y a environ 19 heures
Bon, j'ai visiblement du mal à expliquer le concept de ma démo. oublier la si vous ne la comprenais pas. Le concepts de récursivité est effectivement une bonne solution. C'est ce que je vais faire. Toutefois je cherche à le faire d'une façon différente car à chaque appel de fonction la pile est utilisé. J'ai peur de faire un dépassement de la pile. Mai j'ai peut être trouver un autre moyen de le faire. Chaque fonction utiliserai un pointeur de fonction quel affecterait à la fonction suivante. Alors ont sort de la fonction est en fait appel a l'autre fonction en utilisent le pointeur de fonction. De cette façon la pile n'est pas trop utilisé. Je vais voir si je peut faire comme ça.
> à chaque appel de fonction la pile est utilisé. J'ai peur de faire un dépassement de la pile. Mai j'ai peut être trouver un autre moyen de le faire. Chaque fonction utiliserai un pointeur de fonction quel affecterait à la fonction suivante.
Si tu trimballes des pointeurs de fonctions, la seule chose à quoi ça puisse te servir, c'est d'appeler les fonctions en question.
Et ça utilise la pile, forcément.
Bon courage pour écrire un interprète/compilateur qui n'utilise pas la récursivité qui te fait si peur :-)
Oui. Il y a quelque façon de le faire. Je peut par exemple crée une variable dans la fonction qui fait appel au pointeur de fonction est la passer en paramètre à toute les autres fonctions qui peuvent alors communiquer entre elle. De la même manière je peut passer un pointeur sur une liste de différent type. Donc oui ces possible. Mai je n'est pas encore décidé comment je vais faire.
michelbillaud a écrit:
> r à chaque appel de fonction la pile est utilisé. J'ai peur de faire un dépassement de la pile. Mai j'ai peut être trouver un autre moyen de le faire. Chaque fonction utiliserai un pointeur de fonction quel affecterait à la fonction suivante.
Si tu trimballes des pointeurs de fonctions, la seule chose à quoi ça puisse te servir, c'est d'appeler les fonctions en question.
Et ça utilise la pile, forcément.
Bon courage pour écrire un interprète/compilateur qui n'utilise pas la récursivité qui te fait si peur :-)
- Edité par michelbillaud il y a 2 minutes
oui ca utilise la pile mai seulement pour une profondeur de 1, puisque je revient à chaque fois au sommet. Et ce que j'essai de faire est en faite une récursivité émulé. Oui en fin j'essai
Je vien de comprendre pourquoi Michel me parler de l’erreur type au lieu de int dans mon code, c'est corrigé. Voici ou j'en suis:
#include <stdio.h>
#define SizeTableau 200
/*** Token identité ***/
typedef enum type{
Ident,
OEF,
Virgule,
Egual,
LParent,
RParent,
LParagra,
RParagra,
Value
}type;
/*** structure pour pointé sur la fonction qui traite le prochain Token ***/
typedef struct NextToken NextToken;
typedef struct NextToken{
int(*Next_token)(NextToken *NToken,type T);
type TokenType;
}NextToken;
/*** Les fonction qui traite les différent Token ***/
int noeuA(NextToken*, type);
int noeuB(NextToken*, type);
int noeuC(NextToken*,type);
int main()
{
/*** liste des Token ***/
type thing[SizeTableau]={Ident,Egual,Value,OEF};
NextToken Token;
Token.Next_token=noeuA;
Token.TokenType=thing[0];
int t=0;
/*** execute les fonctions voulue suivont les différents tokens ***/
while(thing[t]!=OEF)
{
Token.Next_token(&Token,thing[t]);
t++;
}
return 0;
}
int noeuA(NextToken* NToken,type t)
{
printf("test\n");
if(t==Ident)
NToken->Next_token=noeuB;
else
printf("erreur");
}
int noeuB(NextToken *NToken,type t)
{
printf("test2\n");
if(t==Egual)
NToken->Next_token=noeuC;
else
printf("erreur");
}
int noeuC(NextToken *NToken,type t)
{
printf("test3\n");
}
As-tu une idée de la profondeur de tes récursivités? J'imagine que les compilateurs actuels utilisent la récursivité. Et même en Python, qui est un langage interprété, on peut aller par défaut jusqu'à un niveau de 1000 (+ ou - 2)
edit:
J'ai commis le programme stupide suivant:
#include <stdio.h> int add(int n) { if(n <= 0) return 0; return n+add(n-1); } int main(void) { int n; scanf("%d", &n); printf("%d\n", add(n)); }
Je me rend à plus de 43300 récursions sur Windows.
- Edité par PierrotLeFou 7 mai 2023 à 3:36:16
Le Tout est souvent plus grand que la somme de ses parties.
Le nombre de niveaux de récursion est à multiplier par la taille du "cadre de pile" qui contient les variables locales à chaque niveau (avec l’adresse de retour, celle du cadre précédent etc)
Si tu n'utilises pas la pile implicite des appels de fonction, tu te retrouves à placer tes données et pointeurs de fonction dans un gros tableau que tu vides/remplis explicitement : c'est une pile aussi...
La boucle de la ligne 42 me fait penser que tu es en train de réinventer le "threaded code".
Le nombre de niveaux de récursion est à multiplier par la taille du "cadre de pile" qui contient les variables locales à chaque niveau (avec l’adresse de retour, celle du cadre précédent etc)
Si tu n'utilises pas la pile implicite des appels de fonction, tu te retrouves à placer tes données et pointeurs de fonction dans un gros tableau que tu vides/remplis explicitement : c'est une pile aussi...
La boucle de la ligne 42 me fait penser que tu es en train de réinventer le "threaded code".
En faite j'aurai certainement besoin d'une chaîne, car après le retour des "noeu" non terminaux, je doit savoir dans quel noeu revenir. La "pile" sera donc une chaîne alloué avec malloc et donc dans le tas et non dans la pile. De plus bravo pour ces article supplémentaire qui alimente la reflection.
PierrotLeFou a écrit:
As-tu une idée de la profondeur de tes récursivités? J'imagine que les compilateurs actuels utilisent la récursivité. Et même en Python, qui est un langage interprété, on peut aller par défaut jusqu'à un niveau de 1000 (+ ou - 2)
edit:
J'ai commis le programme stupide suivant:
#include <stdio.h> int add(int n) { if(n <= 0) return 0; return n+add(n-1); } int main(void) { int n; scanf("%d", &n); printf("%d\n", add(n)); }
Je me rend à plus de 43300 récursions sur Windows.
- Edité par PierrotLeFou il y a environ 6 heures
Si c'est effective la cas alors oui peut être que je n’embête pour rien. Mai bon au moins il y auras une sécurité. Tu a essayé sur windows, peut être que dans l'embarqué par exemple ces différent?
PS: J'ai maintenant finie d'implémenté la chaîne avec les fonctions push et pop. Il me faut maintenant crée quelques noeux terminaux et non terminaux pour voir si tout fonctionne.
Oui j'utilise peut être le mauvais mot. J'ai donc maintenant finie d'implémenté la pile ( sur le tat )
Ok. Ont dirai que ça fonctionne. Mai je dois encore amélioré. Car je pense qu'il peut y avoir actuellement des conflit quand un noeu prend en sortie deux noeu dans l'un est non terminaux
PS: J'ai corrigé, je pense que soit doit être bon. Mai avec ce type de code ont est pas à l’abri d'un bug.
@Phil_1857: la langue maternelle de sdms n'est peut-être pas le français ? Et si tu veux corriger tous les commentaires de ce forum, c'est un travail à plus que plein temps.
- Edité par edgarjacobs 9 mai 2023 à 17:30:06
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Ok. Pour ce que ça intéresse voila le schéma de principe de l'algorithme que je vais implémenté. A chaque fois que le noeux StLOOP et appeler il appelle lui même (par le pointeur de fonction) le noeux Statement
PS: voir le message suivant pour quelques informations utile.
J'avais quelques bugs dans l’implémentation. Je vient de les corriger. ça fonctionne bien. Dans mon cas, à cause de la façon dans je gère la recherche ou non du prochain token, les nœud I,K et D retourne la valeur Nontermineau, malgré le fait qu'il son en fait des nœud terminaux. Cela permet de rester dans la boucle de retour pour continuer à exécuter les nœud non terminaux suivant sans repartir tout de suite sur la recherche du prochain token. Donc si quelqu'un souhaite utilisé cette façon de faire il devras pensé à ça.
D'autre part Le nœud RetourD pointe en faite sur le nœud Début.
- Edité par sdms 5 juin 2023 à 16:44:46
Créer mon langage
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent