tlvc.y

Mon, 01 Sep 2025 00:14:59 +0800

author
Gong Zhile <gongzl@stu.hebust.edu.cn>
date
Mon, 01 Sep 2025 00:14:59 +0800
changeset 0
59c92fa19678
permissions
-rw-r--r--

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;
    }
;

%%

mercurial