summaryrefslogtreecommitdiff
path: root/yy/kalmia.y
diff options
context:
space:
mode:
Diffstat (limited to 'yy/kalmia.y')
-rw-r--r--yy/kalmia.y101
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) {