Skip to content
Snippets Groups Projects
Select Git revision
  • e801d84d6f715b1cecadf4a1323a1b49c8a6d1f0
  • master default
  • object
  • develop protected
  • private_algos
  • cuisine
  • SMOTE
  • revert-76c4cca5
  • archive protected
  • no_graphviz
  • 0.0.2
  • 0.0.1
12 results

test_ExecClassif.py

Blame
  • json_parser.c 15.43 KiB
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include"json_parser.h"
    
    
    /* --------------------------------------------------------------------------- */
    /* quelques macros utiles */
    /* --------------------------------------------------------------------------- */
    
    #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)))
    
    void initialise_premiers(json_parser_ctx *ctx);
    void initialise_suivants(json_parser_ctx *ctx);
    int yylex(json_parser_ctx *ctx);
    
    
    json_struct *json_parse(char *filename)
    {
      return json_parse_full(filename, 0);
    }
    
    json_struct *json_parse_full(char *filename, int trace_xml)
    {
      json_parser_ctx *ctx=json_parser_init_full(filename, trace_xml);
      json_struct *root = structure(ctx);
      fclose(ctx->yyin);
      free(ctx);
      return root;
    }
    
    json_parser_ctx *json_parser_init(char *filename)
    {
      return json_parser_init_full(filename, 0);
    }
    
    json_parser_ctx *json_parser_init_full(char *filename, int trace_xml)
    {
      json_parser_ctx *ctx = (json_parser_ctx *) malloc(sizeof(json_parser_ctx));
      ctx->nb_ligne = 1;
      ctx->trace_xml = trace_xml;
      ctx->indent_xml = 0;
      ctx->indent_step = 1;
      initialise_premiers(ctx);
      initialise_suivants(ctx);
      
      ctx->tableMotsClefs[0] =  (char *) "true"; 
      ctx->tableMotsClefs[1] =  (char *) "false"; 
      ctx->tableMotsClefs[2] =  (char *) "null"; 
      ctx->codeMotClefs[0] =  CONSTANT; 
      ctx->codeMotClefs[1] =  CONSTANT; 
      ctx->codeMotClefs[2] =  CONSTANT;
    
      ctx->yyin = fopen(filename, "r");
      if(ctx->yyin == NULL){
        fprintf(stderr, "cannot open file %s\n", filename);
        exit(1);
      }
      
      ctx->uc = yylex(ctx);
      return ctx;
    }
    
    /*-------------------------------------------------------------------------*/
    /* Affiche le message d'erreur donné en paramètre, avec le numéro de ligne */
    /*-------------------------------------------------------------------------*/
    void erreur(json_parser_ctx *ctx, char *message) {
      fprintf (stderr, "ERREUR ligne %d : ", ctx->nb_ligne);
      fprintf (stderr, "%s\n", message);
      exit(1);
    }
    
    /*******************************************************************************
     * Fonction qui ignore les espaces et commentaires. 
     * Renvoie -1 si arrivé à la fin du fichier, 0 si tout va bien 
     ******************************************************************************/
    int mangeEspaces(json_parser_ctx *ctx)
    { 
      char c = fgetc(ctx->yyin);
      int comment = 0;
      while( comment || (c == ' ') || (c == '\n') || (c == '\t') || (c == '#' ) || (c == '\r') ) {
        if( c == '#' ) {
            comment = 1;
        }
        if( (c == '\n') || (c == '\r')) {
          ctx->nb_ligne++;
          comment = 0;
        }
        c = fgetc(ctx->yyin);    
      }
      if ( feof(ctx->yyin) ) {
        return -1;
      }    
      ungetc(c, ctx->yyin);
      return 0;
    }
    
    /*******************************************************************************
     * Lit un caractère et le stocke dans le buffer yytext 
     ******************************************************************************/
    char lireCar(json_parser_ctx *ctx)
    {
      ctx->yytext[ctx->yyleng++] = fgetc(ctx->yyin);
      ctx->yytext[ctx->yyleng] = '\0';
      return ctx->yytext[ctx->yyleng - 1];
    }
    
    /*******************************************************************************
     * Remet le dernier caractère lu au buffer clavier et enlève du buffer yytext 
     ******************************************************************************/
    void delireCar(json_parser_ctx *ctx)
    {
      char c;
      c = ctx->yytext[ctx->yyleng - 1];
      ctx->yytext[--ctx->yyleng] = '\0';
      ungetc(c, ctx->yyin);
    }
    
    /*******************************************************************************
     * Fonction principale de l'analyseur lexical, lit les caractères de yyin et
     * renvoie les tokens sous forme d'entier. Pour les tokens de 
     * type NUMBER et STRING la valeur du token est dans yytext, visible 
     * dans l'analyseur syntaxique.
     ******************************************************************************/
    int yylex(json_parser_ctx *ctx)
    {
      char c;
      int i;
      ctx->yytext[ctx->yyleng = 0] = '\0';
      
      /* Si j'ai trouvé la fin du fichier en lisant des espaces ... */
      if( mangeEspaces(ctx) == -1 ) {
        return FIN; /* Renvoie le marqueur de fin d'entrée */
      }  
      
      c = lireCar(ctx); 
      /* Caractères uniques non-ambigus */
      if(c == ',') return VIRGULE;
      if(c == ':') return COLON;
      if(c == '{') return ACCOLADE_OUVRANTE;
      if(c == '}') return ACCOLADE_FERMANTE;
      if(c == '[') return CROCHET_OUVRANT;
      if(c == ']') return CROCHET_FERMANT;
      
      if(is_num(c) || (c == '-')){
        do{
          c = lireCar(ctx);
        } while(is_num(c) || (c == '.'));
        delireCar(ctx);
        return NUMBER;
      }  
    
      if(c == '"') {
        ctx->yyleng = 0;
        c = lireCar(ctx);
        while(c != '"'){
          if(ctx->yyleng >= YYTEXT_MAX){
    	erreur(ctx, (char *) "constante trop longue");
          }
          c = lireCar(ctx);
        } 
        ctx->yytext[--ctx->yyleng] = '\0';
        //    printf("c = %c yytext = %s\n", c, ctx->yytext); 
        return STRING;
      }
    
      while( is_alphanum(c) ) {
        c = lireCar(ctx);
      }
      delireCar(ctx);
      
      for(i=0; i < NB_MOTS_CLEFS; i++){
        if(!strcmp(ctx->yytext, ctx->tableMotsClefs[i])){
          return ctx->codeMotClefs[i];
        }
      }
    
      
      if( feof( ctx->yyin ) ) {
      	return '.';
      }
      if(ctx->yyleng == 0) {
        fprintf( stderr, "Ligne %d: caractère invalide: %c\n", ctx->nb_ligne, c );
        exit(-1);
      }
      return -1;
    }
    
    /*-------------------------------------------------------------------------*/
    
    void indent(json_parser_ctx *ctx) {
        int i;
        for( i = 0; i < ctx->indent_xml; i++ ) {
          printf( "  " );
        }    
    }
    /*-------------------------------------------------------------------------*/
    
    
    void consommer(json_parser_ctx *ctx, int c ) {
      if( ctx->uc == c ){
        //    affiche_feuille(ctx);
        ctx->uc = yylex(ctx); /* consommer le caractère */
      }
      else
        erreur(ctx,  (char *) "erreure lexicale" );
    }
    
    /*-------------------------------------------------------------------------*/
    void affiche_balise_ouvrante(json_parser_ctx *ctx, const char *fct_)
    {
      if(ctx->trace_xml ) {
        indent(ctx);
        ctx->indent_xml += ctx->indent_step ;
        fprintf (stdout, "<%s>\n", fct_);
      }  
    }
    
    /*-------------------------------------------------------------------------*/
    
    void affiche_balise_fermante(json_parser_ctx *ctx, const char *fct_) {
      if(ctx->trace_xml) {
        ctx->indent_xml -= ctx->indent_step ;
        indent(ctx);
        fprintf (stdout, "</%s>\n", fct_);
      }
    }
    
    /*-------------------------------------------------------------------------*/
    
    void affiche_texte(json_parser_ctx *ctx, char *texte_) {
      if(ctx->trace_xml) {
        indent(ctx);
        fprintf (stdout, "%s\n", texte_);
      }
    }
    
    /*-------------------------------------------------------------------------*/
    
    void affiche_xml_texte(json_parser_ctx *ctx, char *texte_ ) {
      int i = 0;
      while( texte_[ i ] != '\0' ) {
        if( texte_[ i ] == '<' ) {
          fprintf( stdout, "&lt;" );
        }
        else if( texte_[ i ] == '>' ) {
          fprintf( stdout, "&gt;" );
        }
        else if( texte_[ i ] == '&' ) {
          fprintf( stdout, "&amp;" );
        }
        else {
          putchar( texte_[i] );
        }
        i++;
      }
    }
    
    /*-------------------------------------------------------------------------*/
    
    void affiche_element(json_parser_ctx *ctx, char *fct_, char *texte_, int trace_xml) {
      if(trace_xml) {
        indent(ctx);
        fprintf (stdout, "<%s>", fct_ );
        affiche_xml_texte(ctx,  texte_ );
        fprintf (stdout, "</%s>\n", fct_ );
      }
    }
    
    /* --------------------------------------------------------------------------- */
    
    
    int est_suivant(json_parser_ctx *ctx, int terminal, int non_terminal)
    {
      return ctx->suivants[non_terminal][terminal];
    }
    
    int est_premier(json_parser_ctx *ctx, int terminal, int non_terminal)
    {
      return ctx->premiers[non_terminal][terminal];
    }
    
    
    /* ################################################################
    First(structure) =  NUMBER  CONSTANT  '{'  '['  STRING 
    First(list) =  '[' 
    First(list_structure) =  ε  CONSTANT  STRING  NUMBER  '{'  '[' 
    First(list_structure2) =  ε  ',' 
    First(object) =  '{' 
    First(list_attr_val) =  ε  STRING 
    First(list_attr_val2) =  ε  ',' 
    First(attr_val) =  STRING 
    ################################################################ */
    
    void initialise_premiers(json_parser_ctx *ctx){
      int i,j;
      
      for(i=0; i <= NB_NON_TERMINAUX; i++)
        for(j=0; j <= NB_TERMINAUX; j++)
          ctx->premiers[i][j] = 0;
      
      ctx->premiers[_structure_][NUMBER] = 1;
      ctx->premiers[_structure_][CONSTANT] = 1;
      ctx->premiers[_structure_][STRING] = 1;
      ctx->premiers[_structure_][CROCHET_OUVRANT] = 1;
      ctx->premiers[_structure_][ACCOLADE_OUVRANTE] = 1;
    
      ctx->premiers[_list_structure_][EPSILON] = 1;
      ctx->premiers[_list_structure_][CONSTANT] = 1;
      ctx->premiers[_list_structure_][STRING] = 1;
      ctx->premiers[_list_structure_][NUMBER] = 1;
      ctx->premiers[_list_structure_][ACCOLADE_OUVRANTE] = 1;
      ctx->premiers[_list_structure_][CROCHET_OUVRANT] = 1;
    
      ctx->premiers[_list_structure2_][EPSILON] = 1;
      ctx->premiers[_list_structure2_][VIRGULE] = 1;
    
      ctx->premiers[_list_attr_val_][EPSILON] = 1;
      ctx->premiers[_list_attr_val_][STRING] = 1;
    
      ctx->premiers[_list_attr_val2_][EPSILON] = 1;
      ctx->premiers[_list_attr_val2_][VIRGULE] = 1;
    
      ctx->premiers[_attr_val_][STRING] = 1;
    }
    
    
    /* ################################################################
    Follow(structure) =  '}'  ']'  '.'  ',' 
    Follow(list_structure) =  ']' 
    Follow(list_structure2) =  ']' 
    Follow(list_attr_val) =  '}' 
    Follow(list_attr_val2) =  '}' 
    Follow(attr_val) =  '}'  ',' 
    ################################################################*/
    
    void initialise_suivants(json_parser_ctx *ctx){
      int i,j;
      
      for(i=0; i <= NB_NON_TERMINAUX; i++)
        for(j=0; j <= NB_TERMINAUX; j++)
          ctx->suivants[i][j] = 0;
    
      ctx->suivants[_structure_][ACCOLADE_FERMANTE] = 1;
      ctx->suivants[_structure_][CROCHET_FERMANT] = 1;
      ctx->suivants[_structure_][VIRGULE] = 1;
    
      ctx->suivants[_list_structure_][CROCHET_FERMANT] = 1;
    
      ctx->suivants[_list_structure2_][CROCHET_FERMANT] = 1;
    
      ctx->suivants[_list_attr_val_][ACCOLADE_FERMANTE] = 1;
    
      ctx->suivants[_list_attr_val2_][ACCOLADE_FERMANTE] = 1;
    
      ctx->suivants[_attr_val_][ACCOLADE_FERMANTE] = 1;
      ctx->suivants[_attr_val_][VIRGULE] = 1;
    }
    
    json_struct *structure(json_parser_ctx *ctx);
    json_struct *list (json_parser_ctx *ctx);
    json_struct *list_structure(json_parser_ctx *ctx);
    json_struct *list_structure2(json_parser_ctx *ctx);
    json_attr_val *list_attr_val(json_parser_ctx *ctx);
    json_attr_val *list_attr_val2(json_parser_ctx *ctx);
    json_attr_val *attr_val(json_parser_ctx *ctx);
    
    /*---------------------------------------------------------*/
    /* structure -> '[' list_structure ']' | '{' list_attr_val '}' | STRING | NUMBER | CONSTANT */
    /*---------------------------------------------------------*/
    json_struct *structure(json_parser_ctx *ctx)
    {
      float num;
      char *string;
      int constant;
      affiche_balise_ouvrante(ctx, __FUNCTION__);
    
      if(ctx->uc == CROCHET_OUVRANT){
        consommer(ctx, CROCHET_OUVRANT);
        json_struct *s = list_structure(ctx);
        consommer(ctx, CROCHET_FERMANT);
        affiche_balise_fermante(ctx, __FUNCTION__);
        return json_new_list(s);
      }
      
      if(ctx->uc == ACCOLADE_OUVRANTE){
        consommer(ctx, ACCOLADE_OUVRANTE);
        json_attr_val *l = list_attr_val(ctx);
        consommer(ctx, ACCOLADE_FERMANTE);
        affiche_balise_fermante(ctx, __FUNCTION__);
        return json_new_avl(l);
      }
      
      if(ctx->uc == STRING){
        string = (ctx->yyleng == 0)? NULL : strdup(ctx->yytext);
        consommer(ctx, STRING);
        affiche_balise_fermante(ctx, __FUNCTION__);
        return json_new_string(string);
      }
    
      if(ctx->uc == NUMBER){
        num = atof(ctx->yytext);
        consommer(ctx, NUMBER);
        affiche_balise_fermante(ctx, __FUNCTION__);
        return json_new_number(num);
      }
    
      if(ctx->uc == CONSTANT){
        if(!strcmp(ctx->yytext, "true")) constant = JSON_CONST_TRUE;
        else if(!strcmp(ctx->yytext, "false")) constant = JSON_CONST_FALSE;
        else if(!strcmp(ctx->yytext, "null")) constant = JSON_CONST_NULL;
        else constant = -1;
        consommer(ctx, CONSTANT);
        affiche_balise_fermante(ctx, __FUNCTION__);
        return json_new_constant(constant);
      }
      erreur(ctx,  (char *) "" );
      return NULL;
    }
    
    /*---------------------------------------------------------*/
    /* list_structure -> structure list_structure2 | epsilon */
    /*---------------------------------------------------------*/
    
    json_struct *list_structure(json_parser_ctx *ctx)
    {
      affiche_balise_ouvrante(ctx, __FUNCTION__);
      if(est_premier(ctx, ctx->uc, _structure_)) {
        json_struct *head = structure(ctx);
        json_struct *tail = list_structure2(ctx);
        head->next = tail;
        affiche_balise_fermante(ctx, __FUNCTION__);
        return head;
      }
      if(est_suivant(ctx, ctx->uc, _list_structure_)) {
        affiche_balise_fermante(ctx, __FUNCTION__);
        return NULL;
      }
      erreur(ctx, (char *)"");
      return NULL;
    }
    
    /*---------------------------------------------------------*/
    /* list_structure2 -> ',' structure list_structure2 | epsilon */
    /*---------------------------------------------------------*/
    
    json_struct *list_structure2(json_parser_ctx *ctx)
    {
      affiche_balise_ouvrante(ctx, __FUNCTION__);
      if(ctx->uc == VIRGULE){
        consommer(ctx, VIRGULE);
        json_struct *head = structure(ctx);
        json_struct *tail = list_structure2(ctx);
        head->next = tail;
        affiche_balise_fermante(ctx, __FUNCTION__);
        return head;
      }
      
      if(est_suivant(ctx, ctx->uc, _list_structure2_)) {
        affiche_balise_fermante(ctx, __FUNCTION__);
        return NULL;
      }
      erreur(ctx, (char *)"");
      return NULL;
    }
    
    /*---------------------------------------------------------*/
    /* list_attr_val -> attr_val list_attr_val2 | epsilon */
    /*---------------------------------------------------------*/
    json_attr_val *list_attr_val(json_parser_ctx *ctx)
    {
      affiche_balise_ouvrante(ctx, __FUNCTION__);
      if(est_premier(ctx, ctx->uc, _attr_val_)){
        json_attr_val *head = attr_val(ctx);
        json_attr_val *tail = list_attr_val2(ctx);
        head->next = tail;
        affiche_balise_fermante(ctx, __FUNCTION__);
        return head;
      }
      
      if(est_suivant(ctx, ctx->uc, _list_attr_val_)) {
        affiche_balise_fermante(ctx, __FUNCTION__);
        return NULL;
      }
      erreur(ctx, (char *)"");
      return NULL;
    }
    
    /*---------------------------------------------------------*/
    /* list_attr_val2 -> ',' attr_val list_attr_val2 | epsilon */
    /*---------------------------------------------------------*/
    
    json_attr_val *list_attr_val2(json_parser_ctx *ctx)
    {
      affiche_balise_ouvrante(ctx, __FUNCTION__);
      if(ctx->uc == VIRGULE){
        consommer(ctx, VIRGULE);
        json_attr_val *head = attr_val(ctx);
        json_attr_val *tail = list_attr_val2(ctx);
        head->next = tail;
        affiche_balise_fermante(ctx, __FUNCTION__);
        return head;
      }
      
      if(est_suivant(ctx, ctx->uc, _list_attr_val2_)) {
        affiche_balise_fermante(ctx, __FUNCTION__);
        return NULL;
      }
      
      erreur(ctx, (char *)"");
      return NULL;
    }
    
    /*---------------------------------------------------------*/
    /* attr_val -> STRING ':' structure */
    /*---------------------------------------------------------*/
    
    json_attr_val *attr_val(json_parser_ctx *ctx)
    {
      char *attr;
      affiche_balise_ouvrante(ctx, __FUNCTION__);
      if(ctx->uc == STRING)
        {attr = strdup(ctx->yytext);}
      consommer(ctx, STRING);
      consommer(ctx, COLON);
      json_struct *val = structure(ctx);
      affiche_balise_fermante(ctx, __FUNCTION__);
      return json_new_attr_val(attr, val, NULL);
    }
    
    
    /*int main(int arc, char *argv[])
    {
      json_parser_ctx *ctx = json_parser_init(argv[1]);
      json_struct *s = structure(ctx);
      json_print_struct(stdout, s);
      json_free_struct(s);
      }*/