基于lex/yacc,识别出 .h文件中、所有的合法的函数定义

本文介绍如何利用lex和yacc工具来识别并解析头文件(.h)中的所有有效函数定义。提供了包含词法分析(lex.l)、语法分析(yacc.y)以及主程序(main.c/main.h)的源代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于lex/yacc,识别出 .h文件中、所有的合法的函数定义
包括三个源代码:

  1. lex.l: 词法定义
  2. yacc.y: 语法定义
  3. main.c/main.h: main处理程序

lex.l

D		[0-9]
L		[_a-zA-Z]
A       [_a-zA-Z0-9]
WS		[ \t\v\f]
%option noyywrap yylineno
%{
#include <string.h>
#include <stdlib.h>
#include "main.h"
#include "yacc.tab.h"

char s_lex_str[256];

#define RETURN_STR(y)					return_str(yytext); return y		
void return_str(char *str) ;
%}
%x C_COMMENT MACRO_DEFINE
%%
"/*"									{BEGIN(C_COMMENT);lex_log("/*");}
<C_COMMENT>.|\n							{lex_log(".");}
<C_COMMENT>"*/"							{BEGIN(INITIAL);lex_log("*/");}
"#define"								{BEGIN(MACRO_DEFINE);lex_log("#DEFINE_start");}
<MACRO_DEFINE>\\\n 						{lex_log(".");}
<MACRO_DEFINE>.							{lex_log(".");}
<MACRO_DEFINE>\n						{BEGIN(INITIAL);lex_log("#DEFINE_end\n");}
"//".*									{lex_log("//");}  /* consume //-comment*/
"#include".*							{lex_log("#INCLUDE");}
"typedef".*								{lex_log("TYPEDEF");}
"SFS_IN"								{lex_log(yytext);}
"SFS_OUT"								{lex_log(yytext);}
"SFS_INOUT"								{lex_log(yytext);}
"INPUT"									{lex_log(yytext);}
"OUTPUT"								{lex_log(yytext);}
"INOUT"									{lex_log(yytext);}


"#if".*									{lex_log(yytext);
										RETURN_STR(T_MACRO);
										}
"#elif".*								{lex_log("ELIF");
										RETURN_STR(T_MACRO);
										}
"#else"									{lex_log("ELSE");
										RETURN_STR(T_MACRO);
										}
"#endif"								{lex_log("ENDIF");
										RETURN_STR(T_MACRO);
										}
"PUBLIC"|"public"|"EXTERN"|"extern"		{lex_log("TPUBLIC");
										RETURN_STR(TPUBLIC);
										}
"BOOLEAN"|"boolean"|"bool"|"BOOL"		{lex_log("BOOL"); 
										RETURN_STR(TBOOL);
										}
"int"|"uint"							{lex_log("INT"); 
										RETURN_STR(TINT);
										}
"int8"|"uint8"							{lex_log("INT8"); 
										RETURN_STR(TINT8);
										}
"int16"|"uint16"						{lex_log("INT16");
										RETURN_STR(TINT16);
										}
"int32"|"uint32"						{lex_log("INT32");
										RETURN_STR(TINT32);
										}
"void"|"VOID"							{lex_log("VOID"); 
										RETURN_STR(TVOID);
										}
"const"|"CONST"									{
										lex_log("CONST");
										RETURN_STR(TCONST);										
										}
"..."									{
										lex_log("ELLIPSIS");
										RETURN_STR(TELLIPSIS);										
										}										
{L}{A}*									{
										sprintf(s_lex_str, "TID_%s", yytext);	lex_log(s_lex_str); 
										RETURN_STR(TID);										
										}
[1-9][0-9]*								{
										sprintf(s_lex_str, "TNUM_%s", yytext);	lex_log(s_lex_str); 
										RETURN_STR(TNUM);
										}
[-\[\]()<>=+*;{}.,]							{
										sprintf(s_lex_str, "%c", yytext[0]); lex_log(s_lex_str); 
										return yytext[0];
										}
\n										{lex_log("\n");
										#ifdef RETURN_TRUE
										//return RTN;
										#endif
										}
{WS}										
.										
%%

void return_str(char *s) 	
{
	str_T *str_t = NULL;
	char *str = NULL;
	
	str_t = malloc(sizeof(str_T));
	if(!str_t) 
		{
		printf("return_str out of memory size=%d\n", sizeof(str_T));
		exit(-1);
		}

	str = malloc(strlen(s));
	if(!str) 
		{
		printf("return_str out of memory size=%d\n", strlen(s));
		exit(-1);
		}
	
	memcpy(str,s,strlen(s));
	
	str_t->str = str;
	str_t->len = strlen(s);
	
	yylval.s=str_t;
}
/*


*/

yacc.y

%{
#include "main.h"
#include <string.h>

#define FREE_STR_T(x)	free(x->str);free(x)

int yylex(void);

char bufYacc[1024];

void log1(int i, char *str);
void log(int i, str_T *s);
%}
%union{
		func_stmt_T *f;
		list_node_T *pl;
		param_T	*p;
		type_T	*t;
		str_T *s;
		}

%token <s> TID TNUM
%token <s> T_MACRO
%token <s> TINT TINT8 TINT16 TINT32 TVOID TBOOL TPUBLIC TCONST TELLIPSIS 

%start stmt_list
%type <f> 	funcdef_stmt funcdef_1
%type <pl>	param_list param_list_1 param_list_2
%type <p>	param param1 param_forFP
%type <t>  	vartype vartype_star vartype_pri

%%
stmt_list:
	stmt_item										{log1(1,"");yacc_log("\n");}
	| stmt_list stmt_item							{log1(2,"");yacc_log("\n");}
;
stmt_item:
	error											{log1(3,"");yacc_log("\n");dowrong();}
	| T_MACRO										{log1(4,"");findMarco($1);FREE_STR_T($1)}
	| funcdef_stmt									{log1(5,"");findFuncStmt($1);}
;
funcdef_stmt:
	TPUBLIC funcdef_1								{log1(6,"");$$=$2;$$->hasPublic=1;FREE_STR_T($1)}
	| funcdef_1										{log1(7,"");$$=$1;$$->hasPublic=0;}
;
funcdef_1:
	vartype TID '(' param_list ')' ';'				{log1(8,"");$$=newFuncStmt(newParam($1,$2,NULL),$4);}
;
param_list:
	param_list_1									{log1(9,"");$$=$1;};
	|												{log1(11,"");$$=NULL;}
;
param_list_1:
	param_list_2 ',' TELLIPSIS						{log(12,$3);$$=addParamList(newParam(newType(TELLIPSIS, $3), NULL,NULL), $1); FREE_STR_T($3);}
	| param_list_2									{log1(13,"");$$=$1;}
;
param_list_2:
	param											{log1(14,"");$$=newParamList($1);}
	| param_list_2 ',' param						{log1(15,"");$$=addParamList($3,$1);}
;
param:
	param1											{log1(18, "");$$=$1;}
	| param_forFP									{log1(19, "");$$=$1;}
;
param_forFP: /*FP function pointer*/
	vartype '(' '*' TID ')' '(' param_list ')'		{log(20,$4);$$=newParam($1,$4,NULL);$$->type->typeid=T_FUNC_POINTER;$$->param_list=$7;FREE_STR_T($4);}
;
param1:
	vartype TID	'['TNUM']'								{log(21,$2);$$=newParam($1,$2,$4);FREE_STR_T($2);FREE_STR_T($4);}
	| vartype TID	'['']'								{str_T *p=NULL; 
														log(22,$2);p=(str_T*)malloc(sizeof(str_T));p->len=0;p->str="";
														$$=newParam($1,$2,p);FREE_STR_T($2);free(p);
														}
	| vartype TID										{log(23,$2);$$=newParam($1,$2,NULL);FREE_STR_T($2);}
	| vartype										{log1(24,"");$$=newParam($1,NULL,NULL);}
;
vartype:
	TCONST vartype_star							{log(25,$1);$$=$2;$$->hasConst=1;FREE_STR_T($1);}
	| vartype_star								{log1(26,"");$$=$1;$$->hasConst=0;}
;
vartype_star:
	vartype_pri										{log1(27,"");$$=$1;$$->pointer=0;}
	| vartype_star '*'							{log1(28,"*");$$=$1;$$->pointer++;}
;
vartype_pri:
	TID						
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值