commit abd55be479e44d41048b64aabe7204a1f771038d from: Benjamin Stürz date: Wed Jul 31 09:31:03 2024 UTC fix for bison commit - 7c54bc436fdb3050a031a335afcb1dd0e9cf3b18 commit + abd55be479e44d41048b64aabe7204a1f771038d blob - 7036f7a1d62e2683fafdb50f85224289e2a6156b blob + 6efb98c26c284de343ce321cead165a15b5c25ea --- parse.y +++ parse.y @@ -4,12 +4,28 @@ int yylex (void); void yyerror (const char *, ...); -%} -%token IDENT, INT -%token SIZEOF, STRUCT, UNION, CONST, IF, EQ -%token I8, I16, I32, I64, U8, U16, U32, U64 +static struct list file; +struct list list_new (void); +struct list list_new_with (void *); +struct list list_push (struct list, void *); +struct item *item (char *, struct type *); +struct uitem *uitem (char *, struct type *, struct cond *); +struct cond *cond_cmp (char *, struct value *); +struct structure *structure (char *, struct list); +struct type *type_simple (enum type_type); +struct type *type_name (char *); +struct type *type_int (int); +struct type *type_struct (struct structure *); +struct type *type_union (struct list); +struct type *type_array (struct type *, size_t); +struct value *val_name (char *); +struct value *val_int (int); + +int sizeof_type (const struct type *); +%} + %union { struct structure *st; struct value *val; @@ -20,80 +36,100 @@ void yyerror (const char *, ...); char *s; int i; - struct { + struct list { void **ptr; size_t len, cap; } list; }; +%token IDENT +%token INT +%token SIZEOF STRUCT UNION CONST IF EQ +%token I8 I16 I32 I64 U8 U16 U32 U64 + +%type file items uitems +%type value +%type type +%type struct +%type item +%type uitem +%type cond +%type ident + +%type expr add mult unary atom + %% -file : file struct ';' { list_push (&$$, &$1, $2.st); } - | struct ';' { list_new_with (&$$, $1.st); } +top : file { file = $1; } + ; + + +file : file struct ';' { $$ = list_push ($1, $2); } + | struct ';' { $$ = list_new_with ($1); } ; -struct : STRUCT ident '{' items comma '}' { structure (&$$, $2.s, &$4); } +struct : STRUCT ident '{' items comma '}' { $$ = structure ($2, $4); } ; -ident : IDENT { $$.s = $1.s; } - | { $$.s = NULL; } +ident : IDENT { $$ = $1; } + | { $$ = NULL; } ; comma : ',' | ; -items : items ',' item { list_push (&$$, &$1, $3.it); } - | item { list_new_with (&$$, $1.it); } +items : items ',' item { $$ = list_push ($1, $3); } + | item { $$ = list_new_with ($1); } -item : IDENT ':' type { item (&$$, $1.s, $3.ty); } +item : IDENT ':' type { $$ = item ($1, $3); } ; -type : I8 { type_simple (&$$, T_I8); } - | I16 { type_simple (&$$, T_I16); } - | I32 { type_simple (&$$, T_I32); } - | I64 { type_simple (&$$, T_I64); } - | U8 { type_simple (&$$, T_U8); } - | U16 { type_simple (&$$, T_U16); } - | U32 { type_simple (&$$, T_U32); } - | U64 { type_simple (&$$, T_U64); } - | '[' type ';' expr ']' { type_array (&$$, $2.ty, $4.i); } - | STRUCT IDENT { type_name (&$$, $2.s); } - | struct { type_struct (&$$, $1.st); } - | UNION '{' uitems comma '}' { type_union (&$$, &$3); } +type : I8 { $$ = type_simple (T_I8); } + | I16 { $$ = type_simple (T_I16); } + | I32 { $$ = type_simple (T_I32); } + | I64 { $$ = type_simple (T_I64); } + | U8 { $$ = type_simple (T_U8); } + | U16 { $$ = type_simple (T_U16); } + | U32 { $$ = type_simple (T_U32); } + | U64 { $$ = type_simple (T_U64); } + | '[' type ';' expr ']' { $$ = type_array ($2, $4); } + | STRUCT IDENT { $$ = type_name ($2); } + | struct { $$ = type_struct ($1); } + | UNION '{' uitems comma '}' { $$ = type_union ($3); } ; -uitems : uitems ',' uitem { list_push (&$$, &$1, $3.ui); } - | uitem { list_new_with (&$$, $1.ui); } +uitems : uitems ',' uitem { $$ = list_push ($1, $3); } + | uitem { $$ = list_new_with ($1); } ; -uitem : IDENT ':' type IF cond { uitem (&$$, $1.s, $3.ty, $5.co); } +uitem : IDENT ':' type IF cond { $$ = uitem ($1, $3, $5); } ; -value : IDENT { val_name (&$$, $1.s); } - | INT { val_int (&$$, $1.i); } +value : IDENT { $$ = val_name ($1); } + | INT { $$ = val_int ($1); } ; -cond : IDENT EQ value { cond_cmp (&$$, $1.s, $3.val); } +cond : IDENT EQ value { $$ = cond_cmp ($1, $3); } ; expr : add { $$ = $1; } ; -add : add '+' mult { $$.i = $1.i + $3.i; } - | add '-' mult { $$.i = $1.i - $3.i; } +add : add '+' mult { $$ = $1 + $3; } + | add '-' mult { $$ = $1 - $3; } | mult { $$ = $1; } ; -mult : mult '*' unary { $$.i = $1.i * $3.i; } - | mult '/' unary { $$.i = $1.i / $3.i; } +mult : mult '*' unary { $$ = $1 * $3; } + | mult '/' unary { $$ = $1 / $3; } | unary { $$ = $1; } ; -unary : '-' unary { $$.i = -$2.i; } +unary : '-' unary { $$ = -$2; } | atom { $$ = $1; } ; -atom : INT { $$.i = $1.i; } - | SIZEOF '(' type ')' { $$.i = sizeof_type ($3.ty); } +atom : INT { $$ = $1; } + | SIZEOF '(' type ')' { $$ = sizeof_type ($3); } | '(' expr ')' { $$ = $2; } ; @@ -101,124 +137,130 @@ atom : INT { $$.i = $1.i; } #define new(T) ((T *)malloc (sizeof (T))) -void type_simple (YYSTYPE *y, enum type_type type) +struct list list_new (void) { - y->ty = new (struct type); - y->ty->type = type; + struct list l; + l.len = 0; + l.cap = 10; + l.ptr = calloc (l.cap + 1, sizeof (void *)); + return l; } -void type_array (YYSTYPE *y, struct type *inner, size_t len) +struct list list_new_with (void *e) { - y->ty = new (struct type); - y->ty->type = T_ARRAY; - y->ty->inner = inner; - y->ty->len = len; + struct list l = list_new (); + l.len = 1; + l.ptr[0] = e; + return l; } -void type_name (YYSTYPE *y, char *s) +struct list list_push (struct list l, void *e) { - y->ty = new (struct type); - y->ty->type = T_NAME; - y->ty->name = s; + if (l.len == l.cap) { + l.cap *= 2; + l.ptr = reallocarray (l.ptr, l.cap + 1, sizeof (void *)); + } + + l.ptr[l.len++] = e; + return l; } -void type_struct (YYSTYPE *y, struct structure *st) +void *list_fin (struct list l) { - y->ty = new (struct type); - y->ty->type = T_STRUCT; - y->ty->st = st; + l.ptr[l.len] = NULL; + return l.ptr; } -void item (YYSTYPE *y, char *name, struct type *type) +struct type *type_simple (enum type_type type) { - y->it = new (struct item); - y->it->name = name; - y->it->type = type; + struct type *ty = new (struct type); + ty->type = type; + return ty; } -void list_new (YYSTYPE *y) +struct type *type_array (struct type *inner, size_t len) { - y->list.len = 0; - y->list.cap = 10; - y->list.ptr = calloc (y->list.cap + 1, sizeof (void *)); + struct type *ty = new (struct type); + ty->type = T_ARRAY; + ty->inner = inner; + ty->len = len; + return ty; } -void list_new_with (YYSTYPE *y, void *e) +struct type *type_name (char *s) { - list_new (y); - y->list.len = 1; - y->list.ptr[0] = e; + struct type *ty = new (struct type); + ty->type = T_NAME; + ty->name = s; + return ty; } -void list_push (YYSTYPE *y, YYSTYPE *o, void *e) +struct type *type_struct (struct structure *st) { - *y = *o; - if (y->list.len == y->list.cap) { - y->list.cap *= 2; - y->list.ptr = reallocarray (y->list.ptr, y->list.cap + 1, sizeof (void *)); - } - - y->list.ptr[y->list.len++] = e; + struct type *ty = new (struct type); + ty->type = T_STRUCT; + ty->st = st; + return ty; } -void *list_fin (YYSTYPE *y) +struct type *type_union (struct list items) { - y->list.ptr[y->list.len] = NULL; - return y->list.ptr; + struct type *ty = new (struct type); + ty->type = T_UNION; + ty->un = list_fin (items); + return ty; } -void structure (YYSTYPE *y, char *name, YYSTYPE *items) +struct item *item (char *name, struct type *type) { - y->st = new (struct structure); - y->st->name = name; - y->st->items = list_fin (items); + struct item *it = new (struct item); + it->name = name; + it->type = type; + return it; } -struct structure **parse (void) +struct structure *structure (char *name, struct list items) { - if (yyparse () != 0) - return NULL; - - return list_fin (&yyval); + struct structure *st = new (struct structure); + st->name = name; + st->items = list_fin (items); + return st; } -void val_name (YYSTYPE *y, char *name) +struct value *val_name (char *name) { - y->val = new (struct value); - y->val->type = V_NAME; - y->val->s = name; + struct value *val = new (struct value); + val->type = V_NAME; + val->s = name; + return val; } -void val_int (YYSTYPE *y, int i) +struct value *val_int (int i) { - y->val = new (struct value); - y->val->type = V_INT; - y->val->i = i; + struct value *val = new (struct value); + val->type = V_INT; + val->i = i; + return val; } -void cond_cmp (YYSTYPE *y, char *l, struct value *r) +struct cond *cond_cmp (char *l, struct value *r) { - y->co = new (struct cond); - y->co->type = C_EQ; - y->co->cmp.left = l; - y->co->cmp.right = r; + struct cond *co = new (struct cond); + co->type = C_EQ; + co->cmp.left = l; + co->cmp.right = r; + return co; } -void uitem (YYSTYPE *y, char *name, struct type *type, struct cond *co) +struct uitem *uitem (char *name, struct type *type, struct cond *co) { - y->ui = new (struct uitem); - y->ui->name = name; - y->ui->type = type; - y->ui->cond = co; + struct uitem *ui = new (struct uitem); + ui->name = name; + ui->type = type; + ui->cond = co; + return ui; } -void type_union (YYSTYPE *y, YYSTYPE *i) -{ - y->ty = new (struct type); - y->ty->type = T_UNION; - y->ty->un = list_fin (i); -} - int sizeof_type (const struct type *ty) { int x = 0; @@ -253,7 +295,16 @@ int sizeof_type (const struct type *ty) z = x; } return x; + default: + abort (); } } +struct structure **parse (void) +{ + if (yyparse () != 0) + return NULL; + return list_fin (file); +} +