Initial Commit
This commit is contained in:
154
src/analyseur_lexical.c
Normal file
154
src/analyseur_lexical.c
Normal file
@@ -0,0 +1,154 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "symboles.h"
|
||||
#include "analyseur_lexical.h"
|
||||
#include "util.h"
|
||||
|
||||
#define YYTEXT_MAX 100
|
||||
#define is_num(c)(('0' <= (c)) && ((c) <= '9'))
|
||||
#define is_maj(c)(('A' <= (c)) && ((c) <= 'Z'))
|
||||
#define is_min(c)(('a' <= (c)) && ((c) <= 'z'))
|
||||
#define is_alpha(c)(is_maj(c) || is_min(c) || (c) == '_' || (c) == '$')
|
||||
#define is_alphanum(c)(is_num((c)) || is_alpha((c)))
|
||||
|
||||
extern FILE *yyin;
|
||||
|
||||
char *tableMotsClefs[] = {
|
||||
"si",
|
||||
};
|
||||
|
||||
int codeMotClefs[] = {
|
||||
SI,
|
||||
};
|
||||
|
||||
char yytext[YYTEXT_MAX];
|
||||
int yyleng;
|
||||
int nbMotsClefs = 9;
|
||||
/* Compter les lignes pour afficher les messages d'erreur avec numero ligne */
|
||||
int nb_ligne = 1;
|
||||
|
||||
/*******************************************************************************
|
||||
* Fonction qui ignore les espaces et commentaires.
|
||||
* Renvoie -1 si arrivé à la fin du fichier, 0 si tout va bien
|
||||
******************************************************************************/
|
||||
int mangeEspaces()
|
||||
{
|
||||
char c = fgetc(yyin);
|
||||
int comment = 0;
|
||||
while( comment || (c == ' ') || (c == '\n') || (c == '\t') || (c == '#' ) ) {
|
||||
if( c == '#' ) {
|
||||
comment = 1;
|
||||
}
|
||||
if( c == '\n' ) {
|
||||
nb_ligne++;
|
||||
comment = 0;
|
||||
}
|
||||
c = fgetc(yyin);
|
||||
}
|
||||
if ( feof(yyin) ) {
|
||||
return -1;
|
||||
}
|
||||
ungetc(c, yyin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Lit un caractère et le stocke dans le buffer yytext
|
||||
******************************************************************************/
|
||||
char lireCar(void)
|
||||
{
|
||||
yytext[yyleng++] = fgetc(yyin);
|
||||
yytext[yyleng] = '\0';
|
||||
return yytext[yyleng - 1];
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Remet le dernier caractère lu au buffer clavier et enlève du buffer yytext
|
||||
******************************************************************************/
|
||||
void delireCar()
|
||||
{
|
||||
char c;
|
||||
c = yytext[yyleng - 1];
|
||||
yytext[--yyleng] = '\0';
|
||||
ungetc(c, yyin);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Fonction principale de l'analyseur lexical, lit les caractères de yyin et
|
||||
* renvoie les tokens sous forme d'entier. Le code de chaque unité est défini
|
||||
* dans symboles.h sinon (mot clé, idententifiant, etc.). Pour les tokens de
|
||||
* type ID_FCT, ID_VAR et NOMBRE la valeur du token est dans yytext, visible
|
||||
* dans l'analyseur syntaxique.
|
||||
******************************************************************************/
|
||||
int yylex(void)
|
||||
{
|
||||
char c;
|
||||
int i;
|
||||
yytext[yyleng = 0] = '\0';
|
||||
// COMPLÉTER
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Fonction auxiliaire appelée par l'analyseur syntaxique tout simplement pour
|
||||
* afficher des messages d'erreur et l'arbre XML
|
||||
******************************************************************************/
|
||||
void nom_token( int token, char *nom, char *valeur ) {
|
||||
int i;
|
||||
|
||||
strcpy( nom, "symbole" );
|
||||
if(token == POINT_VIRGULE) strcpy( valeur, "POINT_VIRGULE");
|
||||
else if(token == PLUS) strcpy(valeur, "PLUS");
|
||||
else if(token == MOINS) strcpy(valeur, "MOINS");
|
||||
else if(token == FOIS) strcpy(valeur, "FOIS");
|
||||
else if(token == DIVISE) strcpy(valeur, "DIVISE");
|
||||
else if(token == PARENTHESE_OUVRANTE) strcpy(valeur, "PARENTHESE_OUVRANTE");
|
||||
else if(token == PARENTHESE_FERMANTE) strcpy(valeur, "PARENTHESE_FERMANTE");
|
||||
else if(token == CROCHET_OUVRANT) strcpy(valeur, "CROCHET_OUVRANT");
|
||||
else if(token == CROCHET_FERMANT) strcpy(valeur, "CROCHET_FERMANT");
|
||||
else if(token == ACCOLADE_OUVRANTE) strcpy(valeur, "ACCOLADE_OUVRANTE");
|
||||
else if(token == ACCOLADE_FERMANTE) strcpy(valeur, "ACCOLADE_FERMANTE");
|
||||
else if(token == EGAL) strcpy(valeur, "EGAL");
|
||||
else if(token == INFERIEUR) strcpy(valeur, "INFERIEUR");
|
||||
else if(token == ET) strcpy(valeur, "ET");
|
||||
else if(token == OU) strcpy(valeur, "OU");
|
||||
else if(token == NON) strcpy(valeur, "NON");
|
||||
else if(token == FIN) strcpy(valeur, "FIN");
|
||||
else if(token == VIRGULE) strcpy(valeur, "VIRGULE");
|
||||
|
||||
else if( token == ID_VAR ) {
|
||||
strcpy( nom, "id_variable" );
|
||||
strcpy( valeur, yytext );
|
||||
}
|
||||
else if( token == ID_FCT ) {
|
||||
strcpy( nom, "id_fonction" );
|
||||
strcpy( valeur, yytext );
|
||||
}
|
||||
else if( token == NOMBRE ) {
|
||||
strcpy( nom, "nombre" );
|
||||
strcpy( valeur, yytext );
|
||||
}
|
||||
else {
|
||||
strcpy( nom, "mot_clef" );
|
||||
for(i=0; i < nbMotsClefs; i++){
|
||||
if( token == codeMotClefs[i] ){
|
||||
strcpy( valeur, tableMotsClefs[i] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Fonction auxiliaire appelée par le compilo en mode -l, pour tester l'analyseur
|
||||
* lexical et, étant donné un programme en entrée, afficher la liste des tokens.
|
||||
******************************************************************************/
|
||||
|
||||
void test_yylex_internal(FILE *yyin) {
|
||||
int uniteCourante;
|
||||
char nom[100];
|
||||
char valeur[100];
|
||||
do {
|
||||
uniteCourante = yylex();
|
||||
nom_token( uniteCourante, nom, valeur );
|
||||
printf("%s\t%s\t%s\n", yytext, nom, valeur);
|
||||
} while (uniteCourante != FIN);
|
||||
}
|
||||
17
src/test_yylex.c
Normal file
17
src/test_yylex.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "analyseur_lexical.h"
|
||||
#include "symboles.h"
|
||||
|
||||
char yytext[100];
|
||||
FILE *yyin;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
yyin = fopen(argv[1], "r");
|
||||
if(yyin == NULL){
|
||||
fprintf(stderr, "impossible d'ouvrir le fichier %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
test_yylex_internal(yyin);
|
||||
return 0;
|
||||
}
|
||||
102
src/util.c
Normal file
102
src/util.c
Normal file
@@ -0,0 +1,102 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
extern int nb_ligne;
|
||||
int indent_xml = 0;
|
||||
int indent_step = 1; // set to 0 for no indentation
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void erreur(char *message) {
|
||||
fprintf (stderr, "Ligne %d : ", nb_ligne);
|
||||
fprintf (stderr, "%s\n", message);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void erreur_1s(char *message, char *s) {
|
||||
fprintf( stderr, "Ligne %d : ", nb_ligne );
|
||||
fprintf( stderr, message, s );
|
||||
fprintf( stderr, "\n" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
char *duplique_chaine(char *src) {
|
||||
char *dest = malloc(sizeof(char) * strlen(src));
|
||||
strcpy(dest, src);
|
||||
return dest;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void indent() {
|
||||
int i;
|
||||
for( i = 0; i < indent_xml; i++ ) {
|
||||
printf( " " );
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void affiche_balise_ouvrante(const char *fct_, int trace_xml) {
|
||||
if( trace_xml ) {
|
||||
indent();
|
||||
indent_xml += indent_step ;
|
||||
fprintf (stdout, "<%s>\n", fct_);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void affiche_balise_fermante(const char *fct_, int trace_xml) {
|
||||
if(trace_xml) {
|
||||
indent_xml -= indent_step ;
|
||||
indent();
|
||||
fprintf (stdout, "</%s>\n", fct_);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void affiche_texte(char *texte_, int trace_xml) {
|
||||
if(trace_xml) {
|
||||
indent();
|
||||
fprintf (stdout, "%s\n", texte_);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void affiche_xml_texte( char *texte_ ) {
|
||||
int i = 0;
|
||||
while( texte_[ i ] != '\0' ) {
|
||||
if( texte_[ i ] == '<' ) {
|
||||
fprintf( stdout, "<" );
|
||||
}
|
||||
else if( texte_[ i ] == '>' ) {
|
||||
fprintf( stdout, ">" );
|
||||
}
|
||||
else if( texte_[ i ] == '&' ) {
|
||||
fprintf( stdout, "&" );
|
||||
}
|
||||
else {
|
||||
putchar( texte_[i] );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void affiche_element(char *fct_, char *texte_, int trace_xml) {
|
||||
if(trace_xml) {
|
||||
indent();
|
||||
fprintf (stdout, "<%s>", fct_ );
|
||||
affiche_xml_texte( texte_ );
|
||||
fprintf (stdout, "</%s>\n", fct_ );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user