feat(lexer): 添加词法分析器对##操作符的支持
- 重命名lexer_token.h为scc_lexer_token.h以保持命名一致性 - 在词法分析器中实现##操作符的识别和处理 - 修改头文件包含路径和类型定义的位置 - 修复token结构体定义的顺序问题 fix(lexer): 初始化lexer中的cur变量避免未初始化问题 - 在scc_lexer_get_token函数中初始化scc_sstream_char_t cur变量 refactor(core): 增强ring缓冲区功能并添加cstring比较函数 - 在scc_core_ring.h中添加空值检查防止fill函数为空时崩溃 - 添加scc_ring_by_buffer宏用于通过缓冲区创建ring实例 - 在scc_core_str.h中添加scc_cstring_cmp函数用于字符串比较
This commit is contained in:
@@ -6,13 +6,11 @@
|
|||||||
#ifndef __SCC_LEXER_H__
|
#ifndef __SCC_LEXER_H__
|
||||||
#define __SCC_LEXER_H__
|
#define __SCC_LEXER_H__
|
||||||
|
|
||||||
#include "lexer_token.h"
|
#include "scc_lexer_token.h"
|
||||||
#include <scc_core.h>
|
#include <scc_core.h>
|
||||||
#include <scc_core_ring.h>
|
#include <scc_core_ring.h>
|
||||||
#include <scc_sstream.h>
|
#include <scc_sstream.h>
|
||||||
|
|
||||||
typedef SCC_RING(scc_lexer_tok_t) scc_lexer_tok_ring_t;
|
|
||||||
typedef SCC_VEC(scc_lexer_tok_t) scc_lexer_tok_vec_t;
|
|
||||||
/**
|
/**
|
||||||
* @brief 词法分析器核心结构体
|
* @brief 词法分析器核心结构体
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -4,6 +4,12 @@
|
|||||||
#include <scc_core.h>
|
#include <scc_core.h>
|
||||||
#include <scc_pos.h>
|
#include <scc_pos.h>
|
||||||
|
|
||||||
|
#include <scc_core_ring.h>
|
||||||
|
struct scc_lexer_token;
|
||||||
|
typedef struct scc_lexer_token scc_lexer_tok_t;
|
||||||
|
typedef SCC_RING(scc_lexer_tok_t) scc_lexer_tok_ring_t;
|
||||||
|
typedef SCC_VEC(scc_lexer_tok_t) scc_lexer_tok_vec_t;
|
||||||
|
|
||||||
typedef enum scc_cstd {
|
typedef enum scc_cstd {
|
||||||
SCC_CSTD_C89,
|
SCC_CSTD_C89,
|
||||||
SCC_CSTD_C99,
|
SCC_CSTD_C99,
|
||||||
@@ -82,6 +88,7 @@ typedef enum scc_cstd {
|
|||||||
X(blank , SCC_TOK_SUBTYPE_EMPTYSPACE, SCC_TOK_BLANK ) \
|
X(blank , SCC_TOK_SUBTYPE_EMPTYSPACE, SCC_TOK_BLANK ) \
|
||||||
X(endline , SCC_TOK_SUBTYPE_EMPTYSPACE, SCC_TOK_ENDLINE ) \
|
X(endline , SCC_TOK_SUBTYPE_EMPTYSPACE, SCC_TOK_ENDLINE ) \
|
||||||
X("#" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_SHARP ) \
|
X("#" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_SHARP ) \
|
||||||
|
X("##" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_SHARP_SHARP ) \
|
||||||
X("==" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_EQ ) \
|
X("==" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_EQ ) \
|
||||||
X("=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN ) \
|
X("=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN ) \
|
||||||
X("++" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ADD_ADD ) \
|
X("++" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ADD_ADD ) \
|
||||||
@@ -166,18 +173,18 @@ typedef enum scc_tok_subtype {
|
|||||||
SCC_TOK_SUBTYPE_EOF // 结束标记
|
SCC_TOK_SUBTYPE_EOF // 结束标记
|
||||||
} scc_tok_subtype_t;
|
} scc_tok_subtype_t;
|
||||||
|
|
||||||
scc_tok_subtype_t scc_get_tok_subtype(scc_tok_type_t type);
|
|
||||||
const char *scc_get_tok_name(scc_tok_type_t type);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 词法分析结果
|
* @brief 词法分析结果
|
||||||
* @warning 需要手动释放lexeme否则会出现内存泄漏
|
* @warning 需要手动释放lexeme否则会出现内存泄漏
|
||||||
*/
|
*/
|
||||||
typedef struct scc_lexer_token {
|
struct scc_lexer_token {
|
||||||
scc_tok_type_t type;
|
scc_tok_type_t type;
|
||||||
scc_cstring_t lexeme;
|
scc_cstring_t lexeme;
|
||||||
scc_pos_t loc;
|
scc_pos_t loc;
|
||||||
} scc_lexer_tok_t;
|
};
|
||||||
|
|
||||||
|
scc_tok_subtype_t scc_get_tok_subtype(scc_tok_type_t type);
|
||||||
|
const char *scc_get_tok_name(scc_tok_type_t type);
|
||||||
|
|
||||||
static inline void scc_lexer_tok_drop(scc_lexer_tok_t *tok) {
|
static inline void scc_lexer_tok_drop(scc_lexer_tok_t *tok) {
|
||||||
scc_cstring_free(&tok->lexeme);
|
scc_cstring_free(&tok->lexeme);
|
||||||
@@ -88,7 +88,7 @@ static inline cbool next_char(scc_lexer_t *lexer, scc_cstring_t *lexeme,
|
|||||||
#define set_err_token(token) ((token)->type = SCC_TOK_UNKNOWN)
|
#define set_err_token(token) ((token)->type = SCC_TOK_UNKNOWN)
|
||||||
|
|
||||||
void scc_lexer_get_token(scc_lexer_t *lexer, scc_lexer_tok_t *token) {
|
void scc_lexer_get_token(scc_lexer_t *lexer, scc_lexer_tok_t *token) {
|
||||||
scc_sstream_char_t cur;
|
scc_sstream_char_t cur = {0};
|
||||||
scc_cstring_t lex = scc_cstring_create(); // 临时lexeme
|
scc_cstring_t lex = scc_cstring_create(); // 临时lexeme
|
||||||
|
|
||||||
// 尝试预览第一个字符
|
// 尝试预览第一个字符
|
||||||
@@ -439,6 +439,10 @@ void scc_lexer_get_token(scc_lexer_t *lexer, scc_lexer_tok_t *token) {
|
|||||||
token->type = SCC_TOK_COND;
|
token->type = SCC_TOK_COND;
|
||||||
break;
|
break;
|
||||||
case '#':
|
case '#':
|
||||||
|
if (next.character == '#') {
|
||||||
|
token->type = SCC_TOK_SHARP_SHARP;
|
||||||
|
next_char(lexer, &lex, &cur);
|
||||||
|
} else
|
||||||
token->type = SCC_TOK_SHARP;
|
token->type = SCC_TOK_SHARP;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <lexer_token.h>
|
#include <scc_lexer_token.h>
|
||||||
|
|
||||||
// 生成字符串映射(根据需求选择#str或#name)
|
// 生成字符串映射(根据需求选择#str或#name)
|
||||||
static const char *token_strings[] = {
|
static const char *token_strings[] = {
|
||||||
|
|||||||
@@ -51,7 +51,8 @@
|
|||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
usize phys_tail = scc_ring_phys(ring, (ring).tail); \
|
usize phys_tail = scc_ring_phys(ring, (ring).tail); \
|
||||||
if (!(ring).fill(&(ring).data[phys_tail], (ring).userdata)) { \
|
if ((ring).fill == null || \
|
||||||
|
!(ring).fill(&(ring).data[phys_tail], (ring).userdata)) { \
|
||||||
ok = 0; \
|
ok = 0; \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
@@ -79,6 +80,17 @@
|
|||||||
(ring).userdata = (_userdata); \
|
(ring).userdata = (_userdata); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define scc_ring_by_buffer(ring, buffer, size) \
|
||||||
|
do { \
|
||||||
|
(ring).data = (buffer); \
|
||||||
|
(ring).cap = (size); \
|
||||||
|
(ring).head = 0; \
|
||||||
|
(ring).probe = 0; \
|
||||||
|
(ring).tail = (size); \
|
||||||
|
(ring).fill = null; \
|
||||||
|
(ring).userdata = null; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 释放环形缓冲区内存
|
* @brief 释放环形缓冲区内存
|
||||||
* @param ring 环形缓冲区变量
|
* @param ring 环形缓冲区变量
|
||||||
|
|||||||
@@ -194,6 +194,11 @@ static inline char *scc_cstring_as_cstr(const scc_cstring_t *str) {
|
|||||||
return str->data;
|
return str->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int scc_cstring_cmp(const scc_cstring_t *str1,
|
||||||
|
const scc_cstring_t *str2) {
|
||||||
|
return scc_strcmp(scc_cstring_as_cstr(str1), scc_cstring_as_cstr(str2));
|
||||||
|
}
|
||||||
|
|
||||||
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 null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user