diff options
author | sanine <sanine.not@pm.me> | 2023-01-31 13:01:25 -0600 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-01-31 13:01:25 -0600 |
commit | c4933ae58c84edf5a8e8f741dbb49324b1d12787 (patch) | |
tree | 7b2366989118ca0757caafce971337256677c0b3 | |
parent | 21afbb0644edc06fa47d29b847b4958d317b6a60 (diff) |
begin simplifying parser
-rw-r--r-- | yy/kalmia.l | 77 | ||||
-rw-r--r-- | yy/kalmia.y | 273 |
2 files changed, 82 insertions, 268 deletions
diff --git a/yy/kalmia.l b/yy/kalmia.l index 6950330..ef7c200 100644 --- a/yy/kalmia.l +++ b/yy/kalmia.l @@ -1,7 +1,7 @@ %option noinput nounput noyywrap 8bit nodefault %option reentrant bison-bridge bison-locations %option prefix="kalmia" -%start STRING +%start STRING TAG %{ #include <string.h> @@ -34,91 +34,52 @@ ATTR ([\x20\x0a\x0d\x09]*)?"=" /* xml prologue */ return PROLOG; } -<INITIAL>[\x20\x0a\x0d\x09] { +<INITIAL>[\x20\x0a\x0d\x09] | +<TAG>[\x20\x0a\x0d\x09] { /* ignore whitespace */ } -<INITIAL>"<" { return S_TAG_OPEN; } -<INITIAL>"</" { return E_TAG_OPEN; } -<INITIAL>">" { return TAG_CLOSE; } -<INITIAL>"/>" { return EMPTY_TAG_CLOSE; } +<INITIAL>"<" { BEGIN(TAG); return S_TAG_OPEN; } +<INITIAL>"</" { BEGIN(TAG); return E_TAG_OPEN; } +<TAG>">" { BEGIN(INITIAL); return TAG_CLOSE; } +<TAG>"/>" { BEGIN(INITIAL); return EMPTY_TAG_CLOSE; } -<INITIAL>"float_array" { - /* float_array tag */ - return FLOAT_ARRAY; -} -<INITIAL>"param" { - /* param tag */ - return PARAM; -} - - -<INITIAL>"id"/{ATTR} { - /* id attribute */ - return ID_ATTR; -} -<INITIAL>"count"/{ATTR} { - /* count attribute */ - return COUNT_ATTR; -} -<INITIAL>"name"/{ATTR} { - /* name attribute */ - return NAME_ATTR; -} -<INITIAL>"type"/{ATTR} { - /* type attribute */ - return TYPE_ATTR; -} - - -<INITIAL>[a-zA-Z_:][a-zA-Z0-9\.\-_:]* { +<TAG>[a-zA-Z_:][a-zA-Z0-9\.\-_:]* { /* generic tag name */ - yylval->sval = strdup(yytext); return NAME; + yylval->string = strdup(yytext); + return NAME; } -<INITIAL>[a-zA-Z_:][a-zA-Z0-9\.\-_:]*/{ATTR} { +<TAG>[a-zA-Z_:][a-zA-Z0-9\.\-_:]*/{ATTR} { /* generic attribute key */ - yylval->sval = strdup(yytext); + yylval->string = strdup(yytext); return ATTR; } -<INITIAL>"=" { +<TAG>"=" { /* attribute "=" */ return *yytext; } - - - -<INITIAL>"\"" { +<TAG>"\"" { /* begin a string */ BEGIN(STRING); return *yytext; } <STRING>"\"" { /* end a string */ - BEGIN(INITIAL); + BEGIN(TAG); return *yytext; } <STRING>[^"]+ { /* within a string */ - yylval->sval = strdup(yytext); + yylval->string = strdup(yytext); return TEXT; } -<INITIAL>-?[0-9]+ { - /* integers */ - yylval->lval = strtol(yytext, NULL, 10); - return INTEGER; -} -<INITIAL>-?[0-9]+\.?[0-9]* { - /* doubles */ - yylval->dval = strtod(yytext, NULL); - return DOUBLE; -} -<INITIAL>{DATE} { - /* dates */ - return DATE; +<INITIAL>[^\x20\x0a\x0d\x09<][^<]*[^\x20\x0a\x0d\x09<] { + yylval->string = strdup(yytext); + return CONTENT; } 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); } |