summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yy/bad.xml2
-rw-r--r--yy/kalmia.y50
-rw-r--r--yy/main.c15
3 files changed, 50 insertions, 17 deletions
diff --git a/yy/bad.xml b/yy/bad.xml
index 873797b..4078a14 100644
--- a/yy/bad.xml
+++ b/yy/bad.xml
@@ -36,7 +36,7 @@
</transparent>
<transparency>
<float>1.0</float>
- </transparency>
+ </tranparency>
</phong>
</technique>
</profile_COMMON>
diff --git a/yy/kalmia.y b/yy/kalmia.y
index 56b15ac..ec806f7 100644
--- a/yy/kalmia.y
+++ b/yy/kalmia.y
@@ -8,14 +8,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+ #include <string.h>
}
%code requires {
typedef void* yyscan_t;
- struct kalmia_t {
- struct kai_tag_t *tag;
- };
-
struct kai_attr_t {
char *key;
char *value;
@@ -31,11 +28,21 @@
struct kai_tag_t *next;
};
+
+ void kai_tag_destroy(struct kai_tag_t *tag);
}
-%parse-param { struct kalmia_t *result }
+%parse-param { struct kai_tag_t **document }
%code {
int yylex(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t scanner);
- int yyerror(YYLTYPE *yyllocp, yyscan_t unused, struct kalmia_t *unused2, const char *msg);
+ int yyerror(YYLTYPE *yyllocp, yyscan_t unused, struct kai_tag_t **unused2, const char *msg);
+
+ #define TAG_MISMATCH(a, b) \
+ do { \
+ char buf[1024]; \
+ snprintf(buf, 1024, "Tag name mismatch: \"%s\" != \"%s\"", a, b); \
+ yyerror(&yylloc, NULL, NULL, (const char*) buf); \
+ YYABORT; \
+ } while (0)
struct kai_attr_t * kai_attr_new(char *key, char *value);
struct kai_attr_t * kai_attr_last(struct kai_attr_t *head);
@@ -60,6 +67,7 @@
%token <string> CONTENT
%type <tag> start_tag
+%type <string> end_tag
%type <tag> empty_tag
%type <tag> tag
%type <tag> tags
@@ -71,7 +79,7 @@
%%
-document: PROLOG tag { result->tag = $2; }
+document: PROLOG tag { *document = $2; }
tags:
@@ -81,9 +89,26 @@ tags:
tag:
- start_tag end_tag { $$ = $1; }
- | start_tag CONTENT end_tag { $$ = $1; $$->content = $2; }
- | start_tag tags end_tag { $$ = $1; $$->children = $2; }
+ start_tag end_tag
+ {
+ $$ = $1;
+ if (strcmp($$->type, $2) != 0) TAG_MISMATCH($$->type, $2);
+ free($2);
+ }
+ | start_tag CONTENT end_tag
+ {
+ $$ = $1;
+ $$->content = $2;
+ if (strcmp($$->type, $3) != 0) TAG_MISMATCH($$->type, $3);
+ free($3);
+ }
+ | start_tag tags end_tag
+ {
+ $$ = $1;
+ $$->children = $2;
+ if (strcmp($$->type, $3) != 0) TAG_MISMATCH($$->type, $3);
+ free($3);
+ }
| empty_tag { $$ = $1; }
;
@@ -116,7 +141,7 @@ empty_tag:
end_tag:
- E_TAG_OPEN NAME TAG_CLOSE
+ E_TAG_OPEN NAME TAG_CLOSE { $$ = $2; }
;
@@ -140,7 +165,7 @@ attribute:
int yyerror(
YYLTYPE *yyllocp,
yyscan_t unused,
- struct kalmia_t *unused2,
+ struct kai_tag_t **unused2,
const char *msg)
{
fprintf(
@@ -220,4 +245,5 @@ void kai_tag_destroy(struct kai_tag_t *tag)
kai_tag_destroy(tag->children);
free(tag->content);
kai_tag_destroy(tag->next);
+ free(tag);
}
diff --git a/yy/main.c b/yy/main.c
index 823db5a..5bc5508 100644
--- a/yy/main.c
+++ b/yy/main.c
@@ -56,16 +56,23 @@ int main(int argc, char **argv)
return -1;
}
- struct kalmia_t result;
+ struct kai_tag_t *document;
yyscan_t scanner;
kalmialex_init(&scanner);
kalmiaset_in(in, scanner);
- kalmiaparse(scanner, &result);
+ int result = kalmiaparse(scanner, &document);
kalmialex_destroy(scanner);
+ fclose(in);
- print_tag("", result.tag);
- print_level(1, result.tag->children);
+ if (result != 0) {
+ return result;
+ }
+
+ print_tag("", document);
+ print_level(1, document->children);
+
+ kai_tag_destroy(document);
return 0;
}