写了解析函数定义的部分 大致有了一个生成抽象语法树的思路
This commit is contained in:
@@ -4,5 +4,6 @@
|
||||
初步实现 基于线程的异常捕获,触发异常时可以自动释放异常捕获期间的动态内存
|
||||
|
||||
|
||||
|
||||
2024.11.1
|
||||
c语言语法分析的用处 扩展当前c语言语法 根据有扩展语法的源c文件生成目标c文件
|
||||
|
||||
|
153
soft/clexical.c
153
soft/clexical.c
@@ -438,6 +438,7 @@ typedef enum {
|
||||
typedef struct _describe_var {
|
||||
int attribute;// 属性 静态 只读 无符号 等
|
||||
int type;// 类型
|
||||
char der_name[TOKEN_BUFF_MAX_LEN];// 派生类型的名称 结构体 联合体等
|
||||
void* value;// 变量的值
|
||||
}describe_var_def;
|
||||
|
||||
@@ -475,80 +476,83 @@ typedef struct _par_def
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 定义区分语句类型的token type list
|
||||
const int* g_token_type_list[ ] = {
|
||||
{2,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{2,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
{2,VTYPE_VOID,TOKEN_NAME},// 函数定义
|
||||
|
||||
{3,ATYPE_CONST,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{3,ATYPE_CONST,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
{3,ATYPE_CONST,VTYPE_VOID,TOKEN_NAME},// 函数定义
|
||||
|
||||
{4,ATYPE_STATIC,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{4,ATYPE_STATIC,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
{4,ATYPE_STATIC,VTYPE_VOID,TOKEN_NAME},// 函数定义
|
||||
|
||||
{4,ATYPE_STATIC,ATYPE_CONST,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{4,ATYPE_STATIC,ATYPE_CONST,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
{4,ATYPE_STATIC,ATYPE_CONST,VTYPE_VOID,TOKEN_NAME},// 函数定义
|
||||
|
||||
{4,ATYPE_CONST,ATYPE_STATIC,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{4,ATYPE_CONST,ATYPE_STATIC,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
{4,ATYPE_CONST,ATYPE_STATIC,VTYPE_VOID,TOKEN_NAME},// 函数定义
|
||||
|
||||
{3,ATYPE_UNSIGNED,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{3,ATYPE_UNSIGNED,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
|
||||
{4,ATYPE_CONST,ATYPE_UNSIGNED,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{4,ATYPE_CONST,ATYPE_UNSIGNED,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
|
||||
{4,ATYPE_STATIC,ATYPE_UNSIGNED,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{4,ATYPE_STATIC,ATYPE_UNSIGNED,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
|
||||
{5,ATYPE_STATIC,ATYPE_CONST,ATYPE_UNSIGNED,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{5,ATYPE_STATIC,ATYPE_CONST,ATYPE_UNSIGNED,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
|
||||
{5,ATYPE_CONST,ATYPE_STATIC,ATYPE_UNSIGNED,VTYPE_CHAR,TOKEN_NAME},// 函数定义
|
||||
{5,ATYPE_CONST,ATYPE_STATIC,ATYPE_UNSIGNED,VTYPE_INT,TOKEN_NAME},// 函数定义
|
||||
{0}
|
||||
};
|
||||
|
||||
static int _par_compare_token_type(int* t, token_def* token_list , int len) {
|
||||
for (int j = 0;j < len;j++) {
|
||||
if (t [j] != token_list [j].token) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 对token列表进行合法性审查 如果返回不小于0 则可能是变量声明 函数声明 函数定义
|
||||
int par_legality_review(token_def* token_list , int len) {
|
||||
const int* t[ ] = g_token_type_list;
|
||||
int ret = -1;
|
||||
for (int i = 0;t [i][0];i++) {
|
||||
// 对比token类型
|
||||
if (len >= t [i][0]) {
|
||||
ret = _par_compare_token_type(&t [i][1] , token_list , t [i][0]);
|
||||
if (ret) {
|
||||
return i;
|
||||
}
|
||||
// 找到成对闭合的符号 返回 token 长度
|
||||
int par_find_closed(token_def* t_list , int len , int token_s , int token_e) {
|
||||
if (len < 1) {
|
||||
return 0;
|
||||
}
|
||||
if (t_list [0].token != token_s) {
|
||||
throw_("token_list 不以 \"%c\" 开头,在 %d 行,%d 位置" , token_s , t_list [0].line , t_list [0].pos);
|
||||
}
|
||||
int token_close = 0;
|
||||
for (int i = 0;i < len;i++) {
|
||||
if (t_list [i].token == token_s) {
|
||||
token_close++;
|
||||
} else if (t_list [i].token == token_e) {
|
||||
token_close--;
|
||||
}
|
||||
if (token_close == 0) {
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
throw_("缺少成对的符号,第一个符号 \"%c\" 在 %d 行,%d 位置" , token_s , t_list [0].line , t_list [0].pos);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 解析形参列表
|
||||
int par_var_def( ) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 解析一个变量声明 函数声明 或函数定义
|
||||
// 这个函数在 TOKEN_NAME 的时候调用 保证第一个token_def 为 TOKEN_NAME
|
||||
// 返回 消耗的token 数
|
||||
int par_var_fun_def(par_def* par , token_def* t_list , int len) {
|
||||
token_def* t_start = t_list;
|
||||
if (len < 2) {
|
||||
throw_("缺少后续token,在 %d 行,%d 位置" , t_list [0].line , t_list [0].pos);
|
||||
}
|
||||
if (t_list [1].token == ';') {
|
||||
// 变量声明
|
||||
par->type = STYPE_VDECLARE;
|
||||
par->token_list_len = 0;
|
||||
if (par->token_list) {
|
||||
throw_("出现意外的token_list,在 %d 行,%d 位置" , t_list [0].line , t_list [0].pos);
|
||||
}
|
||||
} else if (t_list [1].token == '(') {
|
||||
// 可能是函数调用或者函数定义 函数声明
|
||||
t_list++;len--;
|
||||
int close_len = 0;
|
||||
close_len = par_find_closed(t_list , len , '(' , ')');
|
||||
if (close_len >= len ) {
|
||||
throw_("缺少后续token,在 %d 行,%d 位置" , t_list [close_len-1 ].line , t_list [close_len-1 ].pos);
|
||||
}
|
||||
if (t_list [close_len + 1].token == '{') {
|
||||
// 是函数定义
|
||||
par->type = STYPE_FDEF;
|
||||
} else if (t_list [close_len + 1].token == ';') {
|
||||
// 函数声明
|
||||
par->type = STYPE_FDECLARE;
|
||||
} else {
|
||||
throw_("意外的token,在 %d 行,%d 位置" , t_list [close_len + 1].line , t_list [close_len + 1].pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 解析一个范围内的token list
|
||||
int par_statement(par_def* p) {
|
||||
token_def* t = p->token_list;
|
||||
par_def* par = mem_calloc(1 , sizeof(par_def));
|
||||
p->child = par;
|
||||
p->child_num++;
|
||||
int type = -1;
|
||||
for (int i = 0;i < p->token_list_len;i++) {
|
||||
int ttype = t [i].token;
|
||||
@@ -571,19 +575,20 @@ int par_statement(par_def* p) {
|
||||
case TOKEN_UNSIGNED:
|
||||
par->attribute |= ATYPE_UNSIGNED;
|
||||
break;
|
||||
case TOKEN_NAME:
|
||||
case TOKEN_NAME: {
|
||||
memcpy(par->name , t [i].buff , t [i].used);
|
||||
if (par_legality_review(t , p->token_list_len) >= 0) {
|
||||
if (i + 1 >= p->token_list_len) {
|
||||
throw_("缺少后续标识符 line=%d,pos=%d" , t [i].line , t [i].pos);
|
||||
}
|
||||
if (t [i + 1].token == ';') {
|
||||
// 变量声明
|
||||
par->type = STYPE_VDECLARE;
|
||||
}
|
||||
|
||||
if (type >= 0) {
|
||||
// 有类型 应该是变量声明 函数声明 或函数定义
|
||||
i+=par_var_fun_def(par,&t[i],p->token_list_len-i);
|
||||
} else {
|
||||
// 是函数调用 指针调用 变量赋值
|
||||
}
|
||||
// 到这里一个语句解析完了 开始解析下一个语句
|
||||
par->next = mem_calloc(1 , sizeof(par_def));
|
||||
par = par->next;
|
||||
p->child_num++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -601,7 +606,7 @@ int par_parser(token_def* token_list , int len) {
|
||||
par->attribute = 0;
|
||||
par->token_list = token_list;
|
||||
par->token_list_len = len;
|
||||
|
||||
par_statement(par);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user