diff options
Diffstat (limited to 'yy/kalmia.y')
-rw-r--r-- | yy/kalmia.y | 273 |
1 files changed, 63 insertions, 210 deletions
diff --git a/yy/kalmia.y b/yy/kalmia.y index 48db26e..98650f8 100644 --- a/yy/kalmia.y +++ b/yy/kalmia.y @@ -17,15 +17,20 @@ int index; }; - struct ka_float_array_t { - char *id; - size_t count; /* required */ - double *buf; + struct kai_attr_t { + char *key; + char *value; + struct kai_attr_t *next; }; - struct ka_param_t { - char *name; - char *type; /* required */ + struct kai_tag_t { + char *type; + struct kai_attr_t *attrs; + + struct kai_tag_t *children; + char *content; + + struct kai_tag_t *next; }; } %parse-param { struct kalmia_t *result } @@ -33,198 +38,31 @@ int yylex(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t scanner); int yyerror(YYLTYPE *yyllocp, yyscan_t unused, struct kalmia_t *unused2, const char *msg); - #define KAI_ABORT -1 - #define KAI_NOMEM -2 - - #define KAI_ABORTF(...) \ - do { \ - kai_abortf_(&yylloc, __VA_ARGS__); \ - YYABORT; \ - } while(0) - void kai_abortf_(YYLTYPE *yyllocp, const char *fmt, ...); - - /* attribute setters */ - int kai_set_float_array_attrs( - struct ka_float_array_t *a, - char *id, char *count); + struct kai_attr_t * kai_attr_new(char *key, char *value); + void kai_attr_destroy(struct kai_attr_t *attr); - #define KAI_WRAP(call) \ - do { \ - int err = call; \ - if (err == KAI_ABORT) { \ - KAI_ABORTF("call returned error: %s", #call); \ - } \ - else if (err == KAI_NOMEM) { \ - KAI_ABORTF("call ran out of memory: %s", #call); \ - } \ - } while(0) + struct kai_tag_t * kai_tag_new(char *type, struct kai_attr_t *attrs, struct kai_tag_t *children, char *content); + void kai_tag_destroy(struct kai_tag_t *tag); } %union { - long lval; - double dval; - char *sval; - char cval; - struct ka_float_array_t float_array; - struct ka_param_t param; + char *string; + struct kai_attr_t *attr; + struct kai_tag_t *tag; } %token PROLOG %token S_TAG_OPEN E_TAG_OPEN TAG_CLOSE EMPTY_TAG_CLOSE -%token <sval> NAME -%token <sval> ATTR -%token <sval> TEXT -%token <lval> INTEGER -%token <dval> DOUBLE -%token DATE +%token <string> NAME +%token <string> ATTR +%token <string> TEXT +%token <string> CONTENT -%token <float_array> FLOAT_ARRAY -%type <float_array> float_array -%type <float_array> float_array_start -%type <float_array> float_array_attributes - -%token PARAM -%type <param> param -%type <param> param_attrs - -%token ID_ATTR COUNT_ATTR NAME_ATTR TYPE_ATTR -%type <sval> attr %% -document: PROLOG element; - -elements: - element - | elements element - ; - -element: - empty_tag - | start_tag end_tag - | start_tag content end_tag - | float_array - | param - ; - -content: - elements - | integers - | doubles - | DATE - ; - -empty_tag: - S_TAG_OPEN NAME attributes EMPTY_TAG_CLOSE { printf("empty tag: %s\n", $2); } - ; - -start_tag: - S_TAG_OPEN NAME attributes TAG_CLOSE - { - printf("enter tag: %s\n", $2); - result->current = NULL; - } - ; - -end_tag: - E_TAG_OPEN NAME TAG_CLOSE { printf("exit tag: %s\n", $2); } - ; - -attributes: - | attribute - | attributes attribute - ; - -attribute: - ATTR attr { printf("attribute: %s=%s\n", $1, $2); } - | ID_ATTR attr - | COUNT_ATTR attr - | NAME_ATTR attr - ; - - - -float_array: - float_array_start doubles float_array_close - { - $$ = $1; - printf("float_array[id='%s', count=%lu]{ ", $$.id, $$.count); - for (size_t i=0; i<$$.count; i++) { - printf("%f, ", $$.buf[i]); - } - printf("}\n"); - } - ; - -float_array_start: - S_TAG_OPEN FLOAT_ARRAY float_array_attributes TAG_CLOSE - { - $$ = $3; - result->current = $$.buf; - result->index = 0; - } - ; - -float_array_close: - E_TAG_OPEN FLOAT_ARRAY TAG_CLOSE - ; - -float_array_attributes: - COUNT_ATTR attr - { KAI_WRAP(kai_set_float_array_attrs(&$$, NULL, $2)); } - | COUNT_ATTR attr ID_ATTR attr - { KAI_WRAP(kai_set_float_array_attrs(&$$, $4, $2)); } - | ID_ATTR attr COUNT_ATTR attr - { KAI_WRAP(kai_set_float_array_attrs(&$$, $2, $4)); } - ; - - -param: - S_TAG_OPEN PARAM param_attrs EMPTY_TAG_CLOSE - { - $$ = $3; - printf("param[name='%s', type='%s']\n", $$.name, $$.type); - } - ; - -param_attrs: - TYPE_ATTR attr - { $$.name = NULL; $$.type = $2; } - | TYPE_ATTR attr NAME_ATTR attr - { $$.name = $4; $$.type = $2; } - | NAME_ATTR attr TYPE_ATTR attr - { $$.name = $2; $$.type = $4; } - ; - - -attr: - '=' '"' TEXT '"' { $$ = $3; } - ; - - -integers: - INTEGER { printf("%ld\n", $1); } - | integers INTEGER { printf("%ld\n", $2); } - ; - -doubles: - DOUBLE - { - if (result->current != NULL) { - ((double*) result->current)[result->index] = $1; - result->index += 1; - } - } - | doubles DOUBLE - { - if (result->current != NULL) { - ((double*) result->current)[result->index] = $2; - result->index += 1; - } - } - - ; +document: PROLOG %% @@ -244,40 +82,55 @@ int yyerror( } -void kai_abortf_(YYLTYPE *yyllocp, const char *fmt, ...) +struct kai_attr_t * kai_attr_new(char *key, char *value) { - va_list args, args_len; - va_start(args, fmt); - va_copy(args_len, args); - size_t len = vsnprintf(NULL, 0, fmt, args_len) + 1; - va_end(args_len); + struct kai_attr_t *attr = malloc(sizeof(struct kai_attr_t)); + if (attr == NULL) { + return NULL; + } + attr->key = key; + attr->value = value; + attr->next = NULL; + return attr; +} - char *buf = malloc(sizeof(char) * len); - if (buf == NULL) { - fprintf(stderr, "failed to allocate buffer for error message!\n"); +void kai_attr_destroy(struct kai_attr_t *attr) +{ + if (attr == NULL) { return; } - vsnprintf(buf, len, fmt, args); - va_end(args); - yyerror(yyllocp, NULL, NULL, buf); + kai_attr_destroy(attr->next); + free(attr->key); + free(attr->value); + free(attr); } -/* float arrays */ -int kai_set_float_array_attrs( - struct ka_float_array_t *a, char *id, char *count) +struct kai_tag_t * kai_tag_new(char *type, struct kai_attr_t *attrs, struct kai_tag_t *children, char *content) { - a->id = id; - char *end = NULL; - a->count = strtoll(count, &end, 10); - if (end == count) { - return -1; + struct kai_tag_t *tag = malloc(sizeof(struct kai_tag_t)); + if (tag == NULL) { + return NULL; } - a->buf = malloc(sizeof(double) * a->count); - if (a->buf == NULL) { - return -2; + tag->type = type; + tag->attrs = attrs; + tag->children = children; + tag->content = content; + tag->next = NULL; + return tag; +} + +void kai_tag_destroy(struct kai_tag_t *tag) +{ + if (tag == NULL) { + return; } - return 0; + + free(tag->type); + kai_attr_destroy(tag->attrs); + kai_tag_destroy(tag->children); + free(tag->content); + kai_tag_destroy(tag->next); } |