Files
scc/libs/parser/tests/test_parser_unit.c
zzy 742bede02f feat(ast): 修改函数调用表达式的结构定义
在AST定义中将函数调用表达式的name字段替换为callee字段,
以支持更复杂的函数调用场景。同时更新了相关的初始化函数、
转储函数和解析逻辑,使函数调用表达式能够正确处理callee节点。

BREAKING CHANGE: 函数调用表达式的结构发生了改变,从使用name字符串
改为使用callee表达式节点。
2026-03-10 14:33:32 +08:00

603 lines
22 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <assert.h>
#include <scc_lexer.h>
#include <scc_parser.h>
#include <string.h>
#include <utest/acutest.h>
typedef scc_ast_node_t *(*scc_parse_node_func)(scc_parser_t *parser);
static scc_ast_node_t *process_input(const char *input,
scc_parse_node_func parse_func) {
int res = 0;
scc_sstream_t mem_stream;
res = scc_sstream_init_by_buffer(&mem_stream, input, strlen(input), false,
16);
Assert(res == 0);
scc_lexer_t lexer;
scc_lexer_init(&lexer, scc_sstream_to_ring(&mem_stream));
scc_lexer_tok_ring_t *tok_ring = scc_lexer_to_ring(&lexer, 64, false);
scc_parser_t parser;
scc_parser_init(&parser, tok_ring, null);
scc_ast_node_t *ret = parse_func(&parser);
cbool not_eof = false;
scc_ring_not_eof(*parser.ring, not_eof);
Assert(!not_eof == true);
scc_lexer_drop_ring(parser.ring);
scc_parser_drop(&parser);
scc_lexer_drop(&lexer);
scc_sstream_drop(&mem_stream);
return ret;
}
typedef void (*scc_tree_dump_output_t)(void *userdata, const char *fmt, ...);
#define BUFFER_SIZE (4096)
char expect_buffer[BUFFER_SIZE];
char output_buffer[BUFFER_SIZE];
static void dump2buffer(void *_buffer, const char *fmt, ...) {
char *buffer = _buffer;
va_list args;
va_start(args, fmt);
scc_vsnprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer) - 1,
fmt, args);
va_end(args);
}
#define SCC_CHECK_AST(expect_node_ptr, str, parse_func) \
do { \
scc_ast_node_t *output_node_ptr = \
process_input(str, (scc_parse_node_func)parse_func); \
scc_tree_dump_ctx_t ctx; \
expect_buffer[0] = '\n', expect_buffer[1] = '\0'; \
scc_tree_dump_ctx_init(&ctx, true, dump2buffer, expect_buffer); \
scc_ast_dump_node(&ctx, expect_node_ptr); \
scc_tree_dump_ctx_drop(&ctx); \
output_buffer[0] = '\n', output_buffer[1] = '\0'; \
scc_tree_dump_ctx_init(&ctx, true, dump2buffer, output_buffer); \
scc_ast_dump_node(&ctx, output_node_ptr); \
scc_tree_dump_ctx_drop(&ctx); \
TEST_CHECK(strcmp(output_buffer, expect_buffer) == 0); \
TEST_MSG("Expected: %s", expect_buffer); \
TEST_MSG("Produced: %s", output_buffer); \
} while (0);
static void test_parser_unit(void) {
// 1. 变量声明 int a;
{
scc_ast_decl_t int_decl;
scc_ast_decl_val_init(
&int_decl, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", null);
SCC_CHECK_AST(&int_decl.base, "int a;", scc_parse_declaration);
}
// 2. 函数声明 int main(void) {}
{
// 构造函数类型:返回 int参数为空
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int,
null); // 无参数,非可变参数
// 构造复合语句块(空)
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, null);
// 构造函数声明
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
SCC_CHECK_AST(&func_decl.base, "int main(void) {}",
scc_parse_declaration);
}
// 3. 翻译单元包含一个函数定义
{
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, null);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, null);
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
// 构造翻译单元
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls);
SCC_CHECK_AST(&tu.base, "int main(void) {}",
scc_parse_translation_unit);
}
// 4. 带返回语句的函数 int main(void) { return 65536; }
{
// 返回语句中的整数常量
scc_ast_expr_t ret_val;
scc_ast_expr_literal_int_init(&ret_val, "65536", false);
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &ret_val);
// 复合语句包含该返回语句
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items); // items 被移动
// 函数类型
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, null);
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls);
SCC_CHECK_AST(&tu.base, "int main(void) { return 65536; }",
scc_parse_translation_unit);
}
// 5. 多语句函数(复杂示例)
{
// 变量声明 int a;
scc_ast_decl_t a_decl;
scc_ast_decl_val_init(&a_decl, &scc_ast_builtin_type_int, "a", null);
// 变量声明 int b;
scc_ast_decl_t b_decl;
scc_ast_decl_val_init(&b_decl, &scc_ast_builtin_type_int, "b", null);
// 表达式 1 + 2 * 3
scc_ast_expr_t lit1, lit2, lit3, mul, add;
scc_ast_expr_literal_int_init(&lit1, "1", false);
scc_ast_expr_literal_int_init(&lit2, "2", false);
scc_ast_expr_literal_int_init(&lit3, "3", false);
scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &lit2, &lit3);
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &lit1, &mul);
// 赋值 a = 1 + 2 * 3;
scc_ast_expr_t a_ref1, assign1;
scc_ast_expr_identifier_init(&a_ref1, "a");
scc_ast_expr_binary_init(&assign1, SCC_AST_OP_ASSIGN, &a_ref1, &add);
scc_ast_stmt_t assign1_stmt;
scc_ast_stmt_expr_init(&assign1_stmt, &assign1);
// 赋值 b = 7;
scc_ast_expr_t lit7;
scc_ast_expr_literal_int_init(&lit7, "7", false);
scc_ast_expr_t b_ref1, assign2;
scc_ast_expr_identifier_init(&b_ref1, "b");
scc_ast_expr_binary_init(&assign2, SCC_AST_OP_ASSIGN, &b_ref1, &lit7);
scc_ast_stmt_t assign2_stmt;
scc_ast_stmt_expr_init(&assign2_stmt, &assign2);
// 表达式 a - b + 1
scc_ast_expr_t a_ref2, b_ref2, sub, add2, lit1_2;
scc_ast_expr_identifier_init(&a_ref2, "a");
scc_ast_expr_identifier_init(&b_ref2, "b");
scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &a_ref2, &b_ref2);
scc_ast_expr_literal_int_init(&lit1_2, "1", false);
scc_ast_expr_binary_init(&add2, SCC_AST_OP_ADD, &sub, &lit1_2);
// 赋值 a = a - b + 1;
scc_ast_expr_t a_ref3, assign3;
scc_ast_expr_identifier_init(&a_ref3, "a");
scc_ast_expr_binary_init(&assign3, SCC_AST_OP_ASSIGN, &a_ref3, &add2);
scc_ast_stmt_t assign3_stmt;
scc_ast_stmt_expr_init(&assign3_stmt, &assign3);
// return a;
scc_ast_expr_t a_ref4;
scc_ast_expr_identifier_init(&a_ref4, "a");
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &a_ref4);
// 复合语句块,按顺序放入
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&a_decl);
scc_vec_push(items, (scc_ast_node_t *)&b_decl);
scc_vec_push(items, (scc_ast_node_t *)&assign1_stmt);
scc_vec_push(items, (scc_ast_node_t *)&assign2_stmt);
scc_vec_push(items, (scc_ast_node_t *)&assign3_stmt);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items);
// 函数类型
scc_ast_type_t func_type;
scc_ast_type_function_init(
&func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, null);
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls);
const char *input = "int main() {\n"
" int a;\n"
" int b;\n"
" a = 1 + 2 * 3;\n"
" b = 7;\n"
" a = a - b + 1;\n"
" return a;\n"
"}\n";
SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit);
}
{
// 整数字面量 10
scc_ast_expr_t lit10;
scc_ast_expr_literal_int_init(&lit10, "10", false);
// 变量声明 int x = 10;
scc_ast_decl_t x_decl;
scc_ast_decl_val_init(
&x_decl, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", &lit10);
// 表达式 x + 1
scc_ast_expr_t x_ref1, lit1, add;
scc_ast_expr_identifier_init(&x_ref1, "x");
scc_ast_expr_literal_int_init(&lit1, "1", false);
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &x_ref1, &lit1);
// 赋值 x = x + 1
scc_ast_expr_t x_ref2, assign;
scc_ast_expr_identifier_init(&x_ref2, "x");
scc_ast_expr_binary_init(&assign, SCC_AST_OP_ASSIGN, &x_ref2, &add);
// 表达式语句
scc_ast_stmt_t assign_stmt;
scc_ast_stmt_expr_init(&assign_stmt, &assign);
// return x
scc_ast_expr_t x_ref3;
scc_ast_expr_identifier_init(&x_ref3, "x");
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &x_ref3);
// 复合语句块
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&x_decl);
scc_vec_push(items, (scc_ast_node_t *)&assign_stmt);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items);
// 函数类型(返回 int无参数
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
null); // null 表示无参数
// 函数声明 int main() { ... }
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
// 翻译单元
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls);
// 输入源代码
const char *input = "int main() {\n"
" int x = 10;\n"
" x = x + 1;\n"
" return x;\n"
"}\n";
// 比较解析结果与期望 AST
SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit);
}
}
static void test_parser_expression(void) {
// 1. 基本表达式
{
scc_ast_expr_t ident;
scc_ast_expr_identifier_init(&ident, "x");
SCC_CHECK_AST(&ident.base, "x", scc_parse_expression);
scc_ast_expr_t int_lit;
scc_ast_expr_literal_int_init(&int_lit, "42", false);
SCC_CHECK_AST(&int_lit.base, "42", scc_parse_expression);
scc_ast_expr_t str_lit;
scc_ast_expr_literal_string_init(&str_lit, "\"hello\"", false);
SCC_CHECK_AST(&str_lit.base, "\"hello\"", scc_parse_expression);
// 括号表达式(解析器应直接返回内部表达式)
scc_ast_expr_t paren_ident;
scc_ast_expr_identifier_init(&paren_ident, "y");
SCC_CHECK_AST(&paren_ident.base, "(y)", scc_parse_expression);
}
// 2. 后缀表达式
{
// 数组下标 a[10]
scc_ast_expr_t a, index, subscript;
scc_ast_expr_identifier_init(&a, "a");
scc_ast_expr_literal_int_init(&index, "10", false);
scc_ast_expr_array_subscript_init(&subscript, &a, &index);
SCC_CHECK_AST(&subscript.base, "a[10]", scc_parse_expression);
// 函数调用 f()
scc_ast_expr_t f;
scc_ast_expr_identifier_init(&f, "f");
scc_ast_expr_vec_t args;
scc_vec_init(args);
scc_ast_expr_t call;
scc_ast_expr_t callee1;
scc_ast_expr_identifier_init(&callee1, "f");
scc_ast_expr_call_init(&call, &callee1,
&args); // 使用函数名target 在语义分析时填充
SCC_CHECK_AST(&call.base, "f()", scc_parse_expression);
// 函数调用带参数 f(1, x)
scc_ast_expr_t arg1, arg2;
scc_ast_expr_literal_int_init(&arg1, "1", false);
scc_ast_expr_identifier_init(&arg2, "x");
scc_ast_expr_vec_t args2;
scc_vec_init(args2);
scc_vec_push(args2, &arg1);
scc_vec_push(args2, &arg2);
scc_ast_expr_t callee2;
scc_ast_expr_identifier_init(&callee2, "f");
scc_ast_expr_t call2;
scc_ast_expr_call_init(&call2, &callee2, &args2);
SCC_CHECK_AST(&call2.base, "f(1, x)", scc_parse_expression);
// 成员访问 .
scc_ast_expr_t s, dot;
scc_ast_expr_identifier_init(&s, "s");
scc_ast_expr_member_init(&dot, &s, "field");
SCC_CHECK_AST(&dot.base, "s.field", scc_parse_expression);
// 指针成员访问 ->
scc_ast_expr_t p, arrow;
scc_ast_expr_identifier_init(&p, "p");
scc_ast_expr_ptr_member_init(&arrow, &p, "field");
SCC_CHECK_AST(&arrow.base, "p->field", scc_parse_expression);
// 后缀 ++/--
scc_ast_expr_t x, post_inc, post_dec;
scc_ast_expr_identifier_init(&x, "x");
scc_ast_expr_unary_init(&post_inc, SCC_AST_OP_POSTFIX_INCREMENT, &x);
scc_ast_expr_unary_init(&post_dec, SCC_AST_OP_POSTFIX_DECREMENT, &x);
SCC_CHECK_AST(&post_inc.base, "x++", scc_parse_expression);
SCC_CHECK_AST(&post_dec.base, "x--", scc_parse_expression);
}
// 3. 一元表达式
{
scc_ast_expr_t x;
scc_ast_expr_identifier_init(&x, "x");
scc_ast_expr_t pre_inc;
scc_ast_expr_unary_init(&pre_inc, SCC_AST_OP_PREFIX_INCREMENT, &x);
SCC_CHECK_AST(&pre_inc.base, "++x", scc_parse_expression);
scc_ast_expr_t pre_dec;
scc_ast_expr_unary_init(&pre_dec, SCC_AST_OP_PREFIX_DECREMENT, &x);
SCC_CHECK_AST(&pre_dec.base, "--x", scc_parse_expression);
scc_ast_expr_t addr;
scc_ast_expr_unary_init(&addr, SCC_AST_OP_ADDRESS_OF, &x);
SCC_CHECK_AST(&addr.base, "&x", scc_parse_expression);
scc_ast_expr_t deref;
scc_ast_expr_unary_init(&deref, SCC_AST_OP_INDIRECTION, &x);
SCC_CHECK_AST(&deref.base, "*x", scc_parse_expression);
scc_ast_expr_t plus;
scc_ast_expr_unary_init(&plus, SCC_AST_OP_UNARY_PLUS, &x);
SCC_CHECK_AST(&plus.base, "+x", scc_parse_expression);
scc_ast_expr_t minus;
scc_ast_expr_unary_init(&minus, SCC_AST_OP_UNARY_MINUS, &x);
SCC_CHECK_AST(&minus.base, "-x", scc_parse_expression);
scc_ast_expr_t bit_not;
scc_ast_expr_unary_init(&bit_not, SCC_AST_OP_BITWISE_NOT, &x);
SCC_CHECK_AST(&bit_not.base, "~x", scc_parse_expression);
scc_ast_expr_t log_not;
scc_ast_expr_unary_init(&log_not, SCC_AST_OP_LOGICAL_NOT, &x);
SCC_CHECK_AST(&log_not.base, "!x", scc_parse_expression);
// sizeof 表达式
// TODO
// scc_ast_expr_t sizeof_expr;
// scc_ast_expr_sizeof_expr_init(&sizeof_expr, &x);
// SCC_CHECK_AST(&sizeof_expr.base, "sizeof x", scc_parse_expression);
}
// 4. 类型转换(示例: (int)x
{
// scc_ast_type_t
// int_type; // 使用内置类型全局变量即可,但类型转换需要一个类型节点
// //
// 我们可以直接使用全局内置类型的地址,但类型转换节点需要一个类型节点,直接引用全局即可
// // TODO
// scc_ast_expr_t x;
// scc_ast_expr_identifier_init(&x, "x");
// scc_ast_expr_t cast;
// scc_ast_expr_cast_init(&cast,
// (scc_ast_type_t *)&scc_ast_builtin_type_int,
// &x);
// SCC_CHECK_AST(&cast.base, "(int)x", scc_parse_expression);
}
// 5. 二元运算符优先级
{
scc_ast_expr_t a, b, c, d;
scc_ast_expr_identifier_init(&a, "a");
scc_ast_expr_identifier_init(&b, "b");
scc_ast_expr_identifier_init(&c, "c");
scc_ast_expr_identifier_init(&d, "d");
// a * b + c
scc_ast_expr_t mul, add;
scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &a, &b);
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &mul, &c);
SCC_CHECK_AST(&add.base, "a * b + c", scc_parse_expression);
// a - b - c => (a - b) - c
scc_ast_expr_t sub1, sub2;
scc_ast_expr_binary_init(&sub1, SCC_AST_OP_SUB, &a, &b);
scc_ast_expr_binary_init(&sub2, SCC_AST_OP_SUB, &sub1, &c);
SCC_CHECK_AST(&sub2.base, "a - b - c", scc_parse_expression);
// a << b
scc_ast_expr_t shift;
scc_ast_expr_binary_init(&shift, SCC_AST_OP_LEFT_SHIFT, &a, &b);
SCC_CHECK_AST(&shift.base, "a << b", scc_parse_expression);
// a < b
scc_ast_expr_t lt;
scc_ast_expr_binary_init(&lt, SCC_AST_OP_LESS, &a, &b);
SCC_CHECK_AST(&lt.base, "a < b", scc_parse_expression);
// a == b
scc_ast_expr_t eq;
scc_ast_expr_binary_init(&eq, SCC_AST_OP_EQUAL, &a, &b);
SCC_CHECK_AST(&eq.base, "a == b", scc_parse_expression);
// a & b ^ c | d
scc_ast_expr_t bitand, bitxor, bitor;
scc_ast_expr_binary_init(&bitand, SCC_AST_OP_BITWISE_AND, &a, &b);
scc_ast_expr_binary_init(&bitxor, SCC_AST_OP_BITWISE_XOR, &bitand, &c);
scc_ast_expr_binary_init(&bitor, SCC_AST_OP_BITWISE_OR, &bitxor, &d);
SCC_CHECK_AST(&bitor.base, "a & b ^ c | d", scc_parse_expression);
// a && b || c
scc_ast_expr_t logand, logor;
scc_ast_expr_binary_init(&logand, SCC_AST_OP_LOGICAL_AND, &a, &b);
scc_ast_expr_binary_init(&logor, SCC_AST_OP_LOGICAL_OR, &logand, &c);
SCC_CHECK_AST(&logor.base, "a && b || c", scc_parse_expression);
}
// 6. 三元运算符
{
scc_ast_expr_t a, b, c;
scc_ast_expr_identifier_init(&a, "a");
scc_ast_expr_identifier_init(&b, "b");
scc_ast_expr_identifier_init(&c, "c");
// a ? b : c
scc_ast_expr_t cond1;
scc_ast_expr_cond_init(&cond1, &a, &b, &c);
SCC_CHECK_AST(&cond1.base, "a ? b : c", scc_parse_expression);
// a ? b : c ? d : e => a ? b : (c ? d : e)
scc_ast_expr_t d, e;
scc_ast_expr_identifier_init(&d, "d");
scc_ast_expr_identifier_init(&e, "e");
scc_ast_expr_t inner, outer;
scc_ast_expr_cond_init(&inner, &c, &d, &e);
scc_ast_expr_cond_init(&outer, &a, &b, &inner);
SCC_CHECK_AST(&outer.base, "a ? b : c ? d : e", scc_parse_expression);
}
// 7. 赋值运算符
{
scc_ast_expr_t a, b, c;
scc_ast_expr_identifier_init(&a, "a");
scc_ast_expr_identifier_init(&b, "b");
scc_ast_expr_identifier_init(&c, "c");
scc_ast_expr_t lit42;
scc_ast_expr_literal_int_init(&lit42, "42", false);
// a = b = c
scc_ast_expr_t assign_inner, assign_outer;
scc_ast_expr_binary_init(&assign_inner, SCC_AST_OP_ASSIGN, &b, &c);
scc_ast_expr_binary_init(&assign_outer, SCC_AST_OP_ASSIGN, &a,
&assign_inner);
SCC_CHECK_AST(&assign_outer.base, "a = b = c", scc_parse_expression);
// a = 42
scc_ast_expr_t assign1;
scc_ast_expr_binary_init(&assign1, SCC_AST_OP_ASSIGN, &a, &lit42);
SCC_CHECK_AST(&assign1.base, "a = 42", scc_parse_expression);
// a = a - b + 42
scc_ast_expr_t sub, add, assign2;
scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &a, &b);
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &sub, &lit42);
scc_ast_expr_binary_init(&assign2, SCC_AST_OP_ASSIGN, &a, &add);
SCC_CHECK_AST(&assign2.base, "a = a - b + 42", scc_parse_expression);
// a += b
scc_ast_expr_t add_assign;
scc_ast_expr_binary_init(&add_assign, SCC_AST_OP_ASSIGN_ADD, &a, &b);
SCC_CHECK_AST(&add_assign.base, "a += b", scc_parse_expression);
}
// 8. 逗号运算符
{
scc_ast_expr_t a, b;
scc_ast_expr_identifier_init(&a, "a");
scc_ast_expr_identifier_init(&b, "b");
scc_ast_expr_t comma;
scc_ast_expr_binary_init(&comma, SCC_AST_OP_COMMA, &a, &b);
SCC_CHECK_AST(&comma.base, "a, b", scc_parse_expression);
}
// 9. 混合优先级
{
scc_ast_expr_t a, b, c, d;
scc_ast_expr_identifier_init(&a, "a");
scc_ast_expr_identifier_init(&b, "b");
scc_ast_expr_identifier_init(&c, "c");
scc_ast_expr_identifier_init(&d, "d");
// a + b * c - d
scc_ast_expr_t mul, add, sub;
scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &b, &c);
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &a, &mul);
scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &add, &d);
SCC_CHECK_AST(&sub.base, "a + b * c - d", scc_parse_expression);
// *p++
scc_ast_expr_t p, post_inc, deref;
scc_ast_expr_identifier_init(&p, "p");
scc_ast_expr_unary_init(&post_inc, SCC_AST_OP_POSTFIX_INCREMENT, &p);
scc_ast_expr_unary_init(&deref, SCC_AST_OP_INDIRECTION, &post_inc);
SCC_CHECK_AST(&deref.base, "*p++", scc_parse_expression);
}
}
TEST_LIST = {
{"parser_unit", test_parser_unit},
{"parser_expression", test_parser_expression},
{null, null},
};