/* -*- c++ -*- copy[write] by dirlt(zhang_yan@baidu.com) date time:Mon Nov 17 12:06:46 CST 2008 file name:idl.gram */ %{ #include #include #include "idl.h" /* to cancel the flex internal definition of idllex:-) */ #define YY_DECL #include "idl_gram.h" #include "idl_lex.h" extern int cfgidllex(YYSTYPE* yylval,yyscan_t scanner, meta_t *loc,idl_t *idl); static void cfgidlerror(yyscan_t scanner,meta_t *loc, idl_t *idl,char *msg); %} /* generate the header file */ %defines /* the output file is idl_gram.c and idl_gram.h */ %output="idl_gram.c" /* we want the name prefix */ %name-prefix="cfgidl" /* we want to get the much more detail error message */ %error-verbose /* lex-param */ %lex-param{yyscan_t scanner} %lex-param{meta_t *loc} %lex-param{idl_t *idl} /* parse param */ %parse-param {yyscan_t scanner} %parse-param{meta_t *loc} %parse-param {idl_t *idl} /* reentrant parser */ %pure-parser /* generate the output file */ %verbose %union{ meta_t *meta; var_t *var; group_t *grp; cf_list_t *cf_list; meta_list_t *meta_list; var_list_t *var_list; cf_t *cf; } %token KW_OVERWRITE KW_STRUCT %token KW_RAW %token KW_CHAR KW_UCHAR %token KW_INT8 KW_UINT8 %token KW_INT16 KW_UINT16 %token KW_INT32 KW_UINT32 %token KW_INT64 KW_UINT64 %token KW_FLOAT KW_DOUBLE %token KW_STRING INTEGER ID LITERAL_STRING DOUBLE %token VAR_CMD %type variable %type variable_list %type group %type optional_array %type optional_cmd %type optional_constraint constraint_list %type constraint_function %type constraint_function_param_list %type type_name cons_func_param /* designate the start symbol */ %start program %% program :program variable { add_idl_var(idl,$2); } |program group { add_idl_group(idl,$2); } | ; variable :type_name ID optional_array optional_constraint ';' optional_cmd { meta_t *type=$1,*id=$2; meta_list_t *array_size_list=$3; meta_list_t *cmdval = $6; cf_list_t *cf_list=$4; cf_t *cf; var_t *var=alloc_var(idl); //allocate the necessary space if(cf_list==NULL) { cf_list=new cf_list_t; idl->parse_list.push_back(cf_list); } if(array_size_list==NULL) { array_size_list=new meta_list_t; idl->parse_meta_list.push_back(array_size_list); } if(array_size_list->size()!=0){ /* the arary size list does exist */ cf=alloc_cf(idl); meta_t func; func.data="array"; func.file=id->file; func.lineno=id->lineno; assemble_idl_cf(cf,&func,array_size_list); cf_list->push_back(cf); } if (cmdval != NULL) { meta_t func ; func.data = "comment"; func.file = id->file; func.lineno = id->lineno; cf_t *cf = alloc_cf(idl); assemble_idl_cf(cf, &func, cmdval); cf_list->push_back(cf); //delete cmdval; } assemble_idl_var(idl,var,id,type,cf_list); //delete cf_list; //delete array_size_list; $$=var; } ; optional_cmd :VAR_CMD { meta_list_t *lst = new meta_list_t; idl->parse_meta_list.push_back(lst); lst->push_back($1); idl->cmdreserve = 0; $$ = lst; } | { idl->cmdreserve = 0; $$ = NULL; } ; optional_array :optional_array '[' INTEGER ']' { meta_list_t *array_size_list=$1; meta_t *array_tag=$3; int array_size=atoi(array_tag->data.c_str()); /* we have to validate here */ if(array_size<=0){ char tmpstr[2048]; meta_t errinfo; snprintf(tmpstr,sizeof(tmpstr),"array size %d is invalid",array_size); errinfo.data=tmpstr; errinfo.file=array_tag->file; errinfo.lineno=array_tag->lineno; add_idl_error(idl,errinfo); array_tag->data="0"; } array_size_list->push_back(array_tag); $$=array_size_list; } | optional_array '[' ']' { meta_list_t *array_size_list=$1; meta_t *array_size=alloc_meta(idl); array_size->data="0"; array_size->file=loc->file; array_size->lineno=loc->lineno; array_size_list->push_back(array_size); $$=array_size_list; } | { meta_list_t *array_size_list=new meta_list_t; idl->parse_meta_list.push_back(array_size_list); $$=array_size_list; } ; type_name :KW_RAW {$$=$1;} |KW_CHAR {$$=$1;} |KW_UCHAR {$$=$1;} |KW_INT8 {$$=$1;} |KW_UINT8 {$$=$1;} |KW_INT16 {$$=$1;} |KW_UINT16 {$$=$1;} |KW_INT32 {$$=$1;} |KW_UINT32 {$$=$1;} |KW_INT64 {$$=$1;} |KW_UINT64 {$$=$1;} |KW_FLOAT {$$=$1;} |KW_DOUBLE {$$=$1;} |KW_STRING {$$=$1;} |ID {$$=$1;} ; optional_constraint :'=' constraint_list { $$=$2; idl->cmdreserve = 1; } | { $$=NULL; idl->cmdreserve = 1; } ; constraint_list :constraint_list ',' constraint_function { cf_list_t *cf_list=$1; cf_t *cf=$3; cf_list->push_back(cf); $$=cf_list; } | constraint_function { cf_list_t *cf_list=new cf_list_t; idl->parse_list.push_back(cf_list); cf_t *cf=$1; cf_list->push_back(cf); $$=cf_list; } ; constraint_function :ID '(' constraint_function_param_list ')' { meta_t *func=$1; meta_list_t *arg_list=$3; cf_t *cf=alloc_cf(idl); assemble_idl_cf(cf,func,arg_list); //delete arg_list; $$=cf; } |ID '(' ')' { meta_t *func=$1; meta_list_t *arg_list=new meta_list_t; cf_t *cf=alloc_cf(idl); assemble_idl_cf(cf,func,arg_list); delete arg_list; $$=cf; } ; constraint_function_param_list :constraint_function_param_list ',' cons_func_param { meta_list_t *param_list=$1; meta_t *param=$3; param_list->push_back(param); $$=param_list; } | cons_func_param { meta_list_t *param_list=new meta_list_t; idl->parse_meta_list.push_back(param_list); meta_t *param=$1; param_list->push_back(param); $$=param_list; } ; cons_func_param :LITERAL_STRING {$$=$1;} |ID {$$=$1;} |INTEGER {$$=$1;} |DOUBLE {$$=$1;} ; group :KW_STRUCT ID '{' variable_list '}' ';' { meta_t *id=$2; var_list_t *var_list=$4; group_t *grp; grp=alloc_group(idl); assemble_idl_group(idl,grp,id,var_list); //delete var_list; $$=grp; } |ID KW_OVERWRITE ID '{' variable_list '}' ';' { meta_t *new_id=$1,*old_id=$3; var_list_t *var_list=$5; group_t *grp; grp=alloc_group(idl); overwrite_idl_group(idl,grp,new_id,old_id,var_list); //delete var_list; $$=grp; } ; variable_list :variable_list variable { var_list_t *var_list=$1; var_t *var=$2; var_list->push_back(var); $$=var_list; } | { var_list_t *var_list=new var_list_t; idl->parse_var_list.push_back(var_list); $$=var_list; } ; %% void cfgidlerror(yyscan_t scanner,meta_t *loc,idl_t *idl,char *msg) { char tmp[2048]; meta_t errinfo; errinfo.file=loc->file; errinfo.lineno=loc->lineno; snprintf(tmp,sizeof(tmp),"%s before char:'%c'", msg, cfgidlget_text(scanner)[0]); errinfo.data=tmp; add_idl_error(idl,errinfo); return ; }