diff options
Diffstat (limited to 'yy/kalmia.y')
-rw-r--r-- | yy/kalmia.y | 101 |
1 files changed, 94 insertions, 7 deletions
diff --git a/yy/kalmia.y b/yy/kalmia.y index 98650f8..56b15ac 100644 --- a/yy/kalmia.y +++ b/yy/kalmia.y @@ -13,8 +13,7 @@ typedef void* yyscan_t; struct kalmia_t { - void *current; - int index; + struct kai_tag_t *tag; }; struct kai_attr_t { @@ -39,9 +38,11 @@ int yyerror(YYLTYPE *yyllocp, yyscan_t unused, struct kalmia_t *unused2, const char *msg); struct kai_attr_t * kai_attr_new(char *key, char *value); + struct kai_attr_t * kai_attr_last(struct kai_attr_t *head); void kai_attr_destroy(struct kai_attr_t *attr); - struct kai_tag_t * kai_tag_new(char *type, struct kai_attr_t *attrs, struct kai_tag_t *children, char *content); + struct kai_tag_t * kai_tag_new(char *type, struct kai_attr_t *attrs); + struct kai_tag_t * kai_tag_last(struct kai_tag_t *head); void kai_tag_destroy(struct kai_tag_t *tag); } @@ -58,11 +59,79 @@ %token <string> TEXT %token <string> CONTENT +%type <tag> start_tag +%type <tag> empty_tag +%type <tag> tag +%type <tag> tags + +%type <attr> attribute +%type <attr> attributes + %% -document: PROLOG +document: PROLOG tag { result->tag = $2; } + + +tags: + tag { $$ = $1; } + | tags tag { $$ = $1; kai_tag_last($$)->next = $2; } + ; + + +tag: + start_tag end_tag { $$ = $1; } + | start_tag CONTENT end_tag { $$ = $1; $$->content = $2; } + | start_tag tags end_tag { $$ = $1; $$->children = $2; } + | empty_tag { $$ = $1; } + ; + +start_tag: + S_TAG_OPEN NAME TAG_CLOSE + { + $$ = kai_tag_new($2, NULL); + if ($$ == NULL) YYNOMEM; + } + | S_TAG_OPEN NAME attributes TAG_CLOSE + { + $$ = kai_tag_new($2, $3); + if ($$ == NULL) YYNOMEM; + } + ; + + +empty_tag: + S_TAG_OPEN NAME EMPTY_TAG_CLOSE + { + $$ = kai_tag_new($2, NULL); + if ($$ == NULL) YYNOMEM; + } + | S_TAG_OPEN NAME attributes EMPTY_TAG_CLOSE + { + $$ = kai_tag_new($2, $3); + if ($$ == NULL) YYNOMEM; + } + ; + + +end_tag: + E_TAG_OPEN NAME TAG_CLOSE + ; + + +attributes: + attribute { $$ = $1; } + | attributes attribute { $$ = $1; kai_attr_last($$)->next = $2; } + ; + +attribute: + ATTR '=' '"' TEXT '"' + { + $$ = kai_attr_new($1, $4); + if ($$ == NULL) YYNOMEM; + } + ; %% @@ -94,6 +163,15 @@ struct kai_attr_t * kai_attr_new(char *key, char *value) return attr; } +struct kai_attr_t * kai_attr_last(struct kai_attr_t *head) +{ + struct kai_attr_t *ptr = head; + while (ptr->next != NULL) { + ptr = ptr->next; + } + return ptr; +} + void kai_attr_destroy(struct kai_attr_t *attr) { if (attr == NULL) { @@ -107,7 +185,7 @@ void kai_attr_destroy(struct kai_attr_t *attr) } -struct kai_tag_t * kai_tag_new(char *type, struct kai_attr_t *attrs, struct kai_tag_t *children, char *content) +struct kai_tag_t * kai_tag_new(char *type, struct kai_attr_t *attrs) { struct kai_tag_t *tag = malloc(sizeof(struct kai_tag_t)); if (tag == NULL) { @@ -116,12 +194,21 @@ struct kai_tag_t * kai_tag_new(char *type, struct kai_attr_t *attrs, struct kai_ tag->type = type; tag->attrs = attrs; - tag->children = children; - tag->content = content; + tag->children = NULL; + tag->content = NULL; tag->next = NULL; return tag; } +struct kai_tag_t * kai_tag_last(struct kai_tag_t *head) +{ + struct kai_tag_t *ptr = head; + while (ptr->next != NULL) { + ptr = ptr->next; + } + return ptr; +} + void kai_tag_destroy(struct kai_tag_t *tag) { if (tag == NULL) { |