Application en langage C : analyseur syntaxique
Application en langage C : analyseur syntaxique
Cet article propose en détaille une application en langage C pour faire un analyseur syntaxique.
Vous pourrez télécharger le fichier au format zip il contient le code sources complet.
Extrait du code source :
#include "ASantaxique.h"
#include "ALexical.h"
#include"Production.h"
#include<stack>
#include "Terminal.h"
#include "ASemantique.h"
#include<iomanip>
#include "Item.h"
#include "NonTerminal.h"
#include<sstream>
#include<fstream>
#include<iostream>
using namespace std;
void ASantaxique::activerGenerationCode(bool f){
generation = f;
}
void ASantaxique::activerAffichageAnalyse(bool actif){
affichage = actif;
}
ASantaxique::ASantaxique(char* fichier_grammaire,char* lexical,int nb_terminal,int nb_nterminal,int nb_prod)
:analyseurlexical(lexical)
{
affichage = false;
generation = false;
terminaux.reserve(nb_terminal);
sterminaux.reserve(nb_terminal);
nterminaux.reserve(nb_nterminal);
snterminaux.reserve(nb_nterminal);
successeur.reserve(200);
action.reserve(200);
grammaire.reserve(nb_prod);
chargerGrammaire(fichier_grammaire);
calculerPremier();
calculerSuivant();
creerCollectionItem();
//afficherCollectionItem();
construireTableAnalyse();
//afficherTableAnalyse();
}
void ASantaxique::chargerGrammaire(char* fichier_grammaire)
{
int index=0;
terminaux.push_back("epsilon");
sterminaux.push_back(new Terminal(0));
terminaux.push_back(MARQUEUR_FIN);
sterminaux.push_back(new Terminal(1));
ifstream ifs(fichier_grammaire);
if(ifs.bad()){
cout << "Erreu lors de l'ouverture du fichier du grammaire" << endl;
exit(1);
}
string temp;
ifs >> temp;
if(temp!="terminal"){
cout<< "Erreur dans la grammaire, elle doit commencer par 'terminal'"<<endl;
exit(2);
}
ifs >> temp;
while(!ifs.eof()){
while(temp != "nonterminal" && !ifs.eof()){
terminaux.push_back(temp);
Terminal* t = new Terminal(sterminaux.size());
sterminaux.push_back(t);
ifs >> temp;
}
if(ifs.eof()){
cout<< "Erreur dans la grammaire, elle doit contenir 'nonterminal' apres la section terminal"<<endl;
exit(2);
}
ifs >> temp;
while(temp != "indication" && !ifs.eof()){
snterminaux.push_back(new NonTerminal(snterminaux.size()));
nterminaux.push_back(temp);
ifs >> temp;
}
if(ifs.eof()){
cout<< "Erreur dans la grammaire, elle doit contenir le champ 'indication'"<<endl;
exit(3);
}
ifs >> temp;
while(temp!="grammaire" && !ifs.eof()){
ifs >> temp;
//travaille pour indication
}
if(ifs.eof()){
cout<< "Erreur dans la grammaire, elle doit contenir le champ 'grammaire'"<<endl;
exit(4);
}
while(!ifs.eof()){
ifs >> temp;
if((index=indexDuNonTerminal(temp))==-1 ){
cout<< "Erreur dans la grammaire: symbole '" << temp << "' non declaré"<<endl;
exit(4);
}
//NonTerminal* ntermianltemp = new NonTerminal(index);
Production* prod = new Production(snterminaux[index]);
ifs >> temp;
if(temp!="="){
cout<< "Erreur dans la grammaire: partie gauche du production doit etre suivie par partie droite"<<endl;
exit(5);
}
ifs >> temp;
if(temp==";"){
cout<< "Erreur dans la grammaire: partie droite vide"<<endl;
exit(6);
}
while(temp != ";" && !ifs.eof()){
if((index=indexDuNonTerminal(temp))!=-1){
prod->addSymboleADroite(snterminaux[index]);
}
else if((index=indexDuTerminal(temp))!=-1){
prod->addSymboleADroite(sterminaux[index]);
}
else{
cout<< "Erreur dans la grammaire: symbole '" << temp << "' non declaré"<<endl;
exit(4);
}
ifs >> temp;
}
if(temp!=";"){
cout << "Erreur dans la grammaire, il manque un ';' "<< endl;
exit(7);
}
grammaire.push_back(prod);
//travaille pour grammaire
//travaille pour grammaire
}
}}
void ASantaxique::afficherGrammaire()
{ cout<<"La grammaire:"<<endl;
for(unsigned int i=0;i<grammaire.size();i++){
cout << "\t"<< nterminaux[grammaire[i]->getGauche()->getId()] << " := " ;
for (unsigned int j = 0;j<grammaire[i]->getDroite().size();j++){
if( grammaire[i]->getDroite()[j]->isTerminal())
cout << terminaux[grammaire[i]->getDroite()[j]->getId()] << "";
else
cout << nterminaux[grammaire[i]->getDroite()[j]->getId()] << "";
}
cout << endl;
}
}
ASantaxique::~ASantaxique(void)
{
}
int ASantaxique::indexDuTerminal(std::string terminal)
{
int f=terminaux.size();
for(int i=0;i<f;i++)
if(terminaux[i]==terminal)return i;
return -1;
}
int ASantaxique::indexDuNonTerminal(std::string nterminal)
{ int f=nterminaux.size();
for(int i=0;i<f;i++)
if(nterminaux[i]==nterminal)return i;
return -1;
}
void ASantaxique::calculerPremier(){
for(unsigned int i=0;i<grammaire.size();i++){
if(grammaire[i]->getDroite().size()==1 && grammaire[i]->getDroite()[0]->isTerminal() && grammaire[i]->getDroite()[0]->getId()==0){
grammaire[i]->getGauche()->ajouterPremier(0);
//cout<< snterminaux[0]->getPremier().size();
}
}
bool continuer = true;
while(continuer){
continuer=false;
for(unsigned int i=0;i<grammaire.size();i++){
unsigned int j;
continuer = continuer || grammaire[i]->getGauche()->ajouterPremier(grammaire[i]->getDroite()[0],true);
if(grammaire[i]->getDroite()[0]->isContientEpsilon()){
for(j=1;j<grammaire[i]->getDroite().size();j++){
continuer = continuer || grammaire[i]->getGauche()->ajouterPremier(grammaire[i]->getDroite()[j],true);
if(!grammaire[i]->getDroite()[j]->isContientEpsilon())break;
}
if(j==grammaire[i]->getDroite().size())continuer = continuer || grammaire[i]->getGauche()->ajouterPremier(0);
}
}}}
void ASantaxique::afficherPremier(){
/*cout << "Terminaux" <<endl ;
for(unsigned int i=0;i<terminaux.size();i++){
cout << "Premier( " <<terminaux[i] << " ) = " ;
for(unsigned int j=0;j<sterminaux[i]->getPremier().size();j++){
cout << terminaux[sterminaux[i]->getPremier()[j]] << " ";
}
cout <<endl;
} */
cout <<endl<< "Premier des Non Terminaux" <<endl;
for(unsigned int i=0;i<nterminaux.size();i++){
cout << "Premier( " <<nterminaux[i] << " ) = " ;
for(unsigned int j=0;j<snterminaux[i]->getPremier().size();j++){
cout << terminaux[snterminaux[i]->getPremier()[j]] << " ";
}
cout <<endl;
}}
void ASantaxique::calculerSuivant()
{
snterminaux[0]->ajouterSuivant(1);
for(unsigned int i=0;i<grammaire.size();i++){
for(unsigned int j=0;j<grammaire[i]->getDroite().size()-1;j++){
if(!grammaire[i]->getDroite()[j]->isTerminal()){
(grammaire[i]->getDroite()[j])->ajouterPremierASuivant(grammaire[i]->getDroite()[j+1],true);
}
} }
bool continuer = true;
while(continuer){
continuer=false;
for(unsigned int i=0;i<grammaire.size();i++){
unsigned int j;
for(j=0;j<grammaire[i]->getDroite().size();j++){
unsigned int k;
if(!grammaire[i]->getDroite()[j]->isTerminal()){
for(k=j+1;k<grammaire[i]->getDroite().size();k++){
if(!grammaire[i]->getDroite()[k]->isContientEpsilon())break;
}
if(k==grammaire[i]->getDroite().size())
continuer=continuer||grammaire[i]->getDroite()[j]->ajouterSuivant(grammaire[i]->getGauche());
} }
}
}
}