%{ /* scan.l: the (f)lex description file for the scanner. */ /* This file is part of bc written for MINIX. Copyright (C) 1991, 1992 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License , or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. You may contact the author by: e-mail: phil@cs.wwu.edu us-mail: Philip A. Nelson Computer Science Department, 9062 Western Washington University Bellingham, WA 98226-9062 *************************************************************************/ #include "bcdefs.h" #include "y.tab.h" #include "global.h" #include "proto.h" /* Using flex, we can ask for a smaller input buffer. With lex, this does nothing! */ #ifdef SMALL_BUF #undef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 512 #endif /* We want to define our own yywrap. */ #undef yywrap _PROTOTYPE(int yywrap, (void)); /* MINIX returns from read with < 0 if SIGINT is encountered. In flex, we can redefine YY_INPUT to the following. In lex, this does nothing! */ #include #undef YY_INPUT #define YY_INPUT(buf,result,max_size) \ while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ if (errno != EINTR) \ YY_FATAL_ERROR( "read() in flex scanner failed" ); %} DIGIT [0-9A-F] LETTER [a-z] %% define return(Define); break return(Break); quit return(Quit); length return(Length); return return(Return); for return(For); if return(If); while return(While); sqrt return(Sqrt); scale return(Scale); ibase return(Ibase); obase return(Obase); auto return(Auto); else return(Else); read return(Read); halt return(Halt); last return(Last); warranty return(Warranty); continue return(Continue); print return(Print); limits return(Limits); "+"|"-"|";"|"("|")"|"{"|"}"|"["|"]"|","|"^" { yylval.c_value = yytext[0]; return((int)yytext[0]); } && { return(AND); } \|\| { return(OR); } "!" { return(NOT); } "*"|"/"|"%" { yylval.c_value = yytext[0]; return(MUL_OP); } "="|\+=|-=|\*=|\/=|%=|\^= { yylval.c_value = yytext[0]; return(ASSIGN_OP); } =\+|=-|=\*|=\/|=%|=\^ { #ifdef OLD_EQ_OP char warn_save; warn_save = warn_not_std; warn_not_std = TRUE; warn ("Old fashioned ="); warn_not_std = warn_save; yylval.c_value = yytext[1]; #else yylval.c_value = '='; yyless (1); #endif return(ASSIGN_OP); } ==|\<=|\>=|\!=|"<"|">" { yylval.s_value = strcopyof((char *) yytext); return(REL_OP); } \+\+|-- { yylval.c_value = yytext[0]; return(INCR_DECR); } "\n" { line_no++; return(NEWLINE); } \\\n { line_no++; /* ignore a "quoted" newline */ } [ \t]+ { /* ignore spaces and tabs */ } "/*" { int c; for (;;) { while ( ((c=input()) != '*') && (c != EOF)) /* eat it */ if (c == '\n') line_no++; if (c == '*') { while ( (c=input()) == '*') /* eat it*/; if (c == '/') break; /* at end of comment */ if (c == '\n') line_no++; } if (c == EOF) { fprintf (stderr,"EOF encountered in a comment.\n"); break; } } } [a-z][a-z0-9_]* { yylval.s_value = strcopyof((char *) yytext); return(NAME); } \"[^\"]*\" { unsigned char *look; int count = 0; yylval.s_value = strcopyof((char *) yytext); for (look = yytext; *look != 0; look++) { if (*look == '\n') line_no++; if (*look == '"') count++; } if (count != 2) yyerror ("NUL character in string."); return(STRING); } {DIGIT}({DIGIT}|\\\n)*("."({DIGIT}|\\\n)*)?|"."(\\\n)*{DIGIT}({DIGIT}|\\\n)* { unsigned char *src, *dst; int len; /* remove a trailing decimal point. */ len = strlen((char *) yytext); if (yytext[len-1] == '.') yytext[len-1] = 0; /* remove leading zeros. */ src = yytext; dst = yytext; while (*src == '0') src++; if (*src == 0) src--; /* Copy strings removing the newlines. */ while (*src != 0) { if (*src == '\\') { src++; src++; line_no++; } else *dst++ = *src++; } *dst = 0; yylval.s_value = strcopyof((char *) yytext); return(NUMBER); } . { if (yytext[0] < ' ') yyerror ("illegal character: ^%c",yytext[0] + '@'); else if (yytext[0] > '~') yyerror ("illegal character: \\%3d", (int) yytext[0]); else yyerror ("illegal character: %s",yytext); } %% /* This is the way to get multiple files input into lex. */ int yywrap() { if (!open_new_file ()) return (1); /* EOF on standard in. */ return (0); /* We have more input. */ }