Unifies unterminated tokens, struct_member_reference into operand.

This commit is contained in:
falsycat 2020-12-25 00:00:00 +00:00
parent fd3a5344b3
commit 4b0dada5c2
3 changed files with 91 additions and 61 deletions

View File

@ -2,8 +2,8 @@ X parser
X error handling (compiler message) X error handling (compiler message)
X user-defined type resolving X user-defined type resolving
X make enum for generic types X make enum for generic types
location for each declarations X constant resolving in expression
expression resolving check if an expression is static/dynamic
enum support enum support
union support union support
constant support constant support

130
biner.y
View File

@ -1,5 +1,6 @@
%{ %{
#include <assert.h> #include <assert.h>
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@ -23,22 +24,38 @@ extern int yylex(void);
#define yyerror(msg) \ #define yyerror(msg) \
fprintf(stderr, "[%zu:%zu] "msg"\n", ctx.line+1, ctx.column+1) fprintf(stderr, "[%zu:%zu] "msg"\n", ctx.line+1, ctx.column+1)
static inline biner_zone_ptr(biner_tree_decl_t) find_decl_by_name_( static inline bool
biner_zone_ptr(char) name); unstringify_struct_member_type_name_(
biner_tree_struct_member_type_name_t* name,
biner_zone_ptr(char) str
);
static inline biner_zone_ptr(biner_tree_decl_t)
find_decl_by_name_(
biner_zone_ptr(char) name
);
static inline biner_zone_ptr(biner_tree_struct_member_t) static inline biner_zone_ptr(biner_tree_struct_member_t)
find_struct_member_by_name_( find_struct_member_by_name_(
biner_zone_ptr(biner_tree_struct_member_t) last_member, biner_zone_ptr(biner_tree_struct_member_t) last_member,
biner_zone_ptr(char) name); biner_zone_ptr(char) name
);
static inline biner_zone_ptr(biner_tree_struct_member_t) static inline biner_zone_ptr(biner_tree_struct_member_t)
find_child_struct_member_by_name_( find_child_struct_member_by_name_(
biner_zone_ptr(biner_tree_struct_member_t) member, biner_zone_ptr(biner_tree_struct_member_t) member,
biner_zone_ptr(char) name); biner_zone_ptr(char) name
);
static inline biner_zone_ptr(biner_tree_struct_member_t) static inline biner_zone_ptr(biner_tree_struct_member_t)
unwrap_struct_member_ref_( unwrap_struct_member_ref_(
biner_zone_ptr(biner_tree_struct_member_reference_t) memref); biner_zone_ptr(biner_tree_struct_member_reference_t) memref
);
static biner_zone_ptr(biner_tree_expr_t)
resolve_constant_(
biner_zone_ptr(char) ident
);
%} %}
%union { %union {
@ -53,7 +70,6 @@ unwrap_struct_member_ref_(
%type <ptr> decl_list decl %type <ptr> decl_list decl
%type <ptr> struct_member_list struct_member %type <ptr> struct_member_list struct_member
%type <ptr> struct_member_type array_struct_member_type unqualified_struct_member_type %type <ptr> struct_member_type array_struct_member_type unqualified_struct_member_type
%type <ptr> struct_member_reference
%type <ptr> expr add_expr mul_expr operand %type <ptr> expr add_expr mul_expr operand
%start decl_list %start decl_list
@ -141,8 +157,7 @@ unqualified_struct_member_type
const biner_zone_ptr(biner_tree_decl_t) decl = find_decl_by_name_($1); const biner_zone_ptr(biner_tree_decl_t) decl = find_decl_by_name_($1);
if (decl == 0) { if (decl == 0) {
if (!biner_tree_struct_member_type_name_unstringify( if (!unstringify_struct_member_type_name_(&t->name, $1)) {
&t->name, ref(char, $1))) {
yyerrorf("unknown type '%s'", ref(char, $1)); yyerrorf("unknown type '%s'", ref(char, $1));
YYABORT; YYABORT;
} }
@ -201,44 +216,68 @@ operand
.i = $1, .i = $1,
}; };
} }
| struct_member_reference { | IDENT {
$$ = alloc_(biner_tree_expr_t); const biner_zone_ptr(biner_tree_struct_member_t) m =
*ref(biner_tree_expr_t, $$) = (biner_tree_expr_t) { find_struct_member_by_name_(ctx.last_member, $1);
.type = BINER_TREE_EXPR_TYPE_OPERAND_REFER, if (m != 0) {
.r = $1, biner_zone_ptr(biner_tree_struct_member_reference_t) mref =
}; alloc_(biner_tree_struct_member_reference_t);
*ref(biner_tree_struct_member_reference_t, mref) =
(biner_tree_struct_member_reference_t) { .member = m, };
$$ = alloc_(biner_tree_expr_t);
*ref(biner_tree_expr_t, $$) = (biner_tree_expr_t) {
.type = BINER_TREE_EXPR_TYPE_OPERAND_REFERENCE,
.r = mref,
};
} else {
$$ = resolve_constant_($1);
if ($$ == 0) {
yyerrorf("unknown member or symbol '%s'", ref(char, $1));
YYABORT;
}
}
}
| operand '.' IDENT {
biner_tree_expr_t* expr = ref(biner_tree_expr_t, $1);
if (expr->type != BINER_TREE_EXPR_TYPE_OPERAND_REFERENCE) {
yyerrorf("refering non-struct's child, '%s'", ref(char, $3));
YYABORT;
}
const biner_zone_ptr(biner_tree_struct_member_t) m =
find_child_struct_member_by_name_(unwrap_struct_member_ref_(expr->r), $3);
if (m == 0) {
yyerrorf("unknown member '%s'", ref(char, $3));
YYABORT;
}
$$ = alloc_(biner_tree_struct_member_reference_t);
*ref(biner_tree_struct_member_reference_t, $$) =
(biner_tree_struct_member_reference_t) {
.member = m,
.prev = expr->r,
};
expr->r = $$;
/* A shared expression such as constant cannot have a reference to member.
* So modification of the expression doesn't cause any side effects.
*/
} }
| '(' expr ')' { $$ = $2; } | '(' expr ')' { $$ = $2; }
; ;
struct_member_reference
: IDENT {
const biner_zone_ptr(biner_tree_struct_member_t) member =
find_struct_member_by_name_(ctx.last_member, $1);
if (member == 0) {
yyerrorf("unknown member '%s'", ref(char, $1));
YYABORT;
}
$$ = alloc_(biner_tree_struct_member_reference_t);
*ref(biner_tree_struct_member_reference_t, $$) =
(biner_tree_struct_member_reference_t) { .member = member, };
}
| struct_member_reference '.' IDENT {
const biner_zone_ptr(biner_tree_struct_member_t) member =
find_child_struct_member_by_name_(unwrap_struct_member_ref_($1), $3);
if (member == 0) {
yyerrorf("unknown member '%s'", ref(char, $3));
YYABORT;
}
$$ = alloc_(biner_tree_struct_member_reference_t);
*ref(biner_tree_struct_member_reference_t, $$) =
(biner_tree_struct_member_reference_t) { .member = member, };
}
;
%% %%
static inline bool unstringify_struct_member_type_name_(
biner_tree_struct_member_type_name_t* name,
biner_zone_ptr(char) str) {
for (size_t i = 0; i < BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_; ++i) {
const char* item = biner_tree_struct_member_type_name_string_map[i];
if (item != NULL && strcmp(ref(char, str), item) == 0) {
*name = (biner_tree_struct_member_type_name_t) i;
return true;
}
}
return false;
}
static inline biner_zone_ptr(biner_tree_decl_t) find_decl_by_name_( static inline biner_zone_ptr(biner_tree_decl_t) find_decl_by_name_(
biner_zone_ptr(char) name) { biner_zone_ptr(char) name) {
biner_zone_ptr(biner_tree_decl_t) itr = ctx.last_decl; biner_zone_ptr(biner_tree_decl_t) itr = ctx.last_decl;
@ -292,3 +331,10 @@ unwrap_struct_member_ref_(
ref(biner_tree_struct_member_reference_t, memref); ref(biner_tree_struct_member_reference_t, memref);
return r->member; return r->member;
} }
static inline biner_zone_ptr(biner_tree_expr_t) resolve_constant_(
biner_zone_ptr(char) ident) {
(void) ident;
/* TODO: check out enums and constants */
return 0;
}

18
tree.h
View File

@ -18,7 +18,7 @@ typedef struct biner_tree_decl_t biner_tree_decl_t;
typedef enum biner_tree_expr_type_t { typedef enum biner_tree_expr_type_t {
BINER_TREE_EXPR_TYPE_OPERAND_INTEGER, BINER_TREE_EXPR_TYPE_OPERAND_INTEGER,
BINER_TREE_EXPR_TYPE_OPERAND_REFER, BINER_TREE_EXPR_TYPE_OPERAND_REFERENCE,
BINER_TREE_EXPR_TYPE_OPERATOR_ADD, BINER_TREE_EXPR_TYPE_OPERATOR_ADD,
BINER_TREE_EXPR_TYPE_OPERATOR_SUB, BINER_TREE_EXPR_TYPE_OPERATOR_SUB,
BINER_TREE_EXPR_TYPE_OPERATOR_MUL, BINER_TREE_EXPR_TYPE_OPERATOR_MUL,
@ -120,22 +120,6 @@ typedef struct biner_tree_parse_context_t {
extern biner_tree_parse_context_t biner_tree_parse_context_; extern biner_tree_parse_context_t biner_tree_parse_context_;
static inline bool biner_tree_struct_member_type_name_unstringify(
biner_tree_struct_member_type_name_t* name,
const char* str) {
assert(name != NULL);
assert(str != NULL);
for (size_t i = 0; i < BINER_TREE_STRUCT_MEMBER_TYPE_NAME_MAX_; ++i) {
const char* item = biner_tree_struct_member_type_name_string_map[i];
if (item != NULL && strcmp(str, item) == 0) {
*name = (biner_tree_struct_member_type_name_t) i;
return true;
}
}
return false;
}
const uint8_t* const uint8_t*
biner_tree_parse( biner_tree_parse(
FILE* fp FILE* fp