%{ /* * * (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: ** ** IDL.L ** ** FACILITY: ** ** Interface Definition Language (IDL) Compiler ** ** ABSTRACT: ** ** This file defines the tokenizing rules for lexical analysis. ** ** VERSION: DCE 1.0 ** */ /* Get definitions for token values */ #define PROCESSING_LEX /* Define before including nidl.h */ #define PROCESSING_NIDL_LEX /* Define before including nidl.h */ #include #include #include #include #include #include #include #include #include #ifdef GNU_LEX_YACC #define YY_DECL int yylex(YYSTYPE *yylval) #define YYLVAL(member) ((yylval)->member) #else #define YYLVAL(member) yylval.member #endif boolean search_attributes_table = false ; #ifndef MAX_INCLUSION_DEPTH #define MAX_INCLUSION_DEPTH 10 #endif void commenteof ( void ); #ifndef YY_DECL int yylex ( void ); #endif int yylook ( void ); static void read_c_comment ( void ); static void yymark ( void ); #ifdef GNU_LEX_YACC int yywrap (void); #else static int yywrap ( void ); #endif static int yyuuid ( char *s, nidl_uuid_t *uuid ); static int yyolduuid ( char *s, nidl_uuid_t *uuid ); int KEYWORDS_screen ( char *token, NAMETABLE_id_t *id ); char *KEYWORDS_lookup_text ( long token ); int yyinput ( void ); #ifndef _AIX int yyoutput ( int c ); #if !defined (GNU_LEX_YACC) int yyunput ( int c ); #endif /* GNU_LEX_YACC */ #endif /* !_AIX */ int yyback ( int *p, int m ); %} /* regular definitions */ delim [ \t\n\f] opt_ws {delim}* ws {delim} letter [A-Za-z_$] digit [0-9] hex_digit [0-9A-Fa-f] id {letter}({letter}|{digit})* l_suffix (l|L) u_suffix (u|U) f_suffix (u|U) integer -?{digit}+(({u_suffix}{l_suffix})|({l_suffix}{u_suffix})|{l_suffix}|{u_suffix})? c_hex_integer (0(x|X){hex_digit}*)(({l_suffix}{u_suffix}?)|({u_suffix}{l_suffix}?))? float {digit}+\.{digit}+({f_suffix}|{l_suffix})? octet {hex_digit}{hex_digit} octet2 {octet}{octet} octet_dot {octet}\. octet2_dash {octet2}\- olduuid \({opt_ws}{octet2}{octet2}{octet}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet}{opt_ws}\) uuid \({opt_ws}{octet2}{octet2_dash}{octet2_dash}{octet2_dash}{octet2_dash}{octet2}{octet2}{octet2}{opt_ws}\) other . %% {ws} { /* No action, and no return */ } ":" {return(COLON);} "," {return(COMMA);} ".." {return(DOTDOT);} "=" {return(EQUAL);} \[ {return(LBRACKET);} "(" {return(LPAREN);} \] {return(RBRACKET);} ")" {return(RPAREN);} ";" {return(SEMI);} "*" {return(STAR);} "{" {return(LBRACE);} "??<" {return(LBRACE);} "}" {return(RBRACE);} "??>" {return(RBRACE);} "?" {return(QUESTION);} "|" {return(BAR);} "||" {return(BARBAR);} "<" {return(LANGLE);} "<<" {return(LANGLEANGLE);} ">" {return(RANGLE);} ">>" {return(RANGLEANGLE);} "&" {return(AMP);} "&&" {return(AMPAMP);} "<=" {return(LESSEQUAL);} ">=" {return(GREATEREQUAL);} "==" {return(EQUALEQUAL);} "^" {return(CARET);} "+" {return(PLUS);} "-" {return(MINUS);} "!" {return(NOT);} "!=" {return(NOTEQUAL);} "/" {return(SLASH);} "%" {return(PERCENT);} "~" {return(TILDE);} ^"#".*\n { yymark() ;} ^"%"(c|C){ws}\n { log_error(yylineno-1,NIDL_USETRANS); } ^"%pascal"{ws}\n { log_error(yylineno-1,NIDL_USETRANS); } ^"%PASCAL"{ws}\n { log_error(yylineno-1,NIDL_USETRANS); } '\\'' { /* Simple escaped single quote character literal */ YYLVAL(y_char) = '\''; return(CHAR); } '[^'\n\\]' { /* Simple character constants */ YYLVAL(y_char) = yytext [1]; return(CHAR); } '\\[^'\n]*' { /* Character constants with an escape */ if ((yyleng > 6) || (yyleng < 4)) { log_error(yylineno, NIDL_INVCHARLIT); return(UNKNOWN); } switch (yytext[2]) { case 'n': YYLVAL(y_char) = '\n'; break; case 't': YYLVAL(y_char) = '\t'; break; case 'v': YYLVAL(y_char) = '\v'; break; case 'b': YYLVAL(y_char) = '\b'; break; case 'r': YYLVAL(y_char) = '\r'; break; case 'f': YYLVAL(y_char) = '\f'; break; case 'a': YYLVAL(y_char) = AUDIBLE_BELL; break; case '\\': YYLVAL(y_char) = '\\'; break; case '?': YYLVAL(y_char) = '\?'; break; case '\'': YYLVAL(y_char) = '\''; break; case '\"': YYLVAL(y_char) = '\"'; break; case 'x' : { /* Hex literal value */ int char_value; if (sscanf((char *)&yytext[3],"%x",&char_value) != 1) log_error(yylineno, NIDL_INVCHARLIT); else { YYLVAL(y_char) = (char )char_value; log_warning(yylineno, NIDL_NONPORTCHAR); } break; } case '0': case '1': case '2': case '3': case '4': case '5': case '7': { /* Octal literal value */ int char_value; if (sscanf((char *)&yytext[2],"%o",&char_value) != 1) log_error(yylineno, NIDL_INVCHARLIT); else { YYLVAL(y_char) = (char )char_value; log_warning(yylineno, NIDL_NONPORTCHAR); } break; } default: /* all others are illegal */ log_error(yylineno, NIDL_INVCHARLIT); return(UNKNOWN); } return (CHAR); } \"[^\"\n]* { if (yytext[yyleng-1] == '\\') yymore(); /* Allow \" within strings, look for next " */ else { YYLVAL(y_string) = STRTAB_add_string((char *)&yytext[1]); if (input() == '\n') log_error(yylineno, NIDL_STRUNTERM); return(STRING); } } "/*" { read_c_comment(); } {id} { int token; NAMETABLE_id_t id; /* If id is too long, truncate it and issue a warning */ if (yyleng > MAX_ID) { NAMETABLE_id_t id; char *identifier; id = NAMETABLE_add_id((char *)yytext); NAMETABLE_id_to_string(id, &identifier); log_warning(yylineno, NIDL_IDTOOLONG, identifier, MAX_ID); /* Truncate the string */ yytext[MAX_ID] = '\0'; id = NAMETABLE_add_id((char *)yytext); } if ((token = KEYWORDS_screen((char *)yytext, &id))==IDENTIFIER) { YYLVAL(y_id) = id; } else { YYLVAL(y_id) = NAMETABLE_NIL_ID; } return token; } {integer} { int unsigned_int = false; #if defined(vax) && defined(ultrix) float fval; char *fval_fmt = "%f"; #define FLOAT float #else double fval; char *fval_fmt = "%lf"; #define FLOAT double #endif /* ** Remove suffix for long and/or unsigned, if present */ if ((yytext[yyleng-1] == 'L') || (yytext[yyleng-1] == 'l') || (yytext[yyleng-1] == 'U') || (yytext[yyleng-1] == 'u')) { if ((yytext[yyleng-1] == 'U') || (yytext[yyleng-1] == 'u')) unsigned_int = true; yytext[yyleng-1] = '\0'; if ((yytext[yyleng-2] == 'L') || (yytext[yyleng-2] == 'l') || (yytext[yyleng-2] == 'U') || (yytext[yyleng-2] == 'u')) { if ((yytext[yyleng-2] == 'U') || (yytext[yyleng-2] == 'u')) unsigned_int = true; yytext[yyleng-2] = '\0'; } } /* ** Convert to a float to get overflow detection. */ sscanf((char *)yytext, fval_fmt, &fval); YYLVAL(y_ival) = 0; /* ** Throw out integers that are out of range. */ if (unsigned_int && ((strlen((char *)yytext) > 10) || (fval > (FLOAT)ASTP_C_ULONG_MAX) || (fval < (FLOAT)ASTP_C_ULONG_MIN) )) log_error(yylineno, NIDL_INTOVERFLOW, KEYWORDS_lookup_text(LONG_KW)); else if ((strlen((char *)yytext) > 11) || (fval > (FLOAT)ASTP_C_LONG_MAX) || (fval < (FLOAT)ASTP_C_LONG_MIN) ) log_error(yylineno, NIDL_INTOVERFLOW, KEYWORDS_lookup_text(LONG_KW)); else { sscanf((char *)yytext, "%i", &YYLVAL(y_ival)); } if ((yytext[0] == '0') && (strlen((char *)yytext) != strspn((char *)yytext,"01234567"))) { char *int_text; /* Text of integer */ STRTAB_str_t string_id; /* Entry in string table of integer */ string_id = STRTAB_add_string(yytext_p); STRTAB_str_to_string(string_id, &int_text); log_error(yylineno, NIDL_INVOCTDIGIT, int_text); } return(INTEGER_NUMERIC); } {c_hex_integer} { /* ** Remove suffix for long and/or unsigned, if present */ if ((yytext[yyleng-1] == 'L') || (yytext[yyleng-1] == 'l') || (yytext[yyleng-1] == 'U') || (yytext[yyleng-1] == 'u')) { yytext[yyleng-1] = '\0'; if ((yytext[yyleng-2] == 'L') || (yytext[yyleng-2] == 'l') || (yytext[yyleng-2] == 'U') || (yytext[yyleng-2] == 'u')) { yytext[yyleng-2] = '\0'; } } /* ** Scan the hex integer and return the value as an integer */ sscanf((char *)&yytext[2],"%x", &YYLVAL(y_ival)); return(INTEGER_NUMERIC); } {float} { YYLVAL(y_float) = STRTAB_add_string((char *)yytext); return(FLOAT_NUMERIC); } {uuid} { return (yyuuid((char *)&yytext[1], &YYLVAL(y_uuid))); } {olduuid} { return (yyolduuid((char *)&yytext[1], &YYLVAL(y_uuid))); } {other} { return (UNKNOWN); } %% void commenteof() { log_error (yylineno, NIDL_COMMENTEOF); nidl_terminate(); } #ifdef GNU_LEX_YACC int yywrap () #else static int yywrap () #endif { /* * With Flex, this causes infinite recursion between "yywrap()" and * "input()"; does it not do so with Lex? */ #ifndef GNU_LEX_YACC int c ; if ((c = input()) != 0) { unput(c) ; return (0) ; } #endif yylineno = 1 ; return (1); } static void yymark() { char *source ; /* Source file name in #line directive */ int prev_lineno = yylineno - 1; if (strncmp((char *)yytext, "#pragma", 7) == 0) { /* Just ignore #pragma. */ return; } source = (char *) MALLOC(yyleng) ; source[0] ='\0'; /* If the format wasn't # line {int} {string}, then reparse without "line" identifier */ if (sscanf((char *)yytext, "# line %d %s", &yylineno, source) < 1) { if (sscanf((char *)yytext, "# %d %s", &yylineno, source) < 1) { log_warning(prev_lineno, NIDL_CPPCMDOPT, #ifdef VMS (CMD_DCL_interface) ? "/PREPROCESS" : #endif "-cpp_cmd"); } } /* If text included a source file name, set name for error reporting. */ if (source[0] != '\0' && !(source[0] == '"' && source[1] == '"')) { 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); } static void read_c_comment() { register int c; /* While not EOF look for end of comment */ while ((c = input())) { if (c == '*') { if ((c = input()) == '/') break ; else unput(c) ; } } /* Didn't find end comment before EOF, issue error */ if (c == 0) commenteof(); } static int yyolduuid(s, uuid) char *s; nidl_uuid_t *uuid; { unsigned32 v1_time_high; unsigned32 v1_time_low; unsigned32 v1_reserved = 0; /* v1 UUID always zero here */ unsigned32 v1_family; unsigned32 v1_host[7]; int i; char *uuid_str; if (sscanf(s, "%8X%4X.%2X.%2X.%2X.%2X.%2X.%2X.%2X.%2X", &v1_time_high, &v1_time_low, &v1_family, &v1_host[0], &v1_host[1], &v1_host[2], &v1_host[3], &v1_host[4], &v1_host[5], &v1_host[6]) != 10) log_error(yylineno, NIDL_SYNTAXUUID); /* scanf only returns ints, so scan into ints and copy into smaller types */ uuid->time_low = v1_time_high; uuid->time_mid = v1_time_low; uuid->time_hi_and_version = v1_reserved; uuid->clock_seq_hi_and_reserved = v1_family; uuid->clock_seq_low = v1_host[0]; for (i=0; i < 6; i++) uuid->node[i] = v1_host[i+1]; uuid_str = (char *)malloc(sizeof("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); sprintf(uuid_str, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", uuid->time_low, uuid->time_mid, uuid->time_hi_and_version, uuid->clock_seq_hi_and_reserved, uuid->clock_seq_low, uuid->node[0], uuid->node[1], uuid->node[2], uuid->node[3], uuid->node[4], uuid->node[5]); log_warning(yylineno, NIDL_OLDUUID); log_warning(yylineno, NIDL_NEWUUID, uuid_str); return (UUID_REP) ; } static int yyuuid(s, uuid) char *s; nidl_uuid_t *uuid; { int i; unsigned32 time_low, time_mid, time_hi_and_version, clock_seq_hi_and_reserved, clock_seq_low, node[6]; if (sscanf(s, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", &time_low, &time_mid, &time_hi_and_version, &clock_seq_hi_and_reserved, &clock_seq_low, &node[0], &node[1], &node[2], &node[3], &node[4], &node[5]) != 11) log_error(yylineno, NIDL_SYNTAXUUID); /* scanf only returns ints, so scan into ints and copy into smaller types */ uuid->time_low = time_low; uuid->time_mid = time_mid; uuid->time_hi_and_version = time_hi_and_version; uuid->clock_seq_hi_and_reserved = clock_seq_hi_and_reserved; uuid->clock_seq_low = clock_seq_low; for (i=0; i < 6; i++) uuid->node[i] = node[i]; return (UUID_REP); } /* * Define some entry points for frontend with GNU Bison & Flex. These * save and restore the Flex state. Flex doesn't provide this functionality * so I had to work it from the lex_yy.c source code. */ #ifdef GNU_LEX_YACC #include "flex_state.h" void flex_SaveState (struct FlexState *Save) { /* * Save the state information */ Save->yy_start = yy_start; Save->yy_init = yy_init; Save->yy_more_flag = yy_more_flag; Save->yy_more_len = yy_more_len; Save->yy_did_buffer_switch_on_eof = yy_did_buffer_switch_on_eof; Save->yy_last_accepting_state = yy_last_accepting_state; Save->yy_last_accepting_cpos = yy_last_accepting_cpos; Save->yy_current_buffer = (void *)yy_current_buffer; #if 1 /* * We need to save these in yy_current_buffer without doing a calling * yy_switch_to_buffer because we don't want the full switch buffer * functionality. We just want to save the state, not initiate a * new buffer. */ if (Save->yy_current_buffer != (void *)NULL) { *yy_c_buf_p = yy_hold_char; yy_current_buffer->yy_buf_pos = yy_c_buf_p; yy_current_buffer->yy_n_chars = yy_n_chars; } #else Save->yy_hold_char = yy_hold_char; Save->yy_n_chars = yy_n_chars; Save->yy_c_buf_p = yy_c_buf_p; #endif /* Force the next call yylex to initialise */ yy_start = 0; yy_init = 1; yy_more_flag = 0; yy_more_len = 0; yy_did_buffer_switch_on_eof = 0; yy_last_accepting_state = 0; yy_last_accepting_cpos = NULL; yy_current_buffer = (YY_BUFFER_STATE)NULL; yy_hold_char = 0; yy_n_chars = 0; yy_c_buf_p = NULL; } /* * Restore the original state */ void flex_RestoreState (struct FlexState *Save) { /* * throw away the input buffer structure from the last parse */ if (yy_current_buffer != (YY_BUFFER_STATE)NULL) yy_delete_buffer (yy_current_buffer); /* * Restore the values */ yy_start = Save->yy_start; yy_init = Save->yy_init; yy_more_flag = Save->yy_more_flag; yy_more_len = Save->yy_more_len; yy_did_buffer_switch_on_eof = Save->yy_did_buffer_switch_on_eof; yy_last_accepting_state = Save->yy_last_accepting_state; yy_last_accepting_cpos = Save->yy_last_accepting_cpos; #if 1 /* * If the old input buffer structure existed, use it. Otherwise, * reset to null */ if (Save->yy_current_buffer != (void *)NULL) yy_switch_to_buffer ((YY_BUFFER_STATE)Save->yy_current_buffer); else yy_current_buffer = (YY_BUFFER_STATE)NULL; #else yy_hold_char = Save->yy_hold_char; yy_n_chars = Save->yy_n_chars; yy_c_buf_p = Save->yy_c_buf_p; #endif } #endif