--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tlvc.y Mon Sep 01 00:14:59 2025 +0800 @@ -0,0 +1,81 @@ +%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; + } +; + +%%