%{ /* * * (c) Copyright 1989 OPEN SOFTWARE FOUNDATION, INC. * (c) Copyright 1989 HEWLETT-PACKARD COMPANY * (c) Copyright 1989 DIGITAL EQUIPMENT CORPORATION * To anyone who acknowledges that this file is provided "AS IS" * without any express or implied warranty: * permission to use, copy, modify, and distribute this * file for any purpose is hereby granted without fee, provided that * the above copyright notices and this notice appears in all source * code copies, and that none of the names of Open Software * Foundation, Inc., Hewlett-Packard Company, or Digital Equipment * Corporation be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. Neither Open Software Foundation, Inc., Hewlett- * Packard Company, nor Digital Equipment Corporation makes any * representations about the suitability of this software for any * purpose. * */ /* */ /* ** ** NAME: ** ** acf.l ** ** FACILITY: ** ** Interface Definition Language (IDL) Compiler ** ** ABSTRACT: ** ** "lex" source file for Attribute Configuration File (ACF) parser. ** ** VERSION: DCE 1.0 ** */ #define PROCESSING_LEX /* Define before including nidl.h */ #define PROCESSING_ACF_LEX /* Define before including nidl.h */ #include /* IDL common defs */ #include /* yacc include file */ #include /* Nametable defs */ #include /* Error message IDs */ #include #include /* Tank Trap to stop non-flex lexxers */ /* The macro FLEX_SCANNER is defined and generated by FLEX */ #ifndef FLEX_SCANNER This grammar file needs to be built with GNU Flex V2.4.6 or later. GNU Flex can be be obtained from ftp://prep.ai.mit.edu:/pub/gnu #endif extern int acf_yylineno; extern YYSTYPE acf_yylval; extern void commenteof( /* Called on EOF within comment */ #ifdef PROTO void #endif ); static void acf_yymark( /* Handles # left by cpp */ #ifdef PROTO void #endif ); static int acf_screen( /* Screens a token to see if it is a keyword */ #ifdef PROTO char *token #endif ); static void acf_read_comment( /* Reads and copies comment text */ #ifdef PROTO void #endif ); static int yywrap(void) { /* * Free the Flex buffer, yy_curent_buffer and yy_delete_buffer() * are FLEX interfaces to the internal buffering system. */ #ifdef YY_CURRENT_BUFFER_LVALUE acf_yy_delete_buffer(YY_CURRENT_BUFFER_LVALUE); /* free the FLEX buffer */ #else acf_yy_delete_buffer(yy_current_buffer); /* free the FLEX buffer */ #endif acf_yylineno = 1; return 1; } /*static char *identifier_name; Ptr to parsed identifier */ typedef struct /* Keyword and corresponding value */ { char *keyword; int token_value; } keyword_entry; static keyword_entry acf_keywords[] = /* Table of keywords and values */ { {"auto_handle", AUTO_HANDLE_KW}, {"binding_callout", BINDING_CALLOUT_KW}, {"code", CODE_KW}, {"comm_status", COMM_STATUS_KW}, {"cs_char", CS_CHAR_KW}, {"cs_tag_rtn", CS_TAG_RTN_KW}, {"enable_allocate", ENABLE_ALLOCATE_KW}, {"explicit_handle", EXPLICIT_HANDLE_KW}, {"extern_exceptions", EXTERN_EXCEPS_KW}, {"fault_status", FAULT_STATUS_KW}, {"handle_t", HANDLE_T_KW}, {"heap", HEAP_KW}, {"implicit_handle", IMPLICIT_HANDLE_KW}, {"include", INCLUDE_KW}, {"interface", INTERFACE_KW}, {"in_line", IN_LINE_KW}, {"nocode", NOCODE_KW}, {"out_of_line", OUT_OF_LINE_KW}, {"represent_as", REPRESENT_AS_KW}, {"typedef", TYPEDEF_KW}, {"nocancel", NOCANCEL_KW}, {0, 0} /* Sentinel - Do not remove */ }; %} delim [ \t\n\f] ws {delim}+ letter [A-Za-z_$] digit [0-9] oct_digit [0-7] hex_digit [0-9A-Fa-f] id {letter}({letter}|{digit})* other . %option yylineno %% {ws} { /* White space: No action, and no return */ } '\n' { /* GNUFLEX doesnt automatically track line #'s */ acf_yylineno++; } "," {return(COMMA);} "{" {return(LBRACE);} "??<" {return(LBRACE);} "[" {return(LBRACKET);} "(" {return(LPAREN);} "}" {return(RBRACE);} "??>" {return(RBRACE);} "]" {return(RBRACKET);} ")" {return(RPAREN);} ";" {return(SEMI);} ^"#".*\n {acf_yymark();} \"[^\"\n]*\" { /* Quoted string: Strip off quotes, add to string table. */ char stripped_string[max_string_len]; strcpy(stripped_string, (char *)&yytext[1]); stripped_string[strlen((char *)yytext)-2] = '\0'; acf_yylval.y_string = STRTAB_add_string(stripped_string); return(STRING); } "/*" { /* Comment: Ignore through closing delimiter. */ acf_read_comment(); } {id} { /* If id is too long, truncate it and issue a warning */ if (yyleng > MAX_ID) { NAMETABLE_id_t id; char const *identifier; id = NAMETABLE_add_id((char *)yytext); NAMETABLE_id_to_string(id, &identifier); log_warning(acf_yylineno, NIDL_IDTOOLONG, identifier, MAX_ID, NULL); /* Truncate the string */ yytext[MAX_ID] = '\0'; id = NAMETABLE_add_id((char *)yytext); } /* Identifier: See if it is a valid keyword. */ return acf_screen((char *)yytext); } {other} {return(UNKNOWN);}; %% /* ** a c f _ y y m a r k ** ** Processes a "# lineno" line as left by cpp. ** ** Implicit Outputs: ** acf_yylineno is updated; If a filename was included in the source ** line, set_name_for_errors is called to set up the source filename ** for error messages. */ static void acf_yymark() { char *source ; /* Source file name in #line directive */ int prev_lineno = acf_yylineno - 1; source = NEW_VEC (char, yyleng); if (sscanf((char *)yytext, "# line %d %s", &acf_yylineno, source) < 1) { if (sscanf((char *)yytext, "# %d %s", &acf_yylineno, source) < 1) { log_warning(prev_lineno, NIDL_CPPCMDOPT, #ifdef VMS (CMD_DCL_interface) ? "/PREPROCESS" : #endif "-cpp_cmd", NULL); } } /* If text included a source file name, set name for error reporting. */ if (source[0] != '\0') { char file_name[max_string_len]; /* Strip the quotes. */ strcpy(file_name, &source[1]); file_name[strlen(file_name)-1] = '\0'; set_name_for_errors(file_name); } FREE(source); } /* * a c f _ s c r e e n * * Function: Checks to see if a token is a keyword. * * Inputs: token to check * * Returns: specific keyword ID if token is a keyword; * the value IDENTIFIER otherwise */ #ifdef PROTO static int acf_screen(char *token) #else static int acf_screen(token) char *token; /* Token to "screen" */ #endif { int i; /* * Scan the reserved word table. */ for (i = 0; acf_keywords[i].keyword != 0; i++) if (strcmp(token, acf_keywords[i].keyword) == 0) return acf_keywords[i].token_value; /* Return keyword ID */ /* * Not a reserved word; therefore, an identifier, return nametable id. */ acf_yylval.y_id = NAMETABLE_add_id(token); return IDENTIFIER; /* Return IDENTIFER */ } /* * a c f _ r e a d _ c o m m e n t * * Function: Reads a comment in the source file. * */ #ifdef PROTO static void acf_read_comment(void) #else static void acf_read_comment() #endif { int c; while ( (c = input()) != 0 ) { if (c == '*') { if ( (c = input()) == '/') break; else yyunput(c, yytext); } else if (c == 0) commenteof(); } } /* * a c f _ k e y w o r d _ l o o k u p * * Looks up a keyword's text string given its numeric token value. */ char * acf_keyword_lookup #ifdef PROTO ( int token_value /* Numeric value of keyword token */ ) #else (token_value) int token_value; /* Numeric value of keyword token */ #endif { keyword_entry * entry; for (entry = acf_keywords ; entry->keyword != NULL ; entry++) if (entry->token_value == token_value) return entry->keyword; /* Not found, just return question mark. */ return "?"; } #ifdef FLEX_SCANNER /***************************************************************** * * Helper functions for managing multiple FLEX contexts * * GNU FLEX support for DCE 1.2.2 idl_compiler * added 07-11-97 Jim Doyle, Boston University, * * Maintainance note: * * The set of flex-specific static and global variables * managed by the following code may need to be changed * for versions of FLEX newer or later than v2.5.4. This * code was tested with Flex 2.4.6 and 2.5.4. V2.4 of FLEX * defined three static variables (yy_start_stack, * yy_start_stack_depth,yy_start_stack_ptr). In V2.5 of FLEX, * these three statics disappeared. Fortunately FLEX defined * macros YY_FLEX_MANOR_VERSION and YY_FLEX_MINOR_VERSION. * These are helpful for conditionally compiling in support for * several vintages of FLEX. * * *****************************************************************/ /***************************************************************** * * Data structure to store the state of a FLEX lexxer context * ACF grammar * *****************************************************************/ struct acf_flexxer_state_data { /* * flex statics - hidden from the outside world. These are * generated by flex. * * MAINTAINANCE NOTE: In versions later or earlier than 2.5.4, * the exact set of static variables that FLEX generates may be * different than is what is defined here. In that case, generate * the lexxer (i.e. flex nidl.l), grep the resulting generated C * flexxer for the word 'static'. You can then determine what * variables are new, dont exist, or have been renamed. Another * alternative for learning the names of all the static and global * variables used by the flexxer - is to compile the stub and * examine the object table dump (i.e using nm(1) on the .o file). * */ YY_BUFFER_STATE yy_current_buffer; char yy_hold_char; int yy_n_chars; char * yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; #ifdef YY_USES_REJECT yy_state_type *yy_state_ptr; char *yy_full_match; int yy_lp; #else yy_state_type yy_last_accepting_state; char * yy_last_accepting_cpos; #endif #if (YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION == 4) int yy_start_stack_ptr; int yy_start_stack_depth; int * yy_start_stack; #endif /* * flex globals - visible to the outside world * */ FILE * yyin; FILE * yyout; int yylineno; YYSTYPE yylval; int yyleng; char * yytext; }; typedef struct acf_flexxer_state_data acf_flexxer_activation_record; /***************************************************************** * * Basic constructors/destructors for FLEX activation states * *****************************************************************/ void * new_acf_flexxer_activation_record() { return (malloc(sizeof(acf_flexxer_activation_record))); } void delete_acf_flexxer_activation_record(void * p) { if (p) { /* * Note: do not call acf_yy_delete_buffer() from here. * Always do it from acf_yywrap(). Otherwise, severe * dementia and psychosis will occur. */ free((void *)p); } } /***************************************************************** * * Get/Set/Initialize methods * *****************************************************************/ void * get_current_acf_flexxer_activation() { acf_flexxer_activation_record * p; p = (acf_flexxer_activation_record * )new_acf_flexxer_activation_record(); /* * save the statics internal to the flexxer * */ #ifdef YY_CURRENT_BUFFER_LVALUE yyensure_buffer_stack(); p->yy_current_buffer = YY_CURRENT_BUFFER_LVALUE; #else p->yy_current_buffer = yy_current_buffer; #endif p->yy_hold_char = yy_hold_char; p->yy_n_chars = yy_n_chars; p->yy_c_buf_p = yy_c_buf_p; p->yy_init = yy_init; p->yy_start = yy_start; p->yy_did_buffer_switch_on_eof = yy_did_buffer_switch_on_eof; #ifdef YY_USES_REJECT p->yy_state_ptr = yy_state_ptr; p->yy_full_match = yy_full_match; p->yy_lp = yy_lp; #else p->yy_last_accepting_state = yy_last_accepting_state; p->yy_last_accepting_cpos = yy_last_accepting_cpos; #endif /* FLEX 2.5 does not have these variables. * FLEX 2.4 does have them though... */ #if (YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION == 4) p->yy_start_stack_ptr = yy_start_stack_ptr; p->yy_start_stack_depth = yy_start_stack_depth; p->yy_start_stack = yy_start_stack; #endif /* * save the globals, these are visible outside the scope * of the lexxer * */ p->yyin = acf_yyin; p->yyout = acf_yyout; p->yylineno = acf_yylineno; p->yylval = acf_yylval; p->yyleng = acf_yyleng; p->yytext = acf_yytext; return (void *)p; } void set_current_acf_flexxer_activation(void * ptr) { acf_flexxer_activation_record * p = (acf_flexxer_activation_record *)ptr; /* restore the statics */ #ifdef YY_CURRENT_BUFFER_LVALUE YY_CURRENT_BUFFER_LVALUE = p->yy_current_buffer; #else yy_current_buffer = p->yy_current_buffer; #endif yy_hold_char = p->yy_hold_char; yy_n_chars = p->yy_n_chars; yy_c_buf_p = p->yy_c_buf_p; yy_init = p->yy_init; yy_start = p->yy_start; yy_did_buffer_switch_on_eof = p->yy_did_buffer_switch_on_eof; #ifdef YY_USES_REJECT yy_state_ptr = p->yy_state_ptr; yy_full_match = p->yy_full_match; yy_lp = p->yy_lp; #else yy_last_accepting_state = p->yy_last_accepting_state; yy_last_accepting_cpos = p->yy_last_accepting_cpos; #endif /* FLEX 2.5 does not have these variables. * FLEX 2.4 does have them though... */ #if (YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION == 4) yy_start_stack_ptr = p->yy_start_stack_ptr; yy_start_stack_depth = p->yy_start_stack_depth; yy_start_stack = p->yy_start_stack; #endif /* * save the globals, these are visible outside the scope * of the lexxer * */ acf_yyin = p->yyin; acf_yyout = p->yyout; acf_yylineno = p->yylineno; acf_yylval = p->yylval; acf_yyleng = p->yyleng; acf_yytext = p->yytext; } void init_new_acf_flexxer_activation() { /* * set some initial conditions for a new FLEXER state * These were gleaned by looking at the compile-time * initializations in the generated nidl_lex_yy.c file. * */ #ifdef YY_CURRENT_BUFFER_LVALUE yyensure_buffer_stack(); YY_CURRENT_BUFFER_LVALUE = 0; #else yy_current_buffer = 0; #endif /* YY_CURRENT_BUFFER_LVALUE */ yy_c_buf_p = (char *) 0; yy_init = 1; yy_start = 0; /* FLEX 2.5 does not have these variables. * FLEX 2.4 does have them though... */ #if (YY_FLEX_MAJOR_VERSION == 2) && (YY_FLEX_MINOR_VERSION == 4) yy_start_stack_ptr = 0; yy_start_stack_depth = 0; yy_start_stack = 0; #endif } #endif /* FLEX_SCANNER */ /** End of "lex" source file. **/ /* preserve coding style vim: set tw=78 sw=4 : */