feat(parser): 启用parser和ast模块并重构解析器结构

- 在cbuild.toml中启用parser和ast依赖项
- 将AST内置类型枚举重命名为SCC_AST_BUILTIN_TYPE_*前缀格式
- 修复ast_def.h中的类型字段命名,将builtin改为type
- 添加逗号操作符支持到表达式操作符枚举中
- 更新字面量表达式的lexeme字段为const char*指针和owned标志
- 重构解析器头文件结构,分离为parser.h、parser_utils.h、scc_sema.h等
- 实现新的解析器工具函数,包括预览、消费、回溯等功能
- 更新声明解析逻辑,使用新的解析器接口进行token处理
- 添加符号表语义分析功能框架
- 修复词法分析器中token移动时的空指针检查
- 统一使用scc_tree_dump_printf替代直接的scc_printf调用
This commit is contained in:
zzy
2026-03-09 15:25:12 +08:00
parent a805814d3f
commit 1fceeca011
28 changed files with 2759 additions and 1987 deletions

View File

@@ -16,6 +16,8 @@ typedef enum {
SCC_FILE_WRITE,
SCC_FILE_APPEND,
} scc_fmode_t;
#define scc_stdout 1
#define scc_stderr 2
scc_file_t scc_fopen(const char *path, scc_fmode_t mode);
void scc_fclose(scc_file_t file);
usize scc_fsize(scc_file_t file);

View File

@@ -65,13 +65,39 @@
(ring).tail++; \
} while (0)
/**
* @brief 环形缓冲区核心操作模板
* @param ring 环形缓冲区变量
* @param ok 状态输出变量
* @param op 具体操作代码块(可包含多条语句)
*
* 封装了以下公共逻辑:
* 1. 确保缓冲区有数据可用
* 2. 检查probe是否越界
* 3. 计算物理索引
* 4. 执行具体操作
*/
#define _SCC_RING_OP(ring, ok, op) \
do { \
_scc_ring_ensure(ring, ok); \
if (!(ok)) \
break; \
if ((ring).probe >= (ring).tail) { \
ok = 0; \
break; \
} \
usize _phys = _scc_ring_phys(ring, (ring).probe); \
(void)_phys; \
op; \
} while (0)
// ==================== 用户操作宏 ====================
/**
* @brief 初始化环形缓冲区
* @param ring 环形缓冲区变量
* @param cap 容量
* @param fill_func 填充回调函数 (可传 NULL)
* @param fill_func 填充回调函数 (可传 NULL) 返回true表示成功
*
* 内存分配失败由 scc_malloc 内部处理 (如 LOG_FATAL)
*/
@@ -116,17 +142,16 @@
* @param ok 变量名,用于接收成功状态 (cbool 类型)
*/
#define scc_ring_peek(ring, val, ok) \
do { \
_scc_ring_ensure(ring, ok); \
if (!(ok)) \
break; \
if ((ring).probe >= (ring).tail) { \
ok = 0; \
break; \
} \
usize _phys = _scc_ring_phys(ring, (ring).probe); \
val = (ring).data[_phys]; \
} while (0)
_SCC_RING_OP(ring, ok, val = (ring).data[_phys])
/**
* @brief 预览 probe 位置的引用 (不移动 probe)
* @param ring 环形缓冲区变量
* @param val_ref 引用变量接收地址
* @param ok 变量名,用于接收成功状态
*/
#define scc_ring_unsafe_peek_ref(ring, val_ref, ok) \
_SCC_RING_OP(ring, ok, val_ref = &((ring).data[_phys]))
/**
* @brief 获取 probe 位置的元素,并将 probe 前进一步
@@ -135,18 +160,41 @@
* @param ok 变量名,用于接收成功状态 (cbool 类型)
*/
#define scc_ring_next(ring, val, ok) \
do { \
_scc_ring_ensure(ring, ok); \
if (!(ok)) \
break; \
if ((ring).probe >= (ring).tail) { \
ok = 0; \
break; \
} \
usize _phys = _scc_ring_phys(ring, (ring).probe); \
val = (ring).data[_phys]; \
(ring).probe++; \
} while (0)
_SCC_RING_OP(ring, ok, val = (ring).data[_phys]; (ring).probe++)
/**
* @brief 获取 probe 位置的引用,并将 probe 前进一步
* @param ring 环形缓冲区变量
* @param val 引用变量接收地址
* @param ok 变量名,用于接收成功状态
*/
#define scc_ring_unsafe_next_ref(ring, val, ok) \
_SCC_RING_OP(ring, ok, val = &((ring).data[_phys]); (ring).probe++)
/**
* @brief 获取元素并消费(移动 probe 和 head)
* @param ring 环形缓冲区变量
* @param val 变量名,用于接收元素值
* @param ok 变量名,用于接收成功状态
*/
#define scc_ring_next_consume(ring, val, ok) \
_SCC_RING_OP(ring, ok, val = (ring).data[_phys]; (ring).probe++; \
(ring).head = (ring).probe)
#define scc_ring_unsafe_pure_next_consume(ring) \
_SCC_RING_OP(ring, ok, (ring).probe++; (ring).head = (ring).probe)
/**
* @brief 获取元素并消费(移动 probe 和 head)
* @param ring 环形缓冲区变量
* @param val 变量名,用于接收元素值
* @param ok 变量名,用于接收成功状态
*/
#define scc_ring_unsafe_next_ref_consume(ring, val, ok) \
_SCC_RING_OP(ring, ok, val = &((ring).data[_phys]); (ring).probe++; \
(ring).head = (ring).probe)
#define scc_ring_not_eof(ring, ok) _SCC_RING_OP(ring, ok, )
/**
* @brief 将 probe 后退一步 (不能低于 head)
@@ -182,16 +230,4 @@
*/
#define scc_ring_available(ring) ((ring).tail - (ring).probe)
/**
* @brief 获取 probe 位置的元素,并将 probe 前进一步同时标记为已消费
* @param ring 环形缓冲区变量
* @param val 变量名,用于接收元素值 (例如 int ch)
* @param ok 变量名,用于接收成功状态 (cbool 类型)
*/
#define scc_ring_next_consume(ring, val, ok) \
do { \
scc_ring_next(ring, val, ok); \
scc_ring_consume(ring); \
} while (0)
#endif /* __SCC_CORE_RING_H__ */

View File

@@ -5,9 +5,6 @@
#define __SCC_LOG_IMPL_IMPORT_SRC__
#include <scc_core_log.h>
#define scc_stdout 1
#define scc_stderr 2
void putchar_(char ch) { LOG_FATAL("you can't use printf.c directly"); }
scc_file_t scc_fopen(const char *path, scc_fmode_t mode) {