From c9874d1eaaf3bf327f7428336b75d61c809f433b Mon Sep 17 00:00:00 2001 From: ranchuan Date: Fri, 1 Nov 2024 14:33:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=99=E4=BA=86=E8=A7=A3=E6=9E=90=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=AE=9A=E4=B9=89=E7=9A=84=E9=83=A8=E5=88=86=20?= =?UTF-8?q?=E5=A4=A7=E8=87=B4=E6=9C=89=E4=BA=86=E4=B8=80=E4=B8=AA=E7=94=9F?= =?UTF-8?q?=E6=88=90=E6=8A=BD=E8=B1=A1=E8=AF=AD=E6=B3=95=E6=A0=91=E7=9A=84?= =?UTF-8?q?=E6=80=9D=E8=B7=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ReadMe.txt | 3 +- soft/clexical.c | 153 +++++++++++++++++++++++++----------------------- 2 files changed, 81 insertions(+), 75 deletions(-) diff --git a/ReadMe.txt b/ReadMe.txt index 2417e74..2c27b6a 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -4,5 +4,6 @@ 初步实现 基于线程的异常捕获,触发异常时可以自动释放异常捕获期间的动态内存 - +2024.11.1 + c语言语法分析的用处 扩展当前c语言语法 根据有扩展语法的源c文件生成目标c文件 diff --git a/soft/clexical.c b/soft/clexical.c index 31ab7ca..8713329 100644 --- a/soft/clexical.c +++ b/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); }