summaryrefslogtreecommitdiff
path: root/yy
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-01-18 16:42:16 -0600
committersanine <sanine.not@pm.me>2023-01-18 16:42:16 -0600
commit5d2e5a312ba73bd48913e9ac5babe1c644997b3e (patch)
tree0c2f9a4667451795ab797398fad0622d00f51367 /yy
parent3409a7dbe08bdc98d7663e5dcafaee5792d12139 (diff)
parse float_array nodes
Diffstat (limited to 'yy')
-rw-r--r--yy/kalmia.h4
-rw-r--r--yy/kalmia.l21
-rw-r--r--yy/kalmia.y164
-rw-r--r--yy/main.c11
-rw-r--r--yy/makefile4
5 files changed, 188 insertions, 16 deletions
diff --git a/yy/kalmia.h b/yy/kalmia.h
deleted file mode 100644
index 98afd13..0000000
--- a/yy/kalmia.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define YYLTYPE KALMIALTYPE
-#define YYSTYPE KALMIASTYPE
-#include "kalmia.tab.h"
-#include "kalmia.lex.h"
diff --git a/yy/kalmia.l b/yy/kalmia.l
index 697d6ac..7e04f1a 100644
--- a/yy/kalmia.l
+++ b/yy/kalmia.l
@@ -45,11 +45,27 @@ ATTR ([\x20\x0a\x0d\x09]*)?"="
<INITIAL>"/>" { return EMPTY_TAG_CLOSE; }
+<INITIAL>"float_array" {
+ /* float_array tag */
+ return FLOAT_ARRAY;
+}
+
+
+<INITIAL>"id"/{ATTR} {
+ /* id attribute */
+ return ID_ATTR;
+}
+<INTIAL>"count"/{ATTR} {
+ /* count attribute */
+ return COUNT_ATTR;
+}
+
+
<INITIAL>[a-zA-Z_:][a-zA-Z0-9\.\-_:]* {
/* generic tag name */
yylval->sval = strdup(yytext); return NAME;
}
-<INITIAL>[a-zA-Z_:][a-zA-Z0-9\.\-_:]*/([\x20\x0a\x0d\x09])*"=" {
+<INITIAL>[a-zA-Z_:][a-zA-Z0-9\.\-_:]*/{ATTR} {
/* generic attribute key */
yylval->sval = strdup(yytext);
return ATTR;
@@ -60,6 +76,9 @@ ATTR ([\x20\x0a\x0d\x09]*)?"="
}
+
+
+
<INITIAL>"\"" {
/* begin a string */
BEGIN(STRING);
diff --git a/yy/kalmia.y b/yy/kalmia.y
index f1d77f9..0d8b16f 100644
--- a/yy/kalmia.y
+++ b/yy/kalmia.y
@@ -6,13 +6,51 @@
%code top {
#include <stdio.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
}
%code requires {
typedef void* yyscan_t;
+
+ struct kalmia_t {
+ void *current;
+ int index;
+ };
+
+ struct ka_float_array_t {
+ char *id;
+ size_t count;
+ double *buf;
+ };
}
+%parse-param { struct kalmia_t *result }
%code {
int yylex(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t scanner);
- int yyerror(YYLTYPE *yyllocp, yyscan_t unused, const char *msg);
+ 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, ...);
+
+ /* float arrays */
+ int kai_set_float_array_attrs(struct ka_float_array_t *a, char *id, char *count);
+
+ #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)
}
%union {
@@ -20,6 +58,7 @@
double dval;
char *sval;
char cval;
+ struct ka_float_array_t float_array;
}
%token PROLOG
@@ -31,6 +70,13 @@
%token <dval> DOUBLE
%token DATE;
+%token <float_array> FLOAT_ARRAY
+%type <float_array> float_array
+%type <float_array> float_array_start
+%type <float_array> float_array_attributes
+
+%token ID_ATTR COUNT_ATTR
+%type <sval> attr
%%
@@ -46,6 +92,7 @@ element:
empty_tag
| start_tag end_tag
| start_tag content end_tag
+ | float_array
;
content:
@@ -60,7 +107,11 @@ empty_tag:
;
start_tag:
- S_TAG_OPEN NAME attributes TAG_CLOSE { printf("enter tag: %s\n", $2); }
+ S_TAG_OPEN NAME attributes TAG_CLOSE
+ {
+ printf("enter tag: %s\n", $2);
+ result->current = NULL;
+ }
;
end_tag:
@@ -69,11 +120,53 @@ end_tag:
attributes:
| attribute
- | attributes attribute;
+ | attributes attribute
;
attribute:
- ATTR '=' '"' TEXT '"' { printf("attribute: %s=%s\n", $1, $4); }
+ ATTR attr { printf("attribute: %s=%s\n", $1, $2); }
+ | ID_ATTR attr
+ | COUNT_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)); }
+ ;
+
+attr:
+ '=' '"' TEXT '"' { $$ = $3; }
;
@@ -83,14 +176,32 @@ integers:
;
doubles:
- DOUBLE { printf("%f\n", $1); }
- | doubles DOUBLE { printf("%f\n", $2); }
+ 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;
+ }
+ }
+
;
%%
-int yyerror(YYLTYPE *yyllocp, yyscan_t unused, const char *msg)
+
+int yyerror(
+ YYLTYPE *yyllocp,
+ yyscan_t unused,
+ struct kalmia_t *unused2,
+ const char *msg)
{
fprintf(
stderr, "[%d:%d]: %s\n",
@@ -98,3 +209,42 @@ int yyerror(YYLTYPE *yyllocp, yyscan_t unused, const char *msg)
);
return 1;
}
+
+
+void kai_abortf_(YYLTYPE *yyllocp, const char *fmt, ...)
+{
+ 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);
+
+ char *buf = malloc(sizeof(char) * len);
+ if (buf == NULL) {
+ fprintf(stderr, "failed to allocate buffer for error message!\n");
+ return;
+ }
+ vsnprintf(buf, len, fmt, args);
+ va_end(args);
+
+ yyerror(yyllocp, NULL, NULL, buf);
+}
+
+
+/* float arrays */
+int kai_set_float_array_attrs(
+ struct ka_float_array_t *a, char *id, char *count)
+{
+ a->id = id;
+ char *end = NULL;
+ a->count = strtoll(count, &end, 10);
+ if (end == count) {
+ return -1;
+ }
+
+ a->buf = malloc(sizeof(double) * a->count);
+ if (a->buf == NULL) {
+ return -2;
+ }
+ return 0;
+}
diff --git a/yy/main.c b/yy/main.c
index 52ee955..0d97fba 100644
--- a/yy/main.c
+++ b/yy/main.c
@@ -1,5 +1,10 @@
#include <stdio.h>
-#include "kalmia.h"
+
+#define YYLTYPE KALMIALTYPE
+#define YYSTYPE KALMIASTYPE
+#include "kalmia.tab.h"
+#include "kalmia.lex.h"
+
int main(int argc, char **argv)
{
@@ -13,10 +18,12 @@ int main(int argc, char **argv)
return -1;
}
+ struct kalmia_t result;
+
yyscan_t scanner;
kalmialex_init(&scanner);
kalmiaset_in(in, scanner);
- kalmiaparse(scanner);
+ kalmiaparse(scanner, &result);
kalmialex_destroy(scanner);
return 0;
}
diff --git a/yy/makefile b/yy/makefile
index 76b5c77..a2022a2 100644
--- a/yy/makefile
+++ b/yy/makefile
@@ -8,8 +8,8 @@ kalmia.tab.c: kalmia.y
kalmia.lex.c: kalmia.l
flex -o "$@" --header-file="kalmia.lex.h" kalmia.l
-kalmia: kalmia.tab.c kalmia.lex.c main.c kalmia.h
- gcc -o kalmia ${WARNINGS} main.c kalmia.tab.c kalmia.lex.c
+kalmia: kalmia.tab.c kalmia.lex.c main.c
+ gcc -g -o kalmia ${WARNINGS} main.c kalmia.tab.c kalmia.lex.c
clean:
rm kalmia.lex.c kalmia.lex.h kalmia.tab.c kalmia.tab.h kalmia