refactor(lex_parser): 重命名libcore为scc_core并重构头文件包含
- 将依赖项从libcore重命名为scc_core - 更新头文件包含路径从<libcore.h>到<scc_core.h> - 保持原有功能不变 refactor(lexer): 重命名libcore为scc_core并添加词法流式解析功能 - 将依赖项从libcore重命名为scc_core - 移除不再需要的scc_lexer_token结构体定义 - 重命名struct cc_lexer为struct scc_lexer - 添加scc_lexer_stream_t流式解析器相关定义和实现 - 新增lexer_stream.c文件实现流式token缓冲功能 refactor(lexer_log): 重命名logger变量和头文件定义 - 将头文件保护宏从__SMCC_LEXER_LOG_H__改为__SCC_LEXER_LOG_H__ - 将logger变量从__smcc_lexer_log改为__scc_lexer_log - 更新头文件包含从<libcore.h>到<scc_core.h> refactor(lexer_token): 重新组织token头文件结构 - 将头文件保护宏从__SMCC_CC_TOKEN_H__改为__SCC_LEXER_TOKEN_H__ - 更新头文件包含从<libcore.h>到<scc_core.h> - 将scc_lexer_token结构体定义移至该文件 refactor(lexer): 简化token匹配代码格式 - 移除LCC相关的注释内容 - 优化括号符号的token匹配代码格式,使用clang-format控制 refactor(pprocessor): 更新依赖项名称和头文件包含 - 将libcore重命名为scc_core - 将libutils重命名为scc_utils - 更新头文件包含路径 refactor(runtime): 重命名libcore为scc_core并重构目录结构 - 将libcore目录重命名为scc_core - 将libutils目录重命名为scc_utils - 更新所有相关的头文件包含路径 - 修改cbuild.toml中的包名称 - 更新core_vec.h中的宏定义以支持标准库模式
This commit is contained in:
@@ -2,4 +2,4 @@
|
|||||||
name = "scc_lex_parser"
|
name = "scc_lex_parser"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
dependencies = [{ name = "libcore", path = "../../runtime/libcore" }]
|
dependencies = [{ name = "scc_core", path = "../../runtime/scc_core" }]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __SCC_LEX_PARSER_H__
|
#ifndef __SCC_LEX_PARSER_H__
|
||||||
#define __SCC_LEX_PARSER_H__
|
#define __SCC_LEX_PARSER_H__
|
||||||
|
|
||||||
#include <libcore.h>
|
#include <scc_core.h>
|
||||||
|
|
||||||
static inline cbool scc_lex_parse_is_endline(int ch) {
|
static inline cbool scc_lex_parse_is_endline(int ch) {
|
||||||
return ch == '\n' || ch == '\r';
|
return ch == '\n' || ch == '\r';
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ name = "scc_lex"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "libcore", path = "../../runtime/libcore" },
|
{ name = "scc_core", path = "../../runtime/scc_core" },
|
||||||
{ name = "lex_parser", path = "../lex_parser" },
|
{ name = "lex_parser", path = "../lex_parser" },
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,20 +7,14 @@
|
|||||||
#define __SCC_LEXER_H__
|
#define __SCC_LEXER_H__
|
||||||
|
|
||||||
#include "lexer_token.h"
|
#include "lexer_token.h"
|
||||||
#include <libcore.h>
|
#include <scc_core.h>
|
||||||
|
|
||||||
typedef struct scc_lexer_token {
|
|
||||||
scc_tok_type_t type;
|
|
||||||
scc_cvalue_t value;
|
|
||||||
scc_pos_t loc;
|
|
||||||
} scc_lexer_tok_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 词法分析器核心结构体
|
* @brief 词法分析器核心结构体
|
||||||
*
|
*
|
||||||
* 封装词法分析所需的状态信息和缓冲区管理
|
* 封装词法分析所需的状态信息和缓冲区管理
|
||||||
*/
|
*/
|
||||||
typedef struct cc_lexer {
|
typedef struct scc_lexer {
|
||||||
scc_probe_stream_t *stream;
|
scc_probe_stream_t *stream;
|
||||||
scc_pos_t pos;
|
scc_pos_t pos;
|
||||||
} scc_lexer_t;
|
} scc_lexer_t;
|
||||||
@@ -50,4 +44,61 @@ void scc_lexer_get_token(scc_lexer_t *lexer, scc_lexer_tok_t *token);
|
|||||||
*/
|
*/
|
||||||
void scc_lexer_get_valid_token(scc_lexer_t *lexer, scc_lexer_tok_t *token);
|
void scc_lexer_get_valid_token(scc_lexer_t *lexer, scc_lexer_tok_t *token);
|
||||||
|
|
||||||
|
typedef SCC_VEC(scc_lexer_tok_t) scc_lexer_tok_vec_t;
|
||||||
|
|
||||||
|
typedef struct scc_lexer_stream scc_lexer_stream_t;
|
||||||
|
struct scc_lexer_stream {
|
||||||
|
scc_lexer_t *lexer;
|
||||||
|
scc_lexer_tok_vec_t toks; // 循环缓冲区
|
||||||
|
usize curr_pos; // 当前读取位置(逻辑位置)
|
||||||
|
usize probe_pos; // 已填充位置(逻辑位置)
|
||||||
|
cbool need_comment;
|
||||||
|
|
||||||
|
/// @brief 向前读取n个token
|
||||||
|
const scc_lexer_tok_t *(*peek)(scc_lexer_stream_t *stream, usize n);
|
||||||
|
|
||||||
|
/// @brief 指针推进到offset
|
||||||
|
void (*advance)(scc_lexer_stream_t *stream, usize offset);
|
||||||
|
|
||||||
|
/// @brief 销毁并释放资源
|
||||||
|
void (*drop)(scc_lexer_stream_t *stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 将词法分析器转换成流式输出(自带缓冲区)
|
||||||
|
* @param[in] lexer 已经词法分析器实例
|
||||||
|
* @param[out] stream 输出流对象指针
|
||||||
|
* @param[in] need_comment 输出时是否需要注释
|
||||||
|
*/
|
||||||
|
void scc_lexer_to_stream(scc_lexer_t *lexer, scc_lexer_stream_t *stream,
|
||||||
|
cbool need_comment);
|
||||||
|
|
||||||
|
static inline const scc_lexer_tok_t *
|
||||||
|
scc_lexer_stream_current(scc_lexer_stream_t *stream) {
|
||||||
|
Assert(stream != null);
|
||||||
|
return stream->peek(stream, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const scc_lexer_tok_t *
|
||||||
|
scc_lexer_stream_peek(scc_lexer_stream_t *stream, usize n) {
|
||||||
|
Assert(stream != null);
|
||||||
|
return stream->peek(stream, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scc_lexer_stream_consume(scc_lexer_stream_t *stream) {
|
||||||
|
Assert(stream != null);
|
||||||
|
return stream->advance(stream, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scc_lexer_stream_advance(scc_lexer_stream_t *stream,
|
||||||
|
usize n) {
|
||||||
|
Assert(stream != null);
|
||||||
|
return stream->advance(stream, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void scc_lexer_stream_drop(scc_lexer_stream_t *stream) {
|
||||||
|
Assert(stream != null);
|
||||||
|
return stream->drop(stream);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __SCC_LEXER_H__ */
|
#endif /* __SCC_LEXER_H__ */
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
#ifndef __SMCC_LEXER_LOG_H__
|
#ifndef __SCC_LEXER_LOG_H__
|
||||||
#define __SMCC_LEXER_LOG_H__
|
#define __SCC_LEXER_LOG_H__
|
||||||
|
|
||||||
#include <libcore.h>
|
#include <scc_core.h>
|
||||||
|
|
||||||
#ifndef LEX_LOG_LEVEL
|
#ifndef LEX_LOG_LEVEL
|
||||||
#define LEX_LOG_LEVEL 4
|
#define LEX_LOG_LEVEL 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LEX_LOG_LEVEL <= 1
|
#if LEX_LOG_LEVEL <= 1
|
||||||
#define LEX_NOTSET(fmt, ...) MLOG_NOTSET(&__smcc_lexer_log, fmt, ##__VA_ARGS__)
|
#define LEX_NOTSET(fmt, ...) MLOG_NOTSET(&__scc_lexer_log, fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define LEX_NOTSET(fmt, ...)
|
#define LEX_NOTSET(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LEX_LOG_LEVEL <= 2
|
#if LEX_LOG_LEVEL <= 2
|
||||||
#define LEX_DEBUG(fmt, ...) MLOG_DEBUG(&__smcc_lexer_log, fmt, ##__VA_ARGS__)
|
#define LEX_DEBUG(fmt, ...) MLOG_DEBUG(&__scc_lexer_log, fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define LEX_DEBUG(fmt, ...)
|
#define LEX_DEBUG(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LEX_LOG_LEVEL <= 3
|
#if LEX_LOG_LEVEL <= 3
|
||||||
#define LEX_INFO(fmt, ...) MLOG_INFO(&__smcc_lexer_log, fmt, ##__VA_ARGS__)
|
#define LEX_INFO(fmt, ...) MLOG_INFO(&__scc_lexer_log, fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define LEX_INFO(fmt, ...)
|
#define LEX_INFO(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LEX_LOG_LEVEL <= 4
|
#if LEX_LOG_LEVEL <= 4
|
||||||
#define LEX_WARN(fmt, ...) MLOG_WARN(&__smcc_lexer_log, fmt, ##__VA_ARGS__)
|
#define LEX_WARN(fmt, ...) MLOG_WARN(&__scc_lexer_log, fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define LEX_WARN(fmt, ...)
|
#define LEX_WARN(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LEX_LOG_LEVEL <= 5
|
#if LEX_LOG_LEVEL <= 5
|
||||||
#define LEX_ERROR(fmt, ...) MLOG_ERROR(&__smcc_lexer_log, fmt, ##__VA_ARGS__)
|
#define LEX_ERROR(fmt, ...) MLOG_ERROR(&__scc_lexer_log, fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define LEX_ERROR(fmt, ...)
|
#define LEX_ERROR(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LEX_LOG_LEVEL <= 6
|
#if LEX_LOG_LEVEL <= 6
|
||||||
#define LEX_FATAL(fmt, ...) MLOG_FATAL(&__smcc_lexer_log, fmt, ##__VA_ARGS__)
|
#define LEX_FATAL(fmt, ...) MLOG_FATAL(&__scc_lexer_log, fmt, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define LEX_FATAL(fmt, ...)
|
#define LEX_FATAL(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern logger_t __smcc_lexer_log;
|
extern logger_t __scc_lexer_log;
|
||||||
|
|
||||||
#endif // __SMCC_LEXER_LOG_H__
|
#endif /* __SCC_LEXER_LOG_H__ */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __SMCC_CC_TOKEN_H__
|
#ifndef __SCC_LEXER_TOKEN_H__
|
||||||
#define __SMCC_CC_TOKEN_H__
|
#define __SCC_LEXER_TOKEN_H__
|
||||||
|
|
||||||
#include <libcore.h>
|
#include <scc_core.h>
|
||||||
|
|
||||||
typedef enum scc_cstd {
|
typedef enum scc_cstd {
|
||||||
SCC_CSTD_C89,
|
SCC_CSTD_C89,
|
||||||
@@ -137,4 +137,24 @@ typedef enum scc_tok_subtype {
|
|||||||
scc_tok_subtype_t scc_get_tok_subtype(scc_tok_type_t type);
|
scc_tok_subtype_t scc_get_tok_subtype(scc_tok_type_t type);
|
||||||
const char *scc_get_tok_name(scc_tok_type_t type);
|
const char *scc_get_tok_name(scc_tok_type_t type);
|
||||||
|
|
||||||
#endif
|
typedef struct scc_lexer_token {
|
||||||
|
scc_tok_type_t type;
|
||||||
|
scc_cvalue_t value;
|
||||||
|
scc_pos_t loc;
|
||||||
|
} scc_lexer_tok_t;
|
||||||
|
|
||||||
|
static inline cbool scc_lexer_tok_match(const scc_lexer_tok_t *tok,
|
||||||
|
scc_tok_type_t type) {
|
||||||
|
return tok->type == type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline cbool scc_lexer_tok_expect(const scc_lexer_tok_t *tok,
|
||||||
|
scc_tok_type_t type) {
|
||||||
|
if (!scc_lexer_tok_match(tok, type)) {
|
||||||
|
LOG_ERROR("expected token %d, got %d\n", type, tok->type);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __SCC_LEXER_TOKEN_H__ */
|
||||||
|
|||||||
@@ -1,31 +1,3 @@
|
|||||||
/**
|
|
||||||
* 仿照LCCompiler的词法分析部分
|
|
||||||
*
|
|
||||||
* 如下为LCC的README in 2025.2
|
|
||||||
This hierarchy is the distribution for lcc version 4.2.
|
|
||||||
|
|
||||||
lcc version 3.x is described in the book "A Retargetable C Compiler:
|
|
||||||
Design and Implementation" (Addison-Wesley, 1995, ISBN 0-8053-1670-1).
|
|
||||||
There are significant differences between 3.x and 4.x, most notably in
|
|
||||||
the intermediate code. For details, see
|
|
||||||
https://drh.github.io/lcc/documents/interface4.pdf.
|
|
||||||
|
|
||||||
VERSION 4.2 IS INCOMPATIBLE WITH EARLIER VERSIONS OF LCC. DO NOT
|
|
||||||
UNLOAD THIS DISTRIBUTION ON TOP OF A 3.X DISTRIBUTION.
|
|
||||||
|
|
||||||
LCC is a C89 ("ANSI C") compiler designed to be highly retargetable.
|
|
||||||
|
|
||||||
LOG describes the changes since the last release.
|
|
||||||
|
|
||||||
CPYRIGHT describes the conditions under you can use, copy, modify, and
|
|
||||||
distribute lcc or works derived from lcc.
|
|
||||||
|
|
||||||
doc/install.html is an HTML file that gives a complete description of
|
|
||||||
the distribution and installation instructions.
|
|
||||||
|
|
||||||
Chris Fraser / cwf@aya.yale.edu
|
|
||||||
David Hanson / drh@drhanson.net
|
|
||||||
*/
|
|
||||||
#include <lex_parser.h>
|
#include <lex_parser.h>
|
||||||
#include <lexer.h>
|
#include <lexer.h>
|
||||||
#include <lexer_log.h>
|
#include <lexer_log.h>
|
||||||
@@ -329,33 +301,17 @@ void scc_lexer_get_token(scc_lexer_t *lexer, scc_lexer_tok_t *token) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '[':
|
/* clang-format off */
|
||||||
type = SCC_TOK_L_BRACKET;
|
case '[': type = SCC_TOK_L_BRACKET; break;
|
||||||
break;
|
case ']': type = SCC_TOK_R_BRACKET; break;
|
||||||
case ']':
|
case '(': type = SCC_TOK_L_PAREN; break;
|
||||||
type = SCC_TOK_R_BRACKET;
|
case ')': type = SCC_TOK_R_PAREN; break;
|
||||||
break;
|
case '{': type = SCC_TOK_L_BRACE; break;
|
||||||
case '(':
|
case '}': type = SCC_TOK_R_BRACE; break;
|
||||||
type = SCC_TOK_L_PAREN;
|
case ';': type = SCC_TOK_SEMICOLON; break;
|
||||||
break;
|
case ',': type = SCC_TOK_COMMA; break;
|
||||||
case ')':
|
case ':': type = SCC_TOK_COLON; break;
|
||||||
type = SCC_TOK_R_PAREN;
|
/* clang-format on */
|
||||||
break;
|
|
||||||
case '{':
|
|
||||||
type = SCC_TOK_L_BRACE;
|
|
||||||
break;
|
|
||||||
case '}':
|
|
||||||
type = SCC_TOK_R_BRACE;
|
|
||||||
break;
|
|
||||||
case ';':
|
|
||||||
type = SCC_TOK_SEMICOLON;
|
|
||||||
break;
|
|
||||||
case ',':
|
|
||||||
type = SCC_TOK_COMMA;
|
|
||||||
break;
|
|
||||||
case ':':
|
|
||||||
type = SCC_TOK_COLON;
|
|
||||||
break;
|
|
||||||
case '.':
|
case '.':
|
||||||
if (scc_probe_stream_next(stream) == '.' &&
|
if (scc_probe_stream_next(stream) == '.' &&
|
||||||
scc_probe_stream_next(stream) == '.') {
|
scc_probe_stream_next(stream) == '.') {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <lexer_log.h>
|
#include <lexer_log.h>
|
||||||
|
|
||||||
logger_t __smcc_lexer_log = {
|
logger_t __scc_lexer_log = {
|
||||||
.name = "lexer",
|
.name = "lexer",
|
||||||
.level = LOG_LEVEL_ALL,
|
.level = LOG_LEVEL_ALL,
|
||||||
.handler = log_default_handler,
|
.handler = log_default_handler,
|
||||||
|
|||||||
138
libs/lexer/src/lexer_stream.c
Normal file
138
libs/lexer/src/lexer_stream.c
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
#include <lexer.h>
|
||||||
|
|
||||||
|
static void lexer_stream_extend(scc_lexer_stream_t *stream, usize n) {
|
||||||
|
Assert(stream != null);
|
||||||
|
// 检查是否需要扩容
|
||||||
|
if ((stream->probe_pos - stream->curr_pos + n) >= stream->toks.cap) {
|
||||||
|
// 需要扩容 - 创建新缓冲区
|
||||||
|
usize new_cap = stream->toks.cap * 2;
|
||||||
|
if (new_cap < stream->probe_pos - stream->curr_pos + n + 1) {
|
||||||
|
new_cap = stream->probe_pos - stream->curr_pos + n + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
scc_lexer_tok_t *new_data =
|
||||||
|
scc_realloc(null, new_cap * sizeof(scc_lexer_tok_t));
|
||||||
|
if (!new_data) {
|
||||||
|
LOG_FATAL("lexer_stream_extend: realloc failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将旧缓冲区中的数据拷贝到新缓冲区,保持顺序
|
||||||
|
usize data_count = stream->probe_pos - stream->curr_pos;
|
||||||
|
for (usize i = 0; i < data_count; ++i) {
|
||||||
|
usize old_idx = (stream->curr_pos + i) % stream->toks.cap;
|
||||||
|
new_data[i] = stream->toks.data[old_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 释放旧缓冲区
|
||||||
|
if (stream->toks.data) {
|
||||||
|
scc_free(stream->toks.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新结构体
|
||||||
|
stream->toks.data = new_data;
|
||||||
|
stream->toks.cap = new_cap;
|
||||||
|
stream->curr_pos = 0;
|
||||||
|
stream->probe_pos = data_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 填充新token
|
||||||
|
for (usize i = 0; i < n; ++i) {
|
||||||
|
usize idx = (stream->probe_pos + i) % stream->toks.cap;
|
||||||
|
if (stream->need_comment)
|
||||||
|
scc_lexer_get_token(stream->lexer, &stream->toks.data[idx]);
|
||||||
|
else
|
||||||
|
scc_lexer_get_valid_token(stream->lexer, &stream->toks.data[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->probe_pos += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const scc_lexer_tok_t *lexer_stream_peek(scc_lexer_stream_t *stream,
|
||||||
|
usize n) {
|
||||||
|
Assert(stream != null);
|
||||||
|
|
||||||
|
// 计算需要的前看token数量
|
||||||
|
usize available = stream->probe_pos - stream->curr_pos;
|
||||||
|
if (n >= available) {
|
||||||
|
// 需要扩展缓冲区
|
||||||
|
usize need = n - available + 1;
|
||||||
|
lexer_stream_extend(stream, need);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算实际缓冲区中的位置
|
||||||
|
usize idx = (stream->curr_pos + n) % stream->toks.cap;
|
||||||
|
return &stream->toks.data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lexer_stream_advance(scc_lexer_stream_t *stream, usize offset) {
|
||||||
|
Assert(stream != null);
|
||||||
|
|
||||||
|
if (stream->curr_pos + offset > stream->probe_pos) {
|
||||||
|
// 尝试填充更多token
|
||||||
|
usize need = stream->curr_pos + offset - stream->probe_pos;
|
||||||
|
lexer_stream_extend(stream, need);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->curr_pos += offset;
|
||||||
|
|
||||||
|
// 可选:当已消费的token过多时,压缩缓冲区
|
||||||
|
if (stream->curr_pos > stream->toks.cap * 3 / 4) {
|
||||||
|
// 压缩缓冲区:将有效数据移动到前面
|
||||||
|
usize data_count = stream->probe_pos - stream->curr_pos;
|
||||||
|
scc_lexer_tok_t *temp =
|
||||||
|
scc_realloc(null, data_count * sizeof(scc_lexer_tok_t));
|
||||||
|
if (!temp)
|
||||||
|
return; // 压缩失败也没关系
|
||||||
|
|
||||||
|
for (usize i = 0; i < data_count; ++i) {
|
||||||
|
usize old_idx = (stream->curr_pos + i) % stream->toks.cap;
|
||||||
|
temp[i] = stream->toks.data[old_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
scc_free(stream->toks.data);
|
||||||
|
stream->toks.data = temp;
|
||||||
|
stream->toks.cap = data_count;
|
||||||
|
stream->curr_pos = 0;
|
||||||
|
stream->probe_pos = data_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lexer_stream_drop(scc_lexer_stream_t *stream) {
|
||||||
|
Assert(stream != null);
|
||||||
|
|
||||||
|
// 清理所有token(如果有需要清理的内部资源)
|
||||||
|
for (usize i = 0; i < stream->toks.cap; ++i) {
|
||||||
|
// 这里假设scc_lexer_tok_t可能包含需要释放的资源
|
||||||
|
// 如果有,需要调用相应的清理函数
|
||||||
|
// 例如: if (stream->toks.data[i].needs_free)
|
||||||
|
// scc_free(stream->toks.data[i].ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
scc_vec_free(stream->toks);
|
||||||
|
stream->lexer = null;
|
||||||
|
stream->curr_pos = 0;
|
||||||
|
stream->probe_pos = 0;
|
||||||
|
stream->need_comment = false;
|
||||||
|
|
||||||
|
stream->peek = null;
|
||||||
|
stream->advance = null;
|
||||||
|
stream->drop = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scc_lexer_to_stream(scc_lexer_t *lexer, scc_lexer_stream_t *stream,
|
||||||
|
cbool need_comment) {
|
||||||
|
Assert(lexer != null && stream != null);
|
||||||
|
|
||||||
|
stream->lexer = lexer;
|
||||||
|
stream->curr_pos = 0;
|
||||||
|
stream->probe_pos = 0;
|
||||||
|
stream->need_comment = need_comment;
|
||||||
|
|
||||||
|
// 初始化循环缓冲区
|
||||||
|
scc_vec_init(stream->toks);
|
||||||
|
scc_vec_realloc(stream->toks, 8); // 初始容量为8
|
||||||
|
|
||||||
|
stream->peek = lexer_stream_peek;
|
||||||
|
stream->advance = lexer_stream_advance;
|
||||||
|
stream->drop = lexer_stream_drop;
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@ int main(int argc, char *argv[]) {
|
|||||||
log_set_level(NULL, LOG_LEVEL_ALL);
|
log_set_level(NULL, LOG_LEVEL_ALL);
|
||||||
} else {
|
} else {
|
||||||
// FIXME it is a hack lexer_logger
|
// FIXME it is a hack lexer_logger
|
||||||
log_set_level(&__smcc_lexer_log, LOG_LEVEL_NOTSET);
|
log_set_level(&__scc_lexer_log, LOG_LEVEL_NOTSET);
|
||||||
log_set_level(NULL, LOG_LEVEL_INFO | LOG_LEVEL_WARN | LOG_LEVEL_ERROR |
|
log_set_level(NULL, LOG_LEVEL_INFO | LOG_LEVEL_WARN | LOG_LEVEL_ERROR |
|
||||||
LOG_LEVEL_FATAL);
|
LOG_LEVEL_FATAL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name = "scc_pprocesser"
|
name = "scc_pprocesser"
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "libcore", path = "../../runtime/libcore" },
|
{ name = "scc_core", path = "../../runtime/scc_core" },
|
||||||
{ name = "libutils", path = "../../runtime/libutils" },
|
{ name = "scc_utils", path = "../../runtime/scc_utils" },
|
||||||
{ name = "lex_parser", path = "../lex_parser" },
|
{ name = "lex_parser", path = "../lex_parser" },
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#ifndef __SCC_PP_MACRO_H__
|
#ifndef __SCC_PP_MACRO_H__
|
||||||
#define __SCC_PP_MACRO_H__
|
#define __SCC_PP_MACRO_H__
|
||||||
|
|
||||||
#include <libcore.h>
|
#include <scc_core.h>
|
||||||
#include <libutils.h>
|
#include <scc_utils.h>
|
||||||
|
|
||||||
// 宏定义类型
|
// 宏定义类型
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#ifndef __SCC_PP_PARSE_H__
|
#ifndef __SCC_PP_PARSE_H__
|
||||||
#define __SCC_PP_PARSE_H__
|
#define __SCC_PP_PARSE_H__
|
||||||
|
|
||||||
#include <libcore.h>
|
|
||||||
#include <pp_macro.h>
|
#include <pp_macro.h>
|
||||||
|
#include <scc_core.h>
|
||||||
void scc_pp_parse_directive(scc_probe_stream_t *stream, scc_pos_t *pos,
|
void scc_pp_parse_directive(scc_probe_stream_t *stream, scc_pos_t *pos,
|
||||||
scc_pp_macro_table_t *macros);
|
scc_pp_macro_table_t *macros);
|
||||||
cbool scc_pp_parse_macro_replace_list(scc_probe_stream_t *stream,
|
cbool scc_pp_parse_macro_replace_list(scc_probe_stream_t *stream,
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
#ifndef __SCC_PP_H__
|
#ifndef __SCC_PP_H__
|
||||||
#define __SCC_PP_H__
|
#define __SCC_PP_H__
|
||||||
|
|
||||||
#include <libcore.h>
|
|
||||||
#include <libutils.h>
|
|
||||||
#include <pp_macro.h>
|
#include <pp_macro.h>
|
||||||
|
#include <scc_core.h>
|
||||||
|
#include <scc_utils.h>
|
||||||
|
|
||||||
// 条件编译状态
|
// 条件编译状态
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -59,4 +59,4 @@ typedef struct pp_stream {
|
|||||||
scc_probe_stream_t *tmp_stream;
|
scc_probe_stream_t *tmp_stream;
|
||||||
} scc_pp_stream_t;
|
} scc_pp_stream_t;
|
||||||
|
|
||||||
#endif /* __SMC_PP_H__ */
|
#endif /* __SCC_PP_H__ */
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#include <lex_parser.h>
|
#include <lex_parser.h>
|
||||||
#include <libutils.h>
|
|
||||||
#include <pp_macro.h>
|
#include <pp_macro.h>
|
||||||
#include <pp_parse.h>
|
#include <pp_parse.h>
|
||||||
|
|
||||||
static inline void scc_generate_cstr(scc_cstring_t *buff) {
|
static inline void scc_generate_cstr(scc_cstring_t *buff) {
|
||||||
scc_cstring_t out_buff = scc_cstring_create();
|
scc_cstring_t out_buff = scc_cstring_create();
|
||||||
scc_cstring_append_ch(&out_buff, '\"');
|
scc_cstring_append_ch(&out_buff, '\"');
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#ifndef __SCC_CORE_H__
|
|
||||||
#define __SCC_CORE_H__
|
|
||||||
|
|
||||||
#include <core_log.h>
|
|
||||||
|
|
||||||
#include <core_impl.h>
|
|
||||||
#include <core_macro.h>
|
|
||||||
#include <core_mem.h>
|
|
||||||
#include <core_pos.h>
|
|
||||||
#include <core_str.h>
|
|
||||||
#include <core_stream.h>
|
|
||||||
#include <core_vec.h>
|
|
||||||
|
|
||||||
#endif // __SCC_CORE_H__
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "libutils"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
{ name = "core", path = "../libcore" }
|
|
||||||
]
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "libcore"
|
name = "scc_core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
default_features = ["std_impl"]
|
default_features = ["std_impl"]
|
||||||
14
runtime/scc_core/include/scc_core.h
Normal file
14
runtime/scc_core/include/scc_core.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __SCC_CORE_H__
|
||||||
|
#define __SCC_CORE_H__
|
||||||
|
|
||||||
|
#include <scc_core_log.h>
|
||||||
|
|
||||||
|
#include <scc_core_impl.h>
|
||||||
|
#include <scc_core_macro.h>
|
||||||
|
#include <scc_core_mem.h>
|
||||||
|
#include <scc_core_pos.h>
|
||||||
|
#include <scc_core_str.h>
|
||||||
|
#include <scc_core_stream.h>
|
||||||
|
#include <scc_core_vec.h>
|
||||||
|
|
||||||
|
#endif // __SCC_CORE_H__
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __SCC_CORE_IMPL_H__
|
#ifndef __SCC_CORE_IMPL_H__
|
||||||
#define __SCC_CORE_IMPL_H__
|
#define __SCC_CORE_IMPL_H__
|
||||||
|
|
||||||
#include "core_type.h"
|
#include "scc_core_type.h"
|
||||||
|
|
||||||
/* ====== 内存管理核心接口 ====== */
|
/* ====== 内存管理核心接口 ====== */
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __SCC_CORE_MEM_H__
|
#ifndef __SCC_CORE_MEM_H__
|
||||||
#define __SCC_CORE_MEM_H__
|
#define __SCC_CORE_MEM_H__
|
||||||
|
|
||||||
#include "core_type.h"
|
#include "scc_core_type.h"
|
||||||
|
|
||||||
void *scc_memcpy(void *dest, const void *src, usize n);
|
void *scc_memcpy(void *dest, const void *src, usize n);
|
||||||
void *scc_memmove(void *dest, const void *src, usize n);
|
void *scc_memmove(void *dest, const void *src, usize n);
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#ifndef __SCC_CORE_POS_H__
|
#ifndef __SCC_CORE_POS_H__
|
||||||
#define __SCC_CORE_POS_H__
|
#define __SCC_CORE_POS_H__
|
||||||
|
|
||||||
#include "core_str.h"
|
#include "scc_core_str.h"
|
||||||
#include "core_type.h"
|
#include "scc_core_type.h"
|
||||||
typedef struct scc_pos {
|
typedef struct scc_pos {
|
||||||
scc_cstring_t name;
|
scc_cstring_t name;
|
||||||
usize line;
|
usize line;
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
#ifndef __SCC_CORE_STR_H__
|
#ifndef __SCC_CORE_STR_H__
|
||||||
#define __SCC_CORE_STR_H__
|
#define __SCC_CORE_STR_H__
|
||||||
|
|
||||||
#include "core_impl.h"
|
#include "scc_core_impl.h"
|
||||||
#include "core_log.h"
|
#include "scc_core_log.h"
|
||||||
#include "core_type.h"
|
#include "scc_core_mem.h"
|
||||||
|
#include "scc_core_type.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 动态字符串结构体
|
* @brief 动态字符串结构体
|
||||||
@@ -68,7 +69,7 @@ static inline void scc_cstring_free(scc_cstring_t *str) {
|
|||||||
if (str == null) {
|
if (str == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (str->cap != 0 && str->data != null) {
|
if (str->data != null) {
|
||||||
scc_free(str->data);
|
scc_free(str->data);
|
||||||
str->data = null;
|
str->data = null;
|
||||||
}
|
}
|
||||||
@@ -188,14 +189,14 @@ static inline void scc_cstring_clear(scc_cstring_t *str) {
|
|||||||
*/
|
*/
|
||||||
static inline char *scc_cstring_as_cstr(const scc_cstring_t *str) {
|
static inline char *scc_cstring_as_cstr(const scc_cstring_t *str) {
|
||||||
if (str == null || str->data == null) {
|
if (str == null || str->data == null) {
|
||||||
return "";
|
return null;
|
||||||
}
|
}
|
||||||
return str->data;
|
return str->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char *scc_cstring_move_cstr(scc_cstring_t *str) {
|
static inline char *scc_cstring_move_cstr(scc_cstring_t *str) {
|
||||||
if (str == null || str->data == null) {
|
if (str == null || str->data == null) {
|
||||||
return "";
|
return null;
|
||||||
}
|
}
|
||||||
char *ret = str->data;
|
char *ret = str->data;
|
||||||
str->data = null;
|
str->data = null;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#ifndef __SMCC_CORE_PROBE_STREAM_H__
|
#ifndef __SMCC_CORE_PROBE_STREAM_H__
|
||||||
#define __SMCC_CORE_PROBE_STREAM_H__
|
#define __SMCC_CORE_PROBE_STREAM_H__
|
||||||
|
|
||||||
#include "core_impl.h"
|
#include "scc_core_impl.h"
|
||||||
#include "core_macro.h"
|
#include "scc_core_macro.h"
|
||||||
#include "core_mem.h"
|
#include "scc_core_mem.h"
|
||||||
#include "core_str.h"
|
#include "scc_core_str.h"
|
||||||
|
|
||||||
struct scc_probe_stream;
|
struct scc_probe_stream;
|
||||||
typedef struct scc_probe_stream scc_probe_stream_t;
|
typedef struct scc_probe_stream scc_probe_stream_t;
|
||||||
@@ -8,11 +8,34 @@
|
|||||||
#ifndef __SCC_CORE_VEC_H__
|
#ifndef __SCC_CORE_VEC_H__
|
||||||
#define __SCC_CORE_VEC_H__
|
#define __SCC_CORE_VEC_H__
|
||||||
|
|
||||||
#include "core_impl.h"
|
#ifndef __SCC_CORE_VEC_USE_STD__
|
||||||
#include "core_type.h"
|
#include "scc_core_impl.h"
|
||||||
|
#include "scc_core_type.h"
|
||||||
|
|
||||||
#define __scc_vec_realloc scc_realloc
|
#define __scc_vec_realloc scc_realloc
|
||||||
#define __scc_vec_free scc_free
|
#define __scc_vec_free scc_free
|
||||||
|
#else
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef size_t usize;
|
||||||
|
#define __scc_vec_realloc realloc
|
||||||
|
#define __scc_vec_free free
|
||||||
|
|
||||||
|
#ifndef LOG_FATAL
|
||||||
|
#include <stdio.h>
|
||||||
|
#define LOG_FATAL(...) \
|
||||||
|
do { \
|
||||||
|
printf(__VA_ARGS__); \
|
||||||
|
exit(1); \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Assert
|
||||||
|
#include <assert.h>
|
||||||
|
#define Assert(cond) assert(cond)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/** @defgroup vec_struct 数据结构定义 */
|
/** @defgroup vec_struct 数据结构定义 */
|
||||||
|
|
||||||
@@ -51,6 +74,22 @@
|
|||||||
(vec).size = 0, (vec).cap = 0, (vec).data = 0; \
|
(vec).size = 0, (vec).cap = 0, (vec).data = 0; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define scc_vec_realloc(vec, new_cap) \
|
||||||
|
do { \
|
||||||
|
void *data = \
|
||||||
|
__scc_vec_realloc((vec).data, new_cap * sizeof(*(vec).data)); \
|
||||||
|
if (!data) { \
|
||||||
|
LOG_FATAL("vector_push: realloc failed\n"); \
|
||||||
|
} \
|
||||||
|
(vec).cap = new_cap; \
|
||||||
|
(vec).data = data; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define scc_vec_size(vec) ((vec).size)
|
||||||
|
#define scc_vec_cap(vec) ((vec).cap)
|
||||||
|
#define scc_vec_foreach(vec, idx) \
|
||||||
|
for (usize idx = 0; idx < scc_vec_size(vec); ++idx)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def scc_vec_push(vec, value)
|
* @def scc_vec_push(vec, value)
|
||||||
* @brief 添加元素到向量末尾
|
* @brief 添加元素到向量末尾
|
||||||
@@ -64,13 +103,7 @@
|
|||||||
do { \
|
do { \
|
||||||
if ((vec).size >= (vec).cap) { \
|
if ((vec).size >= (vec).cap) { \
|
||||||
int cap = (vec).cap ? (vec).cap * 2 : 4; \
|
int cap = (vec).cap ? (vec).cap * 2 : 4; \
|
||||||
void *data = \
|
scc_vec_realloc(vec, cap); \
|
||||||
__scc_vec_realloc((vec).data, cap * sizeof(*(vec).data)); \
|
|
||||||
if (!data) { \
|
|
||||||
LOG_FATAL("vector_push: realloc failed\n"); \
|
|
||||||
} \
|
|
||||||
(vec).cap = cap; \
|
|
||||||
(vec).data = data; \
|
|
||||||
} \
|
} \
|
||||||
Assert((vec).data != null); \
|
Assert((vec).data != null); \
|
||||||
(vec).data[(vec).size++] = value; \
|
(vec).data[(vec).size++] = value; \
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <core_impl.h>
|
#include <scc_core_impl.h>
|
||||||
#define __SCC_LOG_IMPORT_SRC__
|
#define __SCC_LOG_IMPORT_SRC__
|
||||||
#define log_snprintf scc_snprintf
|
#define log_snprintf scc_snprintf
|
||||||
#define log_printf scc_printf
|
#define log_printf scc_printf
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <core_mem.h>
|
#include <scc_core_mem.h>
|
||||||
|
|
||||||
// 判断是否支持非对齐访问(x86/x64 支持)
|
// 判断是否支持非对齐访问(x86/x64 支持)
|
||||||
#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || \
|
#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || \
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <core_log.h>
|
#include <scc_core_log.h>
|
||||||
#include <core_stream.h>
|
#include <scc_core_stream.h>
|
||||||
|
|
||||||
#ifndef __SCC_CORE_NO_MEM_PROBE_STREAM__
|
#ifndef __SCC_CORE_NO_MEM_PROBE_STREAM__
|
||||||
|
|
||||||
5
runtime/scc_utils/cbuild.toml
Normal file
5
runtime/scc_utils/cbuild.toml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[package]
|
||||||
|
name = "scc_utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
dependencies = [{ name = "core", path = "../scc_core" }]
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
#ifndef __SCC_HASHTABLE_H__
|
#ifndef __SCC_HASHTABLE_H__
|
||||||
#define __SCC_HASHTABLE_H__
|
#define __SCC_HASHTABLE_H__
|
||||||
|
|
||||||
#include <libcore.h>
|
#include <scc_core.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum hp_entry_state_t
|
* @enum hp_entry_state_t
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
#ifndef __SCC_STRPOOL_H__
|
#ifndef __SCC_STRPOOL_H__
|
||||||
#define __SCC_STRPOOL_H__
|
#define __SCC_STRPOOL_H__
|
||||||
|
|
||||||
#include "hashtable.h"
|
#include "scc_hashtable.h"
|
||||||
#include <libcore.h>
|
#include <scc_core.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct strpool_t
|
* @struct strpool_t
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#ifndef __SMCC_UTILS_H__
|
#ifndef __SMCC_UTILS_H__
|
||||||
#define __SMCC_UTILS_H__
|
#define __SMCC_UTILS_H__
|
||||||
|
|
||||||
#include "hashtable.h"
|
|
||||||
#include "kllist.h"
|
#include "kllist.h"
|
||||||
#include "strpool.h"
|
#include "scc_hashtable.h"
|
||||||
#include <libcore.h>
|
#include "scc_strpool.h"
|
||||||
|
#include <scc_core.h>
|
||||||
|
|
||||||
#endif /* __SMCC_UTILS_H__ */
|
#endif /* __SMCC_UTILS_H__ */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <hashtable.h>
|
#include <scc_hashtable.h>
|
||||||
|
|
||||||
#ifndef SCC_INIT_HASHMAP_SIZE
|
#ifndef SCC_INIT_HASHMAP_SIZE
|
||||||
#define SCC_INIT_HASHMAP_SIZE (32)
|
#define SCC_INIT_HASHMAP_SIZE (32)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "strpool.h"
|
#include <scc_strpool.h>
|
||||||
|
|
||||||
void scc_strpool_init(scc_strpool_t *pool) {
|
void scc_strpool_init(scc_strpool_t *pool) {
|
||||||
pool->ht.hash_func = (u32 (*)(const void *))scc_strhash32;
|
pool->ht.hash_func = (u32 (*)(const void *))scc_strhash32;
|
||||||
Reference in New Issue
Block a user