基于lex/yacc,识别出 .h文件中、所有的合法的函数定义
包括三个源代码:
- lex.l: 词法定义
- yacc.y: 语法定义
- 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