Files
scc/runtime/libcore/include/core_str.h
zzy 871d031ceb feat(lex_parser): 初始化词法解析器模块
新增词法解析器库 `smcc_lex_parser`,包含基础的词法规则解析功能:
- 支持字符、字符串、数字、标识符的解析
- 支持跳过注释、空白符、行尾等辅助函数
- 提供对应的单元测试用例,覆盖各类合法与非法输入情况

该模块依赖 `libcore`,并被 `smcc_lex` 模块引用以支持更上层的词法分析逻辑。
2025-11-23 22:53:46 +08:00

167 lines
4.0 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.
#ifndef __SMCC_CORE_STR_H__
#define __SMCC_CORE_STR_H__
#include "core_impl.h"
#include "core_log.h"
#include "core_type.h"
/**
* @brief 动态字符串结构体
* @attention 创建的字符串对象需要使用 cstring_free 释放
*/
typedef struct cstring {
usize size; /**< 字符串当前大小(包括结尾的'\0'*/
usize cap; /**< 分配的容量 */
char *data; /**< 实际存储数据的指针 */
} cstring_t;
/**
* @brief 创建一个新的空动态字符串对象
*
* @return cstring_t 初始化后的对象
*/
static inline cstring_t cstring_new(void) {
return (cstring_t){.data = null, .size = 0, .cap = 0};
}
/**
* @brief 从 C 风格字符串创建一个动态字符串副本
*
* @param s 输入的 C 风格字符串
* @return cstring_t 新建对象,包含输入字符串的副本
*/
static inline cstring_t cstring_from_cstr(const char *s) {
if (s == null) {
return cstring_new();
}
usize len = 0;
const char *p = s;
while (*p++)
len++;
char *data = (char *)smcc_malloc(len + 1);
Assert(data != null);
smcc_memcpy(data, s, len);
data[len] = '\0';
return (cstring_t){.size = len + 1, .cap = len + 1, .data = data};
}
/**
* @brief 释放动态字符串占用的内存资源
*
* @param str 要被释放的字符串指针
*/
static inline void cstring_free(cstring_t *str) {
if (str == null) {
return;
}
if (str->data != null && str->cap != 0) {
smcc_free(str->data);
str->data = null;
}
str->size = 0;
str->cap = 0;
}
/**
* @brief 向动态字符串末尾追加一段 C 风格字符串
*
* @param str 目标动态字符串指针
* @param data 要追加的 C 字符串指针
* @param len 要追加的 C 字符串长度
*/
static inline void cstring_push_cstr(cstring_t *str, const char *data,
usize len) {
if (str == null || data == null || len == 0) {
return;
}
if (str->cap == 0) {
str->size = 1;
}
// 如果需要扩容
if (str->size + len > str->cap) {
usize new_cap = str->cap;
while (new_cap < str->size + len) {
new_cap *= 2;
// FIXME write by AI 处理溢出情况
if (new_cap == 0) {
new_cap = str->size + len;
break;
}
}
char *new_data = (char *)smcc_realloc(str->data, new_cap);
Assert(new_data != null);
str->data = new_data;
str->cap = new_cap;
}
smcc_memcpy(str->data + str->size - 1, data, len);
str->size += len;
str->data[str->size - 1] = '\0'; // 保证 C 字符串兼容性
}
/**
* @brief 向动态字符串末尾追加一个字符
*
* @param str 目标动态字符串指针
* @param ch 要追加的字符
*/
static inline void cstring_push(cstring_t *str, char ch) {
cstring_push_cstr(str, &ch, 1);
}
/**
* @brief 获取动态字符串的实际内容长度 不包括结尾的'\0'
*
* @param str 动态字符串指针
* @return usize 字符串实际长度
*/
static inline usize cstring_len(const cstring_t *str) {
return str ? str->size - 1 : 0;
}
/**
* @brief 判断动态字符串是否为空
*
* @param str 动态字符串指针
* @return cbool
*/
static inline cbool cstring_is_empty(const cstring_t *str) {
return str == null || str->size == 0;
}
/**
* @brief 清空动态字符串内容但保留已分配的内存空间
*
* @param str 动态字符串指针
*/
static inline void cstring_clear(cstring_t *str) {
if (str) {
str->size = 1;
if (str->data) {
str->data[0] = '\0';
}
}
}
/**
* @brief 将动态字符串转换为 C 风格字符串
*
* @param str 动态字符串指针
* @return char* 返回指向内部缓冲区的 C 风格字符串指针
*/
static inline char *cstring_as_cstr(const cstring_t *str) {
if (str == null || str->data == null) {
return "";
}
return str->data;
}
#endif /* __SMCC_CORE_STR_H__ */