1 %option yylineno 2 %{ /*-*- Mode: C -*-*/ 3 /************************************************************************** 4 ** File : lexical.l ** 5 ** Author : Edward Groenendaal ** 6 ** Modified : 29/3/92 - set MAXERR to 0, put filename in error ** 7 ** messages, eddyg. ** 8 ** 18-04-92, Edward Groenendaal ** 9 ** Added #if NeedFunctionPrototypes stuff ** 10 **************************************************************************/ 11 12 /* with A/UX on a macII the pre-processor tries to expand the lex input macro 13 * within the X11R4 Xutil.h header file, therefore to prevent this I have 14 * defined the _XUTIL_H_ symbol for macII's, it's not needed in this file 15 * anyway. Edward Groenendaal 19-04-92.. Easter day.. and I'm doing this!?! 16 * 17 * 20-04-92 Edward Groenendaal - I had the same problem on a Sun (SunOS4.1.1) 18 * with X11R4, I therefore am going to undef _XUTIL_H_ for ALL machines. 19 */ 20 21 #ifdef __STDC__ 22 #include "xdtm.h" 23 #endif 24 25 /* #ifdef macII */ 26 #ifndef _XUTIL_H_ 27 #define _XUTIL_H_ 28 #endif 29 /* #endif */ 30 31 #ifndef __STDC__ 32 #include "xdtm.h" 33 #endif 34 #include "parse.h" 35 36 /* 37 * Check to see if we are using flex instead of lex. If so, need to 38 * undefine yywrap. 39 */ 40 41 #ifdef FLEX_SCANNER 42 #undef yywrap 43 #endif 44 45 /* I shall use the macro RETURN whenever returning a token. If DEBUG_LEX has 46 * been defined then the token will be printed out, otherwise it will 47 * be returned. 48 */ 49 50 #ifdef DEBUG_LEX 51 52 /* define the RETURN macro to print the token to be returned */ 53 # define RETURN(token) fprintf(stdout,"Token: " #token "\tReturned.\n") 54 55 /* define the tokens to be returned. ONLY in DEBUG mode, when in normal 56 * operation the tokens are defined by yacc. 57 */ 58 enum tokens { IF_T, 59 SET_T, 60 ICON_T, 61 NAME_T, 62 PATH_T, 63 ASSIGN_T, 64 EQUAL_T, 65 NEQUAL_T, 66 STRING_T, 67 SEMIC_T, 68 O_PAR_T, 69 C_PAR_T, 70 O_BRACE_T, 71 C_BRACE_T, 72 DEFICON_T, 73 CHECKPATH_T, 74 TRUE_T, 75 FALSE_T, 76 TYPE_T, 77 DIR_T, 78 FILE_T, 79 READ_T, 80 WRITE_T, 81 EXE_T, 82 BLOCK_T, 83 CHARACTER_T, 84 SLINK_T, 85 SOCKET_T, 86 FIFO_T, 87 PROG_T, 88 OPTIONS_T, 89 TERMOPT_T, 90 COMMA_T, 91 MSEL_T, 92 OSEL_T, 93 NSEL_T, 94 ASEL_T, 95 DEFINE_T, 96 DEFAPPL_T, 97 TERM_T, 98 NOTERM_T, 99 FIRST_T, 100 COLON_T, 101 IGNORE_T, 102 ERRORTOKEN 103 }; 104 105 #else /* No DEBUG */ 106 107 #include "parser.h" /* get the tokens from yacc */ 108 109 /* define the RETURN token to set the return value to the token to be 110 * returned, then return that token. 111 */ 112 # define RETURN(token) yylval.number=token;return(token) 113 #endif 114 115 #include <sys/types.h> 116 #include <stdio.h> 117 118 #define MAXERR 0 /* Maximum number of errors before the parser */ 119 /* quits. */ 120 121 void yyerror( 122 #if NeedFunctionPrototypes 123 char* 124 #endif 125 ); 126 127 typedef struct { /* structure for keyword table */ 128 String name; 129 int token; 130 } keyword; 131 132 static keyword keywordtable[] = { /* table of keywords, in alphabetical order */ 133 {"ASEL", ASEL_T}, 134 {"False", FALSE_T}, 135 {"MSEL", MSEL_T}, 136 {"NOTERM", NOTERM_T}, 137 {"NSEL", NSEL_T}, 138 {"OSEL", OSEL_T}, 139 {"TERM", TERM_T}, 140 {"True", TRUE_T}, 141 {"block", BLOCK_T}, 142 {"character", CHARACTER_T}, 143 {"checkpath", CHECKPATH_T}, 144 {"cmd", CMD_T}, 145 {"defappl", DEFAPPL_T}, 146 {"deficon", DEFICON_T}, 147 {"define", DEFINE_T}, 148 {"dir", DIR_T}, 149 {"exe", EXE_T}, 150 {"false", FALSE_T}, 151 {"fifo", FIFO_T}, 152 {"file", FILE_T}, 153 {"first", FIRST_T}, 154 {"icon", ICON_T}, 155 {"if", IF_T}, 156 {"ignore", IGNORE_T}, 157 {"name", NAME_T}, 158 {"options", OPTIONS_T}, 159 {"path", PATH_T}, 160 {"prog", PROG_T}, 161 {"read", READ_T}, 162 {"set", SET_T}, 163 {"slink", SLINK_T}, 164 {"socket", SOCKET_T}, 165 {"termopt", TERMOPT_T}, 166 {"true", TRUE_T}, 167 {"type", TYPE_T}, 168 {"write", WRITE_T} 169 }; 170 /* number of entries in the keyword table */ 171 static int numkeywords = (sizeof(keywordtable)/sizeof(keywordtable[0])); 172 173 int parseerror=0; /* Number of parse errors */ 174 char errormessage[255]; /* used for error messsages */ 175 176 %} 177 %% 178 [\t ]*"#".* { /* Remove Comments from beginning of line */ } 179 "=" { RETURN(ASSIGN_T); } 180 "==" { RETURN(EQUAL_T); } 181 "{" { RETURN(O_BRACE_T); } 182 "}" { RETURN(C_BRACE_T); } 183 "(" { RETURN(O_PAR_T); } 184 ")" { RETURN(C_PAR_T); } 185 ";" { RETURN(SEMIC_T); } 186 "," { RETURN(COMMA_T); } 187 ":" { RETURN(COLON_T); } 188 [A-Za-z]+ { int token = parse_keyword(yytext); 189 #ifndef DEBUG_LEX 190 yylval.number = token; 191 return(token); 192 #endif 193 } 194 195 \n { 196 #ifdef FLEX_SCANNER 197 yylineno++; 198 #endif 199 } 200 [\t ] { /* Ignore White space */ } 201 \"[^\"]*\" { 202 #ifdef DEBUG_LEX 203 fprintf(stdout, "Token STRING_T %s returned", yytext); 204 #else 205 yylval.string = yytext; 206 return(STRING_T); 207 #endif 208 } 209 . { 210 sprintf(errormessage, "illegal character \'%c\'.", yytext[0]); 211 yyerror(errormessage); 212 } 213 %% 214 215 216 /***************************************************************************** 217 * yywrap * 218 *****************************************************************************/ 219 int yywrap() 220 { 221 /* function called when EOF encounterd. 222 * 223 * - Takes nothing 224 * + returns EOF token, not actually used other than to indicate an error 225 * to the parser. Useful in DEBUG mode to see that EOF has been detected. 226 */ 227 228 RETURN(EOFTOKEN); 229 } 230 231 232 /***************************************************************************** 233 * parse_keyword * 234 *****************************************************************************/ 235 int parse_keyword(str) 236 String str; 237 { 238 /* Function to determine whether a string is a reserved keyword or an 239 * identifier. A table of keywords is searched via a binary search to check 240 * to see if the string is a keyword,if it is found the associated 241 * token is returned, otherwise an error is printed and ERRORTOKEN 242 * is returned. 243 * The effect of debugging is to prevent the assignment 244 * to the yacc structure, and to print out the keyword if found. 245 * 246 * - Takes a string to check 247 * + Returns a token (int) 248 */ 249 250 register int lower = 0, upper = numkeywords-1; 251 252 while (lower <= upper) { 253 int middle = (lower + upper) /2; 254 keyword *p = &keywordtable[middle]; 255 int res = strcmp(p->name, str); 256 257 if (res < 0) { 258 lower = middle +1; 259 } else if (res == 0) { 260 #ifdef DEBUG_LEX 261 fprintf(stdout, "Token: %s\tReturned.\n", p->name); 262 #endif 263 return(p->token); 264 } else { 265 upper = middle -1; 266 } 267 } 268 sprintf(errormessage, "unknown keyword \'%s\'.", yytext); 269 yyerror(errormessage); 270 RETURN(ERRORTOKEN); 271 } 272 273 /**************************************************************************** 274 * yyerror * 275 ****************************************************************************/ 276 void yyerror(message) 277 char *message; 278 { 279 /* For the moment (29/3/92) the program will be terminated on the first 280 * parse error, this is due to the complexities involved in continuing 281 * the parse after an error. 282 * Edward Groenendaal. 283 * 284 */ 285 286 extern int yylineno; 287 288 if (preferences_filename == NULL) 289 preferences_filename = XtNewString("config file"); 290 291 if (parseerror < MAXERR) { 292 fprintf(stderr, "(E) %s:line :%2d: ", preferences_filename, yylineno); 293 fprintf(stderr, "%s\n", message); 294 parseerror++; 295 } else { 296 fprintf(stderr, "(E) %s:line :%2d: ", preferences_filename, yylineno); 297 fprintf(stderr, "%s\n", message); 298 parseerror++; 299 /* fprintf(stderr, "Fatal error: over %d errors, exiting\n", MAXERR); */ 300 exit(2); 301 } 302 } 303