Files
epics-base/src/dbStatic/dbYacc.y
Andrew Johnson 16f572b06d Added support for 'info' items in database records - named strings that
are saved & loaded in the .db file, with an API for access at runtime and
the ability to associate a void* pointer with each at runtime.

Also added a capability to dbToRecordTypeH allowing a record type's .dbd
file to add lines to the generated .h file.  The C code should be placed
inside the recordtype's braces {} and each line must start with a '%'.
This facility is not currently accessible through a dbStaticLib API.
2000-08-09 21:38:34 +00:00

237 lines
5.0 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
%{
static int yyerror();
static int yy_start;
static long pvt_yy_parse(void);
static int yyFailed = 0;
static int yyAbort = 0;
#include "dbLexRoutines.c"
%}
%start database
%token tokenINCLUDE tokenPATH tokenADDPATH
%token tokenMENU tokenCHOICE tokenRECORDTYPE
%token tokenFIELD tokenINFO
%token tokenDEVICE tokenDRIVER tokenBREAKTABLE
%token tokenRECORD tokenGRECORD
%token <Str> tokenSTRING tokenCDEFS
%union
{
char *Str;
}
%%
database: database database_item | database_item;
database_item: include
| path
| addpath
| tokenMENU menu_head menu_body
| tokenRECORDTYPE recordtype_head recordtype_body
| device
| driver
| tokenBREAKTABLE break_head break_body
| tokenRECORD record_head record_body
| tokenGRECORD grecord_head record_body
;
include: tokenINCLUDE tokenSTRING
{
if(dbStaticDebug>2) printf("include : %s\n",$2);
dbIncludeNew($2); dbmfFree($2);
};
path: tokenPATH tokenSTRING
{
if(dbStaticDebug>2) printf("path : %s\n",$2);
dbPathCmd($2); dbmfFree($2);
};
addpath: tokenADDPATH tokenSTRING
{
if(dbStaticDebug>2) printf("addpath : %s\n",$2);
dbAddPathCmd($2); dbmfFree($2);
};
menu_head: '(' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("menu_head %s\n",$2);
dbMenuHead($2); dbmfFree($2);
};
menu_body: '{' choice_list '}'
{
if(dbStaticDebug>2) printf("menu_body\n");
dbMenuBody();
};
choice_list: choice_list choice | choice;
choice: tokenCHOICE '(' tokenSTRING ',' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("choice %s %s\n",$3,$5);
dbMenuChoice($3,$5); dbmfFree($3); dbmfFree($5);
}
| include;
recordtype_head: '(' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("recordtype_head %s\n",$2);
dbRecordtypeHead($2); dbmfFree($2);
};
recordtype_body: '{' recordtype_field_list '}'
{
if(dbStaticDebug>2) printf("recordtype_body\n");
dbRecordtypeBody();
};
recordtype_field_list: recordtype_field_list recordtype_field
| recordtype_field;
recordtype_field: tokenFIELD recordtype_field_head recordtype_field_body
| tokenCDEFS
{
if(dbStaticDebug>2) printf("recordtype_cdef %s", $1);
dbRecordtypeCdef($1);
}
| include ;
recordtype_field_head: '(' tokenSTRING ',' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("recordtype_field_head %s %s\n",$2,$4);
dbRecordtypeFieldHead($2,$4); dbmfFree($2); dbmfFree($4);
};
recordtype_field_body: '{' recordtype_field_item_list '}' ;
recordtype_field_item_list: recordtype_field_item_list recordtype_field_item
| recordtype_field_item;
recordtype_field_item: tokenSTRING '(' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("recordtype_field_item %s %s\n",$1,$3);
dbRecordtypeFieldItem($1,$3); dbmfFree($1); dbmfFree($3);
}
| tokenMENU '(' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("recordtype_field_item %s (%s)\n","menu",$3);
dbRecordtypeFieldItem("menu",$3); dbmfFree($3);
};
device: tokenDEVICE '('
tokenSTRING ',' tokenSTRING ',' tokenSTRING ',' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("device %s %s %s %s\n",$3,$5,$7,$9);
dbDevice($3,$5,$7,$9);
dbmfFree($3); dbmfFree($5);
dbmfFree($7); dbmfFree($9);
};
driver: tokenDRIVER '(' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("driver %s\n",$3);
dbDriver($3); dbmfFree($3);
};
break_head: '(' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("break_head %s\n",$2);
dbBreakHead($2); dbmfFree($2);
};
break_body : '{' break_list '}'
{
if(dbStaticDebug>2) printf("break_body\n");
dbBreakBody();
};
break_list: break_list ',' break_item
| break_list break_item
| break_item;
break_item: tokenSTRING
{
if(dbStaticDebug>2) printf("break_item tokenSTRING %s\n",$1);
dbBreakItem($1); dbmfFree($1);
};
grecord_head: '(' tokenSTRING ',' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("grecord_head %s %s\n",$2,$4);
dbRecordHead($2,$4,1); dbmfFree($2); dbmfFree($4);
};
record_head: '(' tokenSTRING ',' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("record_head %s %s\n",$2,$4);
dbRecordHead($2,$4,0); dbmfFree($2); dbmfFree($4);
};
record_body: /*Null*/
{
if(dbStaticDebug>2) printf("null record_body\n");
dbRecordBody();
}
| '{' '}'
{
if(dbStaticDebug>2) printf("record_body - no fields\n");
dbRecordBody();
}
| '{' record_field_list '}'
{
if(dbStaticDebug>2) printf("record_body\n");
dbRecordBody();
};
record_field_list: record_field_list record_field
| record_field;
record_field: tokenFIELD '(' tokenSTRING ',' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("record_field %s %s\n",$3,$5);
dbRecordField($3,$5); dbmfFree($3); dbmfFree($5);
}
| tokenINFO '(' tokenSTRING ',' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("record_info %s %s\n",$3,$5);
dbRecordInfo($3,$5); dbmfFree($3); dbmfFree($5);
}
| include ;
%%
#include "dbLex.c"
static int yyerror(char *str)
{
fprintf(stderr,"Error ");
if(str) fprintf(stderr,"\"%s\"",str);
fprintf(stderr," Last token \"%s\"\n",yytext);
dbIncludePrint(stderr);
yyFailed = TRUE;
return(0);
}
static long pvt_yy_parse(void)
{
static int FirstFlag = 1;
long rtnval;
if (!FirstFlag) {
yyAbort = FALSE;
yyFailed = FALSE;
yyreset();
yyrestart(NULL);
}
FirstFlag = 0;
rtnval = yyparse();
if(rtnval!=0 || yyFailed) return(-1); else return(0);
}