diff --git a/maca_common/src/json_parser.c b/maca_common/src/json_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..ecc4ffcb28539c0b244dc94882f6af984f8e0c48 --- /dev/null +++ b/maca_common/src/json_parser.c @@ -0,0 +1,633 @@ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include"json_tree.h" + +#define YYTEXT_MAX 100 +#define EPSILON 0 + +/* symboles non terminaux */ +#define NB_NON_TERMINAUX 8 + +#define _structure_ 1 +#define _list_ 2 +#define _object_ 3 +#define _list_structure_ 4 +#define _list_structure2_ 5 +#define _attr_val_ 6 +#define _list_attr_val_ 7 +#define _list_attr_val2_ 8 + +/* symboles terminaux */ +#define NB_TERMINAUX 10 + +#define CROCHET_OUVRANT 1 +#define CROCHET_FERMANT 2 +#define VIRGULE 3 +#define ACCOLADE_OUVRANTE 4 +#define ACCOLADE_FERMANTE 5 +#define COLON 6 +#define STRING 7 +#define NUMBER 8 +#define CONSTANT 9 +#define FIN 10 + +#define NB_MOTS_CLEFS 3 + +/* --------------------------------------------------------------------------- */ +/* 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))) + + +typedef struct { + FILE *yyin; + int uc; /* current token */ + int comment; + char yytext[YYTEXT_MAX]; + int yyleng; + /* Compter les lignes pour afficher les messages d'erreur avec numero ligne */ + int nb_ligne; + int trace_xml; + int premiers[NB_NON_TERMINAUX+1][NB_TERMINAUX+1]; + int suivants[NB_NON_TERMINAUX+1][NB_TERMINAUX+1]; + int indent_xml; + int indent_step; // set to 0 for no indentation + char *tableMotsClefs[NB_MOTS_CLEFS]; + int codeMotClefs[NB_MOTS_CLEFS]; +}json_parser_ctx; + + + +void initialise_premiers(json_parser_ctx *ctx); +void initialise_suivants(json_parser_ctx *ctx); +int yylex(json_parser_ctx *ctx); + +json_parser_ctx *json_parser_init(char *filename) +{ + json_parser_ctx *ctx = malloc(sizeof(json_parser_ctx)); + ctx->nb_ligne = 1; + ctx->trace_xml = 1; + ctx->indent_xml = 0; + ctx->indent_step = 1; + initialise_premiers(ctx); + initialise_suivants(ctx); + + ctx->tableMotsClefs[0] = "true"; + ctx->tableMotsClefs[1] = "false"; + ctx->tableMotsClefs[2] = "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 == '"') { + do{ + c = lireCar(ctx); + if(ctx->yyleng >= YYTEXT_MAX){ + erreur(ctx, "constante trop longue"); + } + } while(c != '"'); + /* 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); + } + +} + +/*-------------------------------------------------------------------------*/ + +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, "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, "<" ); + } + else if( texte_[ i ] == '>' ) { + fprintf( stdout, ">" ); + } + else if( texte_[ i ] == '&' ) { + fprintf( stdout, "&" ); + } + 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_][CROCHET_OUVRANT] = 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[_object_][ACCOLADE_OUVRANTE] = 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) = ']' '}' '.' ',' +Follow(list_structure) = ']' +Follow(list_structure2) = ']' +Follow(object) = ']' '}' '.' ',' +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_][CROCHET_FERMANT] = 1; + ctx->suivants[_list_][ACCOLADE_FERMANTE] = 1; + ctx->suivants[_list_][VIRGULE] = 1; + + ctx->suivants[_list_structure_][CROCHET_FERMANT] = 1; + + ctx->suivants[_list_structure2_][CROCHET_FERMANT] = 1; + + ctx->suivants[_object_][CROCHET_FERMANT] = 1; + ctx->suivants[_object_][ACCOLADE_FERMANTE] = 1; + ctx->suivants[_object_][VIRGULE] = 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; +} + + +/* + +list, '[' = list -> '[' list_structure ']' + +list_structure, STRING = list_structure -> structure list_structure2 +list_structure, NUMBER = list_structure -> structure list_structure2 +list_structure, CONSTANT = list_structure -> structure list_structure2 +list_structure, '[' = list_structure -> structure list_structure2 +list_structure, ']' = list_structure -> ε +list_structure, '{' = list_structure -> structure list_structure2 + +list_structure2, ']' = list_structure2 -> ε +list_structure2, ',' = list_structure2 -> ',' structure + +object, '{' = object -> '{' list_attr_val '}' + +list_attr_val, '}' = list_attr_val -> ε +list_attr_val, STRING = list_attr_val -> attr_val list_attr_val2 + +list_attr_val2, '}' = list_attr_val2 -> ε +list_attr_val2, ',' = list_attr_val2 -> ',' attr_val + +attr_val, STRING = attr_val -> STRING ':' structure +*/ + + +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 *object(json_parser_ctx *ctx); +json_attr_val *attr_val(json_parser_ctx *ctx); + +/*---------------------------------------------------------*/ +/* structure -> list | object | STRING | NUMBER | CONSTANT */ +/*---------------------------------------------------------*/ +json_struct *structure(json_parser_ctx *ctx) +{ + float num; + char *string; + int constant; + affiche_balise_ouvrante(ctx, __FUNCTION__); + + if(est_premier(ctx, ctx->uc, _list_)) { + json_struct *s = list(ctx); + affiche_balise_fermante(ctx, __FUNCTION__); + return s; + } + + if(est_premier(ctx, ctx->uc, _object_)) { + json_attr_val *avl = object(ctx); + affiche_balise_fermante(ctx, __FUNCTION__); + return json_new_object(avl); + } + + if(ctx->uc == STRING){ + string = 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, "" ); + +} + +/*---------------------------------------------------------*/ +/* list -> '[' list_structure ']'*/ +/*---------------------------------------------------------*/ + +json_struct *list (json_parser_ctx *ctx) +{ + affiche_balise_ouvrante(ctx, __FUNCTION__); + consommer(ctx, CROCHET_OUVRANT); + json_struct *s = list_structure(ctx); + consommer(ctx, CROCHET_FERMANT); + affiche_balise_fermante(ctx, __FUNCTION__); + return json_new_list(s); + erreur(ctx, ""); +} + +/*---------------------------------------------------------*/ +/* 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, ""); +} + +/*---------------------------------------------------------*/ +/* 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, ""); +} + +/*---------------------------------------------------------*/ +/* object -> '{' list_attr_val '}' */ +/*---------------------------------------------------------*/ + +json_attr_val *object(json_parser_ctx *ctx) +{ + affiche_balise_ouvrante(ctx, __FUNCTION__); + consommer(ctx, ACCOLADE_OUVRANTE); + json_attr_val *l = list_attr_val(ctx); + consommer(ctx, ACCOLADE_FERMANTE); + affiche_balise_fermante(ctx, __FUNCTION__); + return l; +} + +/*---------------------------------------------------------*/ +/* 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, ""); +} + +/*---------------------------------------------------------*/ +/* 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, ""); +} + +/*---------------------------------------------------------*/ +/* 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); +} diff --git a/maca_common/src/json_tree.c b/maca_common/src/json_tree.c new file mode 100644 index 0000000000000000000000000000000000000000..afb5361ccd8fe62bcd8b332df1ce10f4851b3e93 --- /dev/null +++ b/maca_common/src/json_tree.c @@ -0,0 +1,160 @@ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include"json_tree.h" + +json_struct *json_new_struct(int type) +{ + json_struct *c = malloc(sizeof(json_struct)); + if(c == NULL){ + fprintf(stderr, "memory allocation problem !\n"); + exit(1); + } + c->type = type; + c->next = NULL; + return c; +} + +json_struct *json_new_string(char *string) +{ + json_struct *c = json_new_struct(JSON_STRING); + c->u.string = string; + return c; +} + +json_struct *json_new_number(float number) +{ + json_struct *c = json_new_struct(JSON_NUMBER); + c->u.number = number; + return c; +} + +json_struct *json_new_constant(int constant) +{ + json_struct *c = json_new_struct(JSON_CONSTANT); + c->u.constant = constant; + return c; +} + + +json_attr_val *json_new_attr_val(char *attr, json_struct *s, json_attr_val *next) +{ + json_attr_val *av = malloc(sizeof(json_attr_val)); + if(av == NULL){ + fprintf(stderr, "memory allocation problem !\n"); + exit(1); + } + av->attr = strdup(attr); + av->val = s; + av->next = next; + return av; +} + +json_struct *json_new_object(json_attr_val *avl) +{ + json_struct *c = json_new_struct(JSON_OBJECT); + c->u.attr_val_list = avl; + return c; +} + +void json_print_struct(FILE *f, json_struct *s) +{ + if(s == NULL) return; + if(s->type == JSON_OBJECT) json_print_object(f, s); + if(s->type == JSON_LIST) json_print_list(f, s); + if(s->type == JSON_STRING) json_print_string(f, s); + if(s->type == JSON_NUMBER) json_print_number(f, s); + if(s->type == JSON_CONSTANT) json_print_constant(f, s); +} + +void json_print_object(FILE *f, json_struct *s) +{ + json_attr_val *avl; + int first = 1; + fprintf(f, "{"); + for(avl = s->u.attr_val_list; avl; avl = avl->next){ + if(first) first = 0; + else fprintf(f, ", "); + fprintf(f, "%s : ", avl->attr); + json_print_struct(f, avl->val); + } + fprintf(f, "}\n"); +} + +void json_print_list(FILE *f, json_struct *s) +{ + int first = 1; + fprintf(f, "["); + s = s->u.first; + while(s){ + if(first) first = 0; + else fprintf(f, ", "); + json_print_struct(f, s); + s = s->next; + } + fprintf(f, "]\n"); +} + +void json_print_string(FILE *f, json_struct *s) +{ + fprintf(f, "%s", s->u.string); +} + +void json_print_number(FILE *f, json_struct *s) +{ + fprintf(f, "%f", s->u.number); + +} + +void json_print_constant(FILE *f, json_struct *s) +{ + if(s->u.constant == JSON_CONST_TRUE){ + fprintf(f, " true"); + return; + } + if(s->u.constant == JSON_CONST_FALSE){ + fprintf(f, " false"); + return; + } + if(s->u.constant == JSON_CONST_NULL){ + fprintf(f, " null"); + return; + } +} + +void json_free_struct(json_struct *s); + +json_struct *json_new_list(json_struct *s) +{ + json_struct *c = json_new_struct(JSON_LIST); + c->u.first = s; + return c; +} + +void json_free_list(json_struct *s) +{ + if(s){ + json_free_list(s->next); + json_free_struct(s); + } +} + +void json_free_attr_val_list(json_attr_val *avl) +{ + if(avl){ + json_free_attr_val_list(avl->next); + free(avl->attr); + json_free_struct(avl->val); + free(avl); + } +} + +void json_free_struct(json_struct *s) +{ + if(s == NULL) return; + if(s->type == JSON_OBJECT) json_free_attr_val_list(s->u.attr_val_list); + if(s->type == JSON_LIST) json_free_list(s->u.first); + if(s->type == JSON_STRING) free(s->u.string); + free(s); +} + diff --git a/maca_common/src/json_tree.h b/maca_common/src/json_tree.h new file mode 100644 index 0000000000000000000000000000000000000000..180eab9fd93683fd3b925e4099dd135f25e4b9eb --- /dev/null +++ b/maca_common/src/json_tree.h @@ -0,0 +1,64 @@ +#ifndef __JSON_TREE__ +#define __JSON_TREE__ + +#define JSON_OBJECT 1 +#define JSON_LIST 2 +#define JSON_STRING 3 +#define JSON_NUMBER 4 +#define JSON_CONSTANT 5 + +#define JSON_CONST_TRUE 1 +#define JSON_CONST_FALSE 2 +#define JSON_CONST_NULL 3 + +typedef struct _json_struct_ json_struct; +typedef struct _json_struct_list_ json_struct_list; +typedef struct _json_attr_val_ json_attr_val; + +struct _json_struct_ { + int type; + union { + json_attr_val *attr_val_list; + char *string; + int constant; + float number; + json_struct *first; + } u; + struct _json_struct_ *next; +}; + +typedef struct _json_object_ { + json_attr_val *list; +} json_object; + +/* +struct _json_struct_list_ { + int nbelem; + json_struct *first; + json_struct *last; + };*/ + +struct _json_attr_val_ { + char *attr; + json_struct *val; + struct _json_attr_val_ *next; +}; + +json_struct *json_new_string(char *string); +json_struct *json_new_number(float number); +json_struct *json_new_constant(int constant); +json_attr_val *json_new_attr_val(char *attr, json_struct *s, json_attr_val *next); +json_struct *json_new_object(json_attr_val *avl); +json_struct *json_new_list(json_struct *s); + + +void json_print_struct(FILE *f, json_struct *s); +void json_print_object(FILE *f, json_struct *s); +void json_print_list(FILE *f, json_struct *s); +void json_print_string(FILE *f, json_struct *s); +void json_print_number(FILE *f, json_struct *s); +void json_print_constant(FILE *f, json_struct *s); +void json_free_struct(json_struct *s); + + +#endif diff --git a/maca_tools/src/mcf2json.c b/maca_tools/src/mcf2json.c index 9efa32c0facb3d2f71e49d97452ce014eceb8cbb..0f1e76b19202fde242b0b93ec3403f736d1b493f 100644 --- a/maca_tools/src/mcf2json.c +++ b/maca_tools/src/mcf2json.c @@ -124,7 +124,7 @@ context *mcf2json_context_read_options(int argc, char *argv[]) void print_footer(FILE *output_file) { - fprintf(output_file, "}]\n"); + fprintf(output_file, "]\n"); fprintf(output_file, "}\n"); } @@ -143,6 +143,7 @@ void print_header(FILE *output_file, mcd *mcd_struct) fprintf(output_file, "\"header\":{\n"); fprintf(output_file, "\"id\": \"\",\n"); fprintf(output_file, "\"timestamp\": \"\",\n"); + fprintf(output_file, "\"labels_segment\": \""); for(i=0; i < dico_pos->nbelem; i++){ fprintf(output_file, " %s", dico_pos->array[i]); @@ -160,7 +161,7 @@ void print_header(FILE *output_file, mcd *mcd_struct) fprintf(output_file, "\"annotations\":{\n"); fprintf(output_file, "\"name\": \"\",\n"); fprintf(output_file, "\"time_start\": \"\",\n"); - fprintf(output_file, "\"time_end\": \"\",\n"); + fprintf(output_file, "\"time_end\": \"\"\n"); fprintf(output_file, "},\n"); }