Le fichier source est ${UPS_HOME}/upssdk/demo/${UPS_LANGUAGE}/analyse2.upl.
Cet exemple utilise les instructions de l'extension d'Up ! 5GL pour Up ! Parser. Les objets sémantiques sont déclarés statiquement.
Pour analyser le fichier source, UpsPrs.upi doit être déclaré parmi les modules importés dans le fichier ${UPS_HOME}/ini/${UPS_USER}/upsp5l.ini.
upscmp Source=analyse2.upl
analyse2
upssng Source=analyse2.upl
Source Composant "Exemple de l'emploi d'Up ! Parser" Version 4.0.0;
ImporterModule
/************/
UpsPrs(<UpsPrs.upi>, ImporterDefinitions);
Constante
/*******/
ElementVariable=70000;
Variable
/******/
Prive :
/*****/
A : Entier;
B : Reel;
C : Caractere;
AnalyseurLexical MonAnalyseurLexical(ReconnaitreChaineGuillemets, ReconnaitreEntier, ReconnaitreReel, ReconnaitreIdentificateur,
IgnorerCommandesPreprocesseur, LireCommentaireIdentifiant MonLireCommentaireIdentifiant)
/******************************************************************************************************************************/
Separateur(" \t\r\n");
ElementLexical("A", ElementVariable);
ElementLexical("B", ElementVariable);
ElementLexical("C", ElementVariable);
Fin AnalyseurLexical
AnalyseurSyntaxique MonAnalyseurSyntaxique
/****************************************/
NonTerminalSyntaxique NonTerminalExpression Recursif;
NonTerminalSyntaxique NonTerminalOperateurBinaire Recursif;
NonTerminalSyntaxique NonTerminalOperateurUnaire Recursif;
NonTerminalSyntaxique NonTerminalExpression
RegleSyntaxique
ElementChaineGuillemets(ActionEtape ActionExpressionConstanteCaractere);
Fin RegleSyntaxique
RegleSyntaxique
ElementEntier(ActionEtape ActionExpressionConstanteEntier);
Fin RegleSyntaxique
RegleSyntaxique
ElementReel(ActionEtape ActionExpressionConstanteReel);
Fin RegleSyntaxique
RegleSyntaxique
ElementVariable(ActionEtape ActionExpressionVariable);
Fin RegleSyntaxique
RegleSyntaxique
NonTerminalExpression NonTerminalOperateurBinaire NonTerminalExpression(ActionEtape ActionExpressionBinaire);
Fin RegleSyntaxique
RegleSyntaxique
NonTerminalOperateurUnaire NonTerminalExpression(ActionEtape ActionExpressionUnaire);
Fin RegleSyntaxique
Fin NonTerminalSyntaxique
NonTerminalSyntaxique NonTerminalExpressionPrincipale
RegleSyntaxique
NonTerminalExpression ";"(ActionEtape ActionExpressionPrincipale);
Fin RegleSyntaxique
Fin NonTerminalSyntaxique
NonTerminalSyntaxique NonTerminalOperateurBinaire
RegleSyntaxique(Priorite 8)
"+";
Fin RegleSyntaxique
RegleSyntaxique(Priorite 8)
"-";
Fin RegleSyntaxique
RegleSyntaxique(Priorite 10)
"*";
Fin RegleSyntaxique
RegleSyntaxique(Priorite 10)
"/";
Fin RegleSyntaxique
Fin NonTerminalSyntaxique
NonTerminalSyntaxique NonTerminalOperateurUnaire
RegleSyntaxique
"+";
Fin RegleSyntaxique
RegleSyntaxique
"-";
Fin RegleSyntaxique
Fin NonTerminalSyntaxique
Fin AnalyseurSyntaxique
Prive :
/*****/
Fonction LireCommentaireIdentifiant(Identifiant : Entier, Liaison : Booleen) Retourner Nul Ou Caractere
/*****************************************************************************************************/
Debut
Si Identifiant==ElementVariable Alors
Si Liaison Alors
Retourner "d'une variable";
Sinon
Retourner "une variable";
Fin Si
Fin Si
Retourner Nul;
Fin Fonction
Fonction ActionExpressionConstanteCaractere(ValeurLexicale : Nul Ou Objet, ? : Nul Ou Objet, ? : Entier, ? : Entier) Retourner ActionEtapeReponse
/***********************************************************************************************************************************************/
Debut
MonAnalyseurSyntaxique.FixerValeurSemantique(ValeurLexicale);
Retourner ActionEtapeSucces;
Fin Fonction
Fonction ActionExpressionConstanteEntier(ValeurLexicale : Nul Ou Objet, ? : Nul Ou Objet, ? : Entier, ? : Entier) Retourner ActionEtapeReponse
/********************************************************************************************************************************************/
Debut
MonAnalyseurSyntaxique.FixerValeurSemantique(ValeurLexicale);
Retourner ActionEtapeSucces;
Fin Fonction
Fonction ActionExpressionConstanteReel(ValeurLexicale : Nul Ou Objet, ? : Nul Ou Objet, ? : Entier, ? : Entier) Retourner ActionEtapeReponse
/******************************************************************************************************************************************/
Debut
MonAnalyseurSyntaxique.FixerValeurSemantique(ValeurLexicale);
Retourner ActionEtapeSucces;
Fin Fonction
Fonction ActionExpressionVariable(ValeurLexicale : Nul Ou Objet, ? : Nul Ou Objet, NumeroLigne : Entier, NumeroColonne : Entier) Retourner ActionEtapeReponse
/***********************************************************************************************************************************************************/
Variable
/******/
NomVariable : Caractere;
Debut
NomVariable=Caractere(ValeurLexicale);
Selon NomVariable Faire
Cas Pour "A" Faire
MonAnalyseurSyntaxique.FixerValeurSemantique(A);
Fin Cas
Cas Pour "B" Faire
MonAnalyseurSyntaxique.FixerValeurSemantique(B);
Fin Cas
Cas Pour "C" Faire
MonAnalyseurSyntaxique.FixerValeurSemantique(C);
Fin Cas
Defaut
Ecran.Ecrire("Analyse-5 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : la variable '"+NomVariable+"' est inconnue.");
Retourner ActionEtapeArreterTout;
Fin Defaut
Fin Selon
Retourner ActionEtapeSucces;
Fin Fonction
Fonction ActionExpressionPrincipale(? : Nul Ou Objet, ? : Nul Ou Objet, ? : Entier, ? : Entier) Retourner ActionEtapeReponse
/**************************************************************************************************************************/
Variable
/******/
Valeur1 : Nul Ou Objet;
Debut
Valeur1=MonAnalyseurSyntaxique.LireValeurSemantique(1);
Selon Valeur1.EstInstanceDe Faire
Cas Pour Caractere Faire
Ecran.Ecrire(Caractere(Valeur1));
Fin Cas
Cas Pour Entier Faire
Ecran.Ecrire(Entier(Valeur1));
Fin Cas
Cas Pour Reel Faire
Ecran.Ecrire(Reel(Valeur1));
Fin Cas
Defaut
Ecran.Ecrire("?");
Fin Defaut
Fin Selon
Retourner ActionEtapeSucces;
Fin Fonction
Fonction ActionExpressionBinaire(? : Nul Ou Objet, ValeurSemantique : Nul Ou Objet, NumeroLigne : Entier, NumeroColonne : Entier) Retourner ActionEtapeReponse
/************************************************************************************************************************************************************/
Variable
/******/
Valeur1 : Nul Ou Objet;
Valeur3 : Nul Ou Objet;
ValeurReponse : Nul Ou Objet;
SymboleLexical : Caractere;
Debut
Valeur1=MonAnalyseurSyntaxique.LireValeurSemantique(1);
Valeur3=ValeurSemantique;
SymboleLexical=Caractere(MonAnalyseurSyntaxique.LireSymboleLexical(2));
Selon SymboleLexical Faire
Cas Pour "+" Faire
Si Valeur1.EstInstanceDe==Entier Alors
Si Valeur3.EstInstanceDe==Entier Alors
ValeurReponse=Entier(Valeur1)+Entier(Valeur3);
SinonSi Valeur3.EstInstanceDe==Reel Alors
ValeurReponse=Entier(Valeur1)+Reel(Valeur3);
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '+' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
SinonSi Valeur1.EstInstanceDe==Reel Alors
Si Valeur3.EstInstanceDe==Entier Alors
ValeurReponse=Reel(Valeur1)+Entier(Valeur3);
SinonSi Valeur3.EstInstanceDe==Reel Alors
ValeurReponse=Reel(Valeur1)+Reel(Valeur3);
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '+' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
SinonSi Valeur1.EstInstanceDe==Caractere Et Valeur3.EstInstanceDe==Caractere Alors
ValeurReponse=Caractere(Valeur1)+Caractere(Valeur3);
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '+' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
Fin Cas
Cas Pour "-" Faire
Si Valeur1.EstInstanceDe==Entier Alors
Si Valeur3.EstInstanceDe==Entier Alors
ValeurReponse=Entier(Valeur1)-Entier(Valeur3);
SinonSi Valeur3.EstInstanceDe==Reel Alors
ValeurReponse=Entier(Valeur1)-Reel(Valeur3);
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '-' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
SinonSi Valeur1.EstInstanceDe==Reel Alors
Si Valeur3.EstInstanceDe==Entier Alors
ValeurReponse=Reel(Valeur1)-Entier(Valeur3);
SinonSi Valeur3.EstInstanceDe==Reel Alors
ValeurReponse=Reel(Valeur1)-Reel(Valeur3);
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '-' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '-' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
Fin Cas
Cas Pour "*" Faire
Si Valeur1.EstInstanceDe==Entier Alors
Si Valeur3.EstInstanceDe==Entier Alors
ValeurReponse=Entier(Valeur1)*Entier(Valeur3);
SinonSi Valeur3.EstInstanceDe==Reel Alors
ValeurReponse=Entier(Valeur1)*Reel(Valeur3);
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '*' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
SinonSi Valeur1.EstInstanceDe==Reel Alors
Si Valeur3.EstInstanceDe==Entier Alors
ValeurReponse=Reel(Valeur1)*Entier(Valeur3);
SinonSi Valeur3.EstInstanceDe==Reel Alors
ValeurReponse=Reel(Valeur1)*Reel(Valeur3);
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '*' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)*
+" : les opérandes de '*' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
Fin Cas
Cas Pour "/" Faire
Si Valeur1.EstInstanceDe==Entier Alors
Si Valeur3.EstInstanceDe==Entier Alors
ValeurReponse=Entier(Valeur1)/Entier(Valeur3);
SinonSi Valeur3.EstInstanceDe==Reel Alors
ValeurReponse=Entier(Valeur1)/Reel(Valeur3);
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '/' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
SinonSi Valeur1.EstInstanceDe==Reel Alors
Si Valeur3.EstInstanceDe==Entier Alors
ValeurReponse=Reel(Valeur1)/Entier(Valeur3);
SinonSi Valeur3.EstInstanceDe==Reel Alors
ValeurReponse=Reel(Valeur1)/Reel(Valeur3);
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '/' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
Sinon
Ecran.Ecrire("Analyse-1 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : les opérandes de '/' sont de types incompatibles.");
Retourner ActionEtapeArreterTout;
Fin Si
Fin Cas
Defaut
Ecran.Ecrire("Analyse-2 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : l'opérateur '"+SymboleLexical+"' est non pris en compte.");
Retourner ActionEtapeArreterTout;
Fin Defaut
Fin Selon
MonAnalyseurSyntaxique.FixerValeurSemantique(ValeurReponse);
Retourner ActionEtapeSucces;
Fin Fonction
Fonction ActionExpressionUnaire(? : Nul Ou Objet, ValeurSemantique : Nul Ou Objet, NumeroLigne : Entier, NumeroColonne : Entier) Retourner ActionEtapeReponse
/***********************************************************************************************************************************************************/
Variable
/******/
Valeur2 : Nul Ou Objet;
ValeurReponse : Nul Ou Objet;
SymboleLexical : Caractere;
Debut
Valeur2=ValeurSemantique;
SymboleLexical=Caractere(MonAnalyseurSyntaxique.LireSymboleLexical(1));
Selon SymboleLexical Faire
Cas Pour "+" Faire
Si Valeur2.EstInstanceDe==Entier Alors
ValeurReponse=Entier(Valeur2);
SinonSi Valeur2.EstInstanceDe==Reel Alors
ValeurReponse=Reel(Valeur2);
Sinon
Ecran.Ecrire("Analyse-3 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : l'opérande de '+' est de type incompatible.");
Retourner ActionEtapeArreterTout;
Fin Si
Fin Cas
Cas Pour "-" Faire
Si Valeur2.EstInstanceDe==Entier Alors
ValeurReponse=-Entier(Valeur2);
SinonSi Valeur2.EstInstanceDe==Reel Alors
ValeurReponse=-Reel(Valeur2);
SinonSi Valeur2.EstInstanceDe==Caractere Alors
ValeurReponse=-Caractere(Valeur2);
Sinon
Ecran.Ecrire("Analyse-3 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : l'opérande de '-' est de type incompatible.");
Retourner ActionEtapeArreterTout;
Fin Si
Fin Cas
Defaut
Ecran.Ecrire("Analyse-2 : Erreur de sémantique en ligne "+Caractere(NumeroLigne)+" colonne "+Caractere(NumeroColonne)
+" : l'opérateur '"+SymboleLexical+"' est non pris en compte.");
Retourner ActionEtapeArreterTout;
Fin Defaut
Fin Selon
MonAnalyseurSyntaxique.FixerValeurSemantique(ValeurReponse);
Retourner ActionEtapeSucces;
Fin Fonction
Procedure EnvoyerErreur(MessageErreur : Caractere, ? : Caractere, ? : Entier, ? : Entier)
/***************************************************************************************/
Debut
Ecran.Ecrire(MessageErreur);
Fin Procedure
Procedure Analyser(Chaine : Caractere)
/************************************/
Variable
/******/
F : Nul Ou FluxCaractere;
Debut
Ecran.Ecrire("Analyse de : "+Chaine);
F=FluxCaractere(Chaine, Vrai);
MonAnalyseurLexical.DebuterAnalyse(IFlux(F), "<Chaine>", EnvoyerErreur);
?=MonAnalyseurSyntaxique.Analyser(NonTerminalExpressionPrincipale, Faux, EnvoyerErreur);
MonAnalyseurLexical.TerminerAnalyse();
F.Fermer();
Fin Procedure
Principal
/*******/
Debut
MonAnalyseurSyntaxique.DebuterAnalyse(MonAnalyseurLexical);
Analyser("1+2-3*4/5;");
Analyser("1.0+2.0-3.0*4.0/5.0;");
Analyser("1+2.0-3*4.0/5;");
Analyser("1.0+2-3.0*4/5.0;");
A=2;
Analyser("1+A-3*4/5;");
B=3.0;
Analyser("1.0+2.0-B*4.0/5.0;");
Analyser("\"coucou\"+\"hello\";");
Analyser("-\"coucou\";");
C="coucou";
Analyser("C+\"hello\";");
Analyser("1^2;");
Analyser("1+D;");
MonAnalyseurSyntaxique.TerminerAnalyse();
Fin Principal