home *** CD-ROM | disk | FTP | other *** search
Lex Description | 1990-12-28 | 11.0 KB | 504 lines |
- %{
- /* This is the yacc definition for the iid command language.
- * The main program, scanner, and parser are defined here.
- * The utility functions invoked from here are in iidfun.c
- */
-
- #include "iiddef.h"
-
- %}
-
- %union {
- set_type * setdef ;
- id_type * strdef ;
- id_list_type * listdef ;
- }
-
- %token < setdef > SET
-
- %token < strdef > ID SHELL_QUERY SHELL_COMMAND
-
- %type < setdef > Query Primitive
-
- %type < listdef > Lid_group Aid_group Id_list Command_list
-
- %token LID AID BEGIN SETS SS FILES SHOW HELP OFF MATCH
-
- %left OR
-
- %left AND
-
- %left NOT
-
- %start Command
-
- %%
-
- Command :
- BEGIN ID
- {
- /* cd to the directory specified as argument, flush sets */
-
- SetDirectory($2) ;
- FlushSets() ;
- }
- | Set_query Query
- | File_query Query
- {
- /* print the list of files resulting from Query */
-
- PrintSet($2) ;
- }
- | SHOW SET
- {
- /* run PAGER on the list of files in SET */
-
- RunPager(Pager, $2) ;
- }
- | SETS
- {
- /* describe sets created so far */
-
- DescribeSets() ;
- }
- | HELP
- {
- /* run PAGER on the help file */
-
- RunPager(Pager, HelpSet) ;
- }
- | OFF
- {
- exit(0) ;
- }
- | SHELL_QUERY Command_list
- {
- /* run the shell command and eat the results as a file set */
-
- OneDescription(RunProg($1->id, $2)) ;
- free($1) ;
- }
- | SHELL_COMMAND Command_list
- {
- /* run the shell command */
-
- RunShell($1->id, $2) ;
- free($1) ;
- }
- ;
-
- Set_query :
- SS
- {
- /* Turn on verbose query flag */
-
- VerboseQuery = TRUE ;
- }
- ;
-
- File_query :
- FILES
- {
- /* Turn off verbose query flag */
-
- VerboseQuery = FALSE ;
- }
- ;
-
- Query :
- Primitive
- {
- /* value of query is set associated with primitive */
-
- $$ = $1 ;
- }
- | Query AND Query
- {
- /* value of query is intersection of the two query sets */
-
- $$ = SetIntersect($1, $3) ;
- if (VerboseQuery) {
- OneDescription($$) ;
- }
- }
- | Query OR Query
- {
- /* value of query is union of the two query sets */
-
- $$ = SetUnion($1, $3) ;
- if (VerboseQuery) {
- OneDescription($$) ;
- }
- }
- | NOT Query
- {
- /* value of query is inverse of other query */
-
- $$ = SetInverse($2) ;
- if (VerboseQuery) {
- OneDescription($$) ;
- }
- }
- ;
-
- Primitive :
- SET
- {
- /* Value of primitive is value of recorded set */
-
- $$ = $1 ;
- }
- | Lid_group
- {
- /* Value of primitive is obtained by running an lid query */
-
- $$ = RunProg(LidCommand, $1) ;
- if (VerboseQuery) {
- OneDescription($$) ;
- }
- }
- | Aid_group
- {
- /* Value of primitive is obtained by running an aid query */
-
- $$ = RunProg("aid -kmn", $1) ;
- if (VerboseQuery) {
- OneDescription($$) ;
- }
- }
- | MATCH Id_list
- {
- /* Match names from database against pattern */
- $$ = RunProg("pid -kmn", $2) ;
- if (VerboseQuery) {
- OneDescription($$) ;
- }
- }
- | '(' Query ')'
- {
- /* value of primitive is value of query */
-
- $$ = $2 ;
- }
- ;
-
- Lid_group :
- ID
- {
- /* make arg list holding single ID */
-
- $$ = InitList() ;
- $$ = ExtendList($$, $1) ;
- LidCommand = DefaultCommand ;
- }
- | LID Id_list
- {
- /* arg list is Id_list */
-
- $$ = $2 ;
- LidCommand = "lid -kmn" ;
- }
- ;
-
- Aid_group :
- AID Id_list
- {
- /* arg list is Id_list */
-
- $$ = $2 ;
- }
- ;
-
- Command_list :
- ID
- {
- /* make arg list holding single ID */
-
- $$ = InitList() ;
- $$ = ExtendList($$, $1) ;
- }
- | SET
- {
- /* make arg list holding names from set */
-
- $$ = InitList() ;
- $$ = SetList($$, $1) ;
- }
- | Command_list ID
- {
- /* extend arg list with additional ID */
-
- $$ = ExtendList($1, $2) ;
- }
- | Command_list SET
- {
- /* extend arg list with additional file names */
-
- $$ = SetList($1, $2) ;
- }
- ;
-
- Id_list :
- ID
- {
- /* make arg list holding single ID */
-
- $$ = InitList() ;
- $$ = ExtendList($$, $1) ;
- }
- | Id_list ID
- {
- /* extend arg list with additional ID */
-
- $$ = ExtendList($1, $2) ;
- }
- ;
-
- %%
-
- /* ScanLine - a global variable holding a pointer to the current
- * command being scanned.
- */
- char * ScanLine ;
-
- /* ScanPtr - a global pointer to the current scan position in ScanLine.
- */
- char * ScanPtr ;
-
- /* yytext - buffer holding the token.
- */
- char yytext [ MAXCMD ] ;
-
- /* yyerror - process syntax errors.
- */
- int
- yyerror(s)
- char * s ;
- {
- if (*ScanPtr == '\0') {
- fprintf(stderr,"Syntax error near end of command.\n") ;
- } else {
- fprintf(stderr,"Syntax error on or before %s\n",ScanPtr) ;
- }
- return(0) ;
- }
-
- /* ScanInit - initialize the yylex routine for the new line of input.
- * Basically just initializes the global variables that hold the char
- * ptrs the scanner uses.
- */
- void
- ScanInit(line)
- char * line ;
- {
- /* skip the leading white space - the yylex routine is sensitive
- * to keywords in the first position on the command line.
- */
-
- while (isspace(*line)) ++line ;
- ScanLine = line ;
- ScanPtr = line ;
- }
-
- /* NameEq - compare two names for equality in a case insensitive manner.
- * return TRUE for equal, FALSE otherwise.
- */
- int
- NameEq(n1,n2)
- char * n1 ;
- char * n2 ;
- {
- char c1 ;
- char c2 ;
-
- for ( ; ; ) {
- c1 = *n1++ ;
- c2 = *n2++ ;
- if (isalpha(c1)) c1 = tolower(c1) ;
- if (isalpha(c2)) c2 = tolower(c2) ;
- if (c1 != c2) return FALSE ;
- if (c1 == '\0') return TRUE ;
- }
- }
-
- /* yylex - the scanner for iid. Basically a kludge ad-hoc piece of junk,
- * but what the heck, if it works...
- *
- * Mostly just scans for non white space strings and returns ID for them.
- * Does check especially for '(' and ')'. Just before returning ID it
- * checks for command names if it is the first token on line or
- * AND, OR, LID, AID if it is in the middle of a line.
- */
- int
- yylex()
- {
- char * bp ;
- char c ;
- int code = ID ;
- char * dp ;
- char * sp ;
- int val ;
-
- bp = ScanPtr ;
- while (isspace(*bp)) ++bp ;
- sp = bp ;
- c = *sp++ ;
- if ((c == '(') || (c == ')') || (c == '\0')) {
- ScanPtr = sp ;
- if (c == '\0') {
- --ScanPtr ;
- }
- return(c) ;
- } else {
- dp = yytext ;
- while (! ((c == '(') || (c == ')') || (c == '\0') || isspace(c))) {
- *dp++ = c ;
- c = *sp++ ;
- }
- *dp++ = '\0' ;
- ScanPtr = sp - 1 ;
- if (bp == ScanLine) {
-
- /* first token on line, check for command names */
-
- if (NameEq(yytext, "SS")) return(SS) ;
- if (NameEq(yytext, "FILES")) return(FILES) ;
- if (NameEq(yytext, "F")) return(FILES) ;
- if (NameEq(yytext, "HELP")) return(HELP) ;
- if (NameEq(yytext, "H")) return(HELP) ;
- if (NameEq(yytext, "?")) return(HELP) ;
- if (NameEq(yytext, "BEGIN")) return(BEGIN) ;
- if (NameEq(yytext, "B")) return(BEGIN) ;
- if (NameEq(yytext, "SETS")) return(SETS) ;
- if (NameEq(yytext, "SHOW")) return(SHOW) ;
- if (NameEq(yytext, "P")) return(SHOW) ;
- if (NameEq(yytext, "OFF")) return(OFF) ;
- if (NameEq(yytext, "Q")) return(OFF) ;
- if (NameEq(yytext, "QUIT")) return(OFF) ;
- if (yytext[0] == '!') {
- code = SHELL_COMMAND ;
- } else {
- code = SHELL_QUERY ;
- }
- } else {
-
- /* not first token, check for operator names */
-
- if (NameEq(yytext, "LID")) return(LID) ;
- if (NameEq(yytext, "AID")) return(AID) ;
- if (NameEq(yytext, "AND")) return(AND) ;
- if (NameEq(yytext, "OR")) return(OR) ;
- if (NameEq(yytext, "NOT")) return(NOT) ;
- if (NameEq(yytext, "MATCH")) return(MATCH) ;
- if ((yytext[0] == 's' || yytext[0] == 'S') && isdigit(yytext[1])) {
-
- /* this might be a set specification */
-
- sp = &yytext[1] ;
- val = 0 ;
- for ( ; ; ) {
- c = *sp++ ;
- if (c == '\0') {
- if (val < NextSetNum) {
- yylval.setdef = TheSets[val] ;
- return(SET) ;
- }
- }
- if (isdigit(c)) {
- val = (val * 10) + (c - '0') ;
- } else {
- break ;
- }
- }
- }
- }
- yylval.strdef = (id_type *)malloc(sizeof(id_type) + strlen(yytext)) ;
- if (yylval.strdef == NULL) {
- fatal("Out of memory in yylex") ;
- }
- yylval.strdef->next_id = NULL ;
- if (code == SHELL_COMMAND) {
- strcpy(yylval.strdef->id, &yytext[1]) ;
- } else {
- strcpy(yylval.strdef->id, yytext) ;
- }
- return(code) ;
- }
- }
-
- /* The main program for iid - parse the command line, initialize processing,
- * loop processing one command at a time.
- */
- main(argc, argv)
- int argc ;
- char * argv [ ] ;
- {
- int c ; /* current option */
- char * CmdPtr ; /* Points to the command string */
- char Command [ MAXCMD ] ; /* Buffer for reading commands */
- int Do1 = FALSE ; /* TRUE if should only do 1 command */
- int DoPrompt ; /* TRUE if should write a prompt */
- int errors = 0 ; /* error count */
-
- DoPrompt = isatty(fileno(stdin)) ;
- while ((c = getopt(argc, argv, "Hac:")) != EOF) {
- switch(c) {
- case 'a':
- DefaultCommand = "aid -kmn" ;
- break ;
- case 'c':
- CmdPtr = optarg ;
- Do1 = TRUE ;
- break ;
- case 'H':
- fputs("\
- iid: interactive ID database query tool. Call with:\n\
- iid [-a] [-c] [-H]\n\
- \n\
- -a\tUse the aid as the default query command (not lid).\n\
- -c cmd\tExecute the single query cmd and exit.\n\
- -H\tPrint this message and exit.\n\
- \n\
- To get help after starting program type 'help'.\n\
- ",stderr) ;
- exit(0) ;
- default:
- ++errors ;
- break ;
- }
- }
- if (argc != optind) {
- fputs("iid: Excess arguments ignored.\n",stderr) ;
- ++errors ;
- }
- if (errors) {
- fputs("run iid -H for help.\n",stderr) ;
- exit(1) ;
- }
-
- /* initialize global data */
-
- InitIid() ;
-
- /* run the parser */
-
- if (Do1) {
- ScanInit(CmdPtr) ;
- exit(yyparse()) ;
- } else {
- for ( ; ; ) {
- if (DoPrompt) {
- fputs(Prompt, stdout) ;
- fflush(stdout) ;
- }
- gets(Command) ;
- if (feof(stdin)) {
- if (DoPrompt) fputs("\n", stdout) ;
- strcpy(Command, "off") ;
- }
- ScanInit(Command) ;
- errors += yyparse() ;
- }
- }
- }
-