2 /* $FreeBSD: src/contrib/bc/bc/scan.l,v 1.4.2.1 2001/03/04 09:34:54 kris Exp $ */
3 /* $DragonFly: src/contrib/bc/bc/Attic/scan.l,v 1.2 2003/06/17 04:23:58 dillon Exp $ */
4 /* scan.l: the (f)lex description file for the scanner. */
6 /* This file is part of GNU bc.
7 Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License , or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING. If not, write to
21 The Free Software Foundation, Inc.
22 59 Temple Place, Suite 330
25 You may contact the author by:
26 e-mail: philnelson@acm.org
27 us-mail: Philip A. Nelson
28 Computer Science Department, 9062
29 Western Washington University
30 Bellingham, WA 98226-9062
32 *************************************************************************/
40 /* Using flex, we can ask for a smaller input buffer. With lex, this
44 #undef YY_READ_BUF_SIZE
45 #define YY_READ_BUF_SIZE 512
48 /* Force . as last for now. */
51 /* We want to define our own yywrap. */
53 _PROTOTYPE(int yywrap, (void));
56 /* Support for the BSD libedit with history for
57 nicer input on the interactive part of input. */
61 /* Have input call the following function. */
63 #define YY_INPUT(buf,result,max_size) \
64 bcel_input((char *)buf, &result, max_size)
66 /* Variables to help interface editline with bc. */
67 static const char *bcel_line = (char *)NULL;
68 static int bcel_len = 0;
71 /* Required to get rid of that ugly ? default prompt! */
73 null_prompt (EditLine *el)
79 /* bcel_input puts upto MAX characters into BUF with the number put in
80 BUF placed in *RESULT. If the yy input file is the same as
81 stdin, use editline. Otherwise, just read it.
85 bcel_input (buf, result, max)
90 if (!edit || yyin != stdin)
92 while ( (*result = read( fileno(yyin), buf, max )) < 0 )
95 yyerror( "read() in flex scanner failed" );
101 /* Do we need a new string? */
104 bcel_line = el_gets(edit, &bcel_len);
105 if (bcel_line == NULL) {
112 history (hist, &histev, H_ENTER, bcel_line);
118 strncpy (buf, bcel_line, bcel_len);
124 strncpy (buf, bcel_line, max);
133 /* Support for the readline and history libraries. This allows
134 nicer input on the interactive part of input. */
136 /* Have input call the following function. */
138 #define YY_INPUT(buf,result,max_size) \
139 rl_input((char *)buf, &result, max_size)
141 /* Variables to help interface readline with bc. */
142 static char *rl_line = (char *)NULL;
143 static char *rl_start = (char *)NULL;
144 static int rl_len = 0;
146 /* Definitions for readline access. */
147 extern FILE *rl_instream;
148 _PROTOTYPE(char *readline, (char *));
150 /* rl_input puts upto MAX characters into BUF with the number put in
151 BUF placed in *RESULT. If the yy input file is the same as
152 rl_instream (stdin), use readline. Otherwise, just read it.
156 rl_input (buf, result, max)
161 if (yyin != rl_instream)
163 while ( (*result = read( fileno(yyin), buf, max )) < 0 )
166 yyerror( "read() in flex scanner failed" );
172 /* Do we need a new string? */
177 rl_start = readline ("");
178 if (rl_start == NULL) {
185 rl_len = strlen (rl_line)+1;
187 add_history (rl_line);
188 rl_line[rl_len-1] = '\n';
194 strncpy (buf, rl_line, rl_len);
200 strncpy (buf, rl_line, max);
208 #if !defined(READLINE) && !defined(LIBEDIT)
210 /* MINIX returns from read with < 0 if SIGINT is encountered.
211 In flex, we can redefine YY_INPUT to the following. In lex, this
214 #define YY_INPUT(buf,result,max_size) \
215 while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
216 if (errno != EINTR) \
217 YY_FATAL_ERROR( "read() in flex scanner failed" );
229 yyerror ("illegal character: #");
231 <slcomment>[^\n]* { BEGIN(INITIAL); }
232 <slcomment>"\n" { line_no++; BEGIN(INITIAL); return(ENDOFLINE); }
233 define return(Define);
236 length return(Length);
237 return return(Return);
251 #if defined(READLINE) || defined(LIBEDIT)
254 yylval.s_value = strcopyof(yytext); return(NAME);
258 warranty return(Warranty);
259 continue return(Continue);
261 limits return(Limits);
266 yyerror ("illegal character: %s",yytext);
269 "+"|"-"|";"|"("|")"|"{"|"}"|"["|"]"|","|"^" { yylval.c_value = yytext[0];
270 return((int)yytext[0]); }
274 "*"|"/"|"%" { yylval.c_value = yytext[0]; return((int)yytext[0]); }
275 "="|\+=|-=|\*=|\/=|%=|\^= { yylval.c_value = yytext[0]; return(ASSIGN_OP); }
276 =\+|=-|=\*|=\/|=%|=\^ {
279 warn_save = warn_not_std;
281 warn ("Old fashioned =<op>");
282 warn_not_std = warn_save;
283 yylval.c_value = yytext[1];
285 yylval.c_value = '=';
290 ==|\<=|\>=|\!=|"<"|">" { yylval.s_value = strcopyof(yytext); return(REL_OP); }
291 \+\+|-- { yylval.c_value = yytext[0]; return(INCR_DECR); }
292 "\n" { line_no++; return(ENDOFLINE); }
293 \\\n { line_no++; /* ignore a "quoted" newline */ }
294 [ \t]+ { /* ignore spaces and tabs */ }
300 while ( ((c=input()) != '*') && (c != EOF))
302 if (c == '\n') line_no++;
305 while ( (c=input()) == '*') /* eat it*/;
306 if (c == '/') break; /* at end of comment */
307 if (c == '\n') line_no++;
311 fprintf (stderr,"EOF encountered in a comment.\n");
316 [a-z][a-z0-9_]* { yylval.s_value = strcopyof(yytext); return(NAME); }
320 yylval.s_value = strcopyof(yytext);
321 for (look = yytext; *look != 0; look++)
323 if (*look == '\n') line_no++;
324 if (*look == '"') count++;
326 if (count != 2) yyerror ("NUL character in string.");
329 {DIGIT}({DIGIT}|\\\n)*("."({DIGIT}|\\\n)*)?|"."(\\\n)*{DIGIT}({DIGIT}|\\\n)* {
330 unsigned char *src, *dst;
332 /* remove a trailing decimal point. */
333 len = strlen(yytext);
334 if (yytext[len-1] == '.')
336 /* remove leading zeros. */
339 while (*src == '0') src++;
340 if (*src == 0) src--;
341 /* Copy strings removing the newlines. */
353 yylval.s_value = strcopyof(yytext);
358 yyerror ("illegal character: ^%c",yytext[0] + '@');
361 yyerror ("illegal character: \\%03o", (int) yytext[0]);
363 yyerror ("illegal character: %s",yytext);
369 /* This is the way to get multiple files input into lex. */
374 if (!open_new_file ()) return (1); /* EOF on standard in. */
375 return (0); /* We have more input. */