Mon, 01 Sep 2025 00:14:59 +0800
Initial Lexer/Parser
%locations %define parse.error verbose %{ #include "tlvast.h" #include "tlvc.yy.h" extern void yyerror(const char *s); int field_index = 0; %} %union { int num; char *str; struct tlv_field *field; struct tlv_field_list_head *field_list; struct tlv *msg; } %token <str> IDENT %token <num> TYPE %token <num> NUMBER %token MESSAGE %type <msg> message %type <field> field %type <field_list> field_list %% input: /* empty */ | input message { TAILQ_INSERT_TAIL(&g_tlvs, $2, entries); } ; message: MESSAGE IDENT NUMBER '{' field_list '}' { struct tlv *m = malloc(sizeof(*m)); m->name = strdup($2); m->tag = $3; TAILQ_INIT(&m->fields); struct tlv_field *f; TAILQ_FOREACH(f, $5, entries) { TAILQ_INSERT_TAIL(&m->fields, f, entries); } $$ = m; } ; field_list: /* empty */ { $$ = NULL; } | field_list field { if ($1 == NULL) { struct tlv_field_list_head *list = malloc(sizeof(*list)); TAILQ_INIT(list); TAILQ_INSERT_TAIL(list, $2, entries); $$ = list; } else { TAILQ_INSERT_TAIL($1, $2, entries); $$ = $1; } field_index = 0; } ; field: TYPE IDENT ';' { struct tlv_field *f = malloc(sizeof(*f)); f->type = $1; f->name = strdup($2); f->tag = field_index++; $$ = f; } ; %%