feat(ast): 添加复合表达式和初始化器解析支持

重构AST表达式枚举,将COMPOUND_LITERAL重命名为COMPOUND,
更新相关结构体定义以支持复合字面量的左右表达式向量表示。

添加lvalue表达式类型用于左值处理,实现完整的初始化器解析功能,
包括大括号初始化列表、成员访问和数组下标的处理逻辑。

更新表达式解析器为基于优先级的递归下降解析,修复变量声明中
初始化表达式的内存泄漏问题。

完善类型限定符和存储类说明符的重复检查机制,增强语法分析的准确性。
This commit is contained in:
zzy
2026-03-12 21:14:08 +08:00
parent b00a42a539
commit c46578736a
15 changed files with 495 additions and 225 deletions

View File

@@ -6,7 +6,8 @@ static void rescan(scc_pproc_expand_t *expand_ctx,
const scc_pproc_macro_t *macro,
scc_lexer_tok_vec_t *tok_buffer);
static scc_lexer_tok_t stringify_argument(scc_lexer_tok_vec_t *arg_tokens) {
static scc_lexer_tok_t stringify_argument(scc_pproc_expand_t *ctx,
scc_lexer_tok_vec_t *arg_tokens) {
// WRITE BY AI
scc_cstring_t str = scc_cstring_create();
scc_cstring_append_ch(&str, '\"'); // 左引号
@@ -38,10 +39,13 @@ static scc_lexer_tok_t stringify_argument(scc_lexer_tok_vec_t *arg_tokens) {
scc_lexer_tok_t result;
result.type = SCC_TOK_STRING_LITERAL;
result.lexeme = str;
if (ctx->need_keep_org_pos)
result.loc = ctx->call_pos;
return result;
}
static scc_lexer_tok_t concatenate_tokens(const scc_lexer_tok_t *left,
static scc_lexer_tok_t concatenate_tokens(scc_pproc_expand_t *ctx,
const scc_lexer_tok_t *left,
const scc_lexer_tok_t *right) {
scc_cstring_t new_lex = scc_cstring_from_cstr("");
if (left != null) {
@@ -84,6 +88,8 @@ RETURN:
scc_lexer_drop_ring(ring);
scc_lexer_drop(&lexer);
scc_sstream_drop(&sstream);
if (ctx->need_keep_org_pos)
result.loc = ctx->call_pos;
return result;
}
@@ -102,7 +108,8 @@ static inline void scc_copy_expand(scc_pproc_expand_t *expand_ctx,
void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table,
scc_lexer_tok_ring_t *input,
scc_lexer_tok_ring_t *output,
const scc_pproc_macro_t *macro) {
const scc_pproc_macro_t *macro,
cbool need_keep_org_pos) {
scc_lexer_tok_vec_t expaned_buffer;
scc_vec_init(expaned_buffer);
@@ -130,7 +137,8 @@ void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table,
}
scc_lexer_tok_vec_t output_vec;
scc_pproc_expand_by_vec(macro_table, &expaned_buffer, &output_vec, false);
scc_pproc_expand_by_vec(macro_table, &expaned_buffer, &output_vec, false,
need_keep_org_pos);
Assert(output->cap == 0 && output->data == null); // FIXME hack it
*output = scc_lexer_array_to_ring(&output_vec);
}
@@ -138,13 +146,16 @@ void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table,
void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table,
scc_lexer_tok_vec_t *input,
scc_lexer_tok_vec_t *output,
cbool need_parse_defined) {
cbool need_parse_defined,
cbool need_keep_org_pos) {
scc_pproc_expand_t ctx;
scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(input);
ctx.input = ˚
ctx.macro_table = macro_table;
ctx.need_rescan = false;
ctx.need_parse_defined = need_parse_defined;
ctx.need_keep_org_pos = need_keep_org_pos;
ctx.call_pos = scc_pos_create();
scc_vec_init(ctx.output);
scc_pproc_macro_table_t expanded_set;
ctx.expanded_set = &expanded_set;
@@ -311,7 +322,8 @@ static void rescan(scc_pproc_expand_t *expand_ctx,
true);
scc_lexer_tok_vec_t output = {0};
scc_pproc_expand_by_vec(expand_ctx->macro_table, &expaned_buffer,
&output, expand_ctx->need_parse_defined);
&output, expand_ctx->need_parse_defined,
expand_ctx->need_keep_org_pos);
scc_vec_foreach(output, i) {
scc_vec_push(expand_ctx->output, scc_vec_at(output, i));
}
@@ -352,8 +364,8 @@ static inline int got_right_non_blank(int i,
return right_idx;
}
static void concact(scc_lexer_tok_vec_t *tok_buffer, scc_lexer_tok_t *right,
cbool gnu_va_arg_extend) {
static void concact(scc_pproc_expand_t *ctx, scc_lexer_tok_vec_t *tok_buffer,
scc_lexer_tok_t *right, cbool gnu_va_arg_extend) {
// ## contact
int tok_buf_size = (int)scc_vec_size(*tok_buffer);
int left_idx = got_left_non_blank(tok_buf_size, tok_buffer);
@@ -369,7 +381,7 @@ static void concact(scc_lexer_tok_vec_t *tok_buffer, scc_lexer_tok_t *right,
}
}
scc_lexer_tok_t concate_tok = concatenate_tokens(left, right);
scc_lexer_tok_t concate_tok = concatenate_tokens(ctx, left, right);
while (left_idx++ < tok_buf_size) {
scc_lexer_tok_drop(&scc_vec_pop(*tok_buffer));
@@ -409,6 +421,8 @@ static inline void expand_function_macro(scc_pproc_expand_t *expand_ctx,
scc_vec_foreach(macro->replaces, i) {
scc_lexer_tok_t tok =
scc_lexer_tok_copy(&scc_vec_at(macro->replaces, i));
if (expand_ctx->need_keep_org_pos)
tok.loc = expand_ctx->call_pos;
if (tok.type == SCC_TOK_BLANK) {
scc_cstring_free(&tok.lexeme);
tok.lexeme = scc_cstring_from_cstr(" ");
@@ -430,7 +444,8 @@ static inline void expand_function_macro(scc_pproc_expand_t *expand_ctx,
int j = find_params(&scc_vec_at(macro->replaces, right_idx), macro);
Assert(j != -1 && j < (int)scc_vec_size(splited_params));
tok = stringify_argument(&scc_vec_at(splited_params, j));
tok =
stringify_argument(expand_ctx, &scc_vec_at(splited_params, j));
scc_vec_push(tok_buffer, tok);
i = right_idx;
continue;
@@ -467,12 +482,12 @@ static inline void expand_function_macro(scc_pproc_expand_t *expand_ctx,
if (scc_strcmp(scc_cstring_as_cstr(&(right_tok->lexeme)),
"__VA_ARGS__") == 0) {
if (scc_vec_size(right_vec) == 0) {
concact(&tok_buffer, right, true);
concact(expand_ctx, &tok_buffer, right, true);
} else {
continue;
}
} else {
concact(&tok_buffer, right, false);
concact(expand_ctx, &tok_buffer, right, false);
}
scc_vec_foreach(right_vec, j) {
@@ -520,6 +535,8 @@ static inline void expand_object_macro(scc_pproc_expand_t *expand_ctx,
scc_vec_foreach(macro->replaces, i) {
scc_lexer_tok_t tok =
scc_lexer_tok_copy(&scc_vec_at(macro->replaces, i));
if (expand_ctx->need_keep_org_pos)
tok.loc = expand_ctx->call_pos;
if (tok.type == SCC_TOK_BLANK) {
// FIXME using function to warpper it
scc_cstring_free(&tok.lexeme);
@@ -536,7 +553,7 @@ static inline void expand_object_macro(scc_pproc_expand_t *expand_ctx,
right = &scc_vec_at(macro->replaces, right_idx);
}
concact(&tok_buffer, right, false);
concact(expand_ctx, &tok_buffer, right, false);
i = right_idx;
continue;
}
@@ -630,6 +647,7 @@ void scc_pproc_expand_macro(scc_pproc_expand_t *expand_ctx) {
}
expand_ctx->need_rescan = true;
expand_ctx->call_pos = tok.loc;
if (macro->type == SCC_PP_MACRO_OBJECT) {
scc_lexer_tok_drop(&tok);
expand_object_macro(expand_ctx, macro);