home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / bc-1.03-base.tgz / bc-1.03-base.tar / fsf / bc / scan.l < prev    next >
Text File  |  1994-11-02  |  5KB  |  197 lines

  1. %{
  2. /* scan.l: the (f)lex description file for the scanner. */
  3.  
  4. /*  This file is part of bc written for MINIX.
  5.     Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License , or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.     You may contact the author by:
  22.        e-mail:  phil@cs.wwu.edu
  23.       us-mail:  Philip A. Nelson
  24.                 Computer Science Department, 9062
  25.                 Western Washington University
  26.                 Bellingham, WA 98226-9062
  27.        
  28. *************************************************************************/
  29.  
  30. #include "bcdefs.h"
  31. #include "y.tab.h"
  32. #include "global.h"
  33. #include "proto.h"
  34.  
  35. /* Using flex, we can ask for a smaller input buffer.  With lex, this
  36.    does nothing! */
  37.  
  38. #ifdef SMALL_BUF
  39. #undef YY_READ_BUF_SIZE
  40. #define YY_READ_BUF_SIZE 512
  41. #endif
  42.  
  43. /* We want to define our own yywrap. */
  44. #undef yywrap
  45. _PROTOTYPE(int yywrap, (void));
  46.  
  47. /* MINIX returns from read with < 0 if SIGINT is  encountered.
  48.    In flex, we can redefine YY_INPUT to the following.  In lex, this
  49.    does nothing! */
  50. #include <errno.h>
  51. #undef  YY_INPUT
  52. #define YY_INPUT(buf,result,max_size) \
  53.     while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
  54.         if (errno != EINTR) \
  55.         YY_FATAL_ERROR( "read() in flex scanner failed" );
  56.  
  57. %}
  58. DIGIT [0-9A-F]
  59. LETTER [a-z]
  60. %%
  61. define return(Define);
  62. break  return(Break);
  63. quit   return(Quit);
  64. length return(Length);
  65. return return(Return);
  66. for    return(For);
  67. if     return(If);
  68. while  return(While);
  69. sqrt   return(Sqrt);
  70. scale  return(Scale);
  71. ibase  return(Ibase);
  72. obase  return(Obase);
  73. auto   return(Auto);
  74. else   return(Else);
  75. read   return(Read);
  76. halt   return(Halt);
  77. last   return(Last);
  78. warranty return(Warranty);
  79. continue return(Continue);
  80. print  return(Print);
  81. limits return(Limits);
  82. "." {
  83. #ifdef DOT_IS_LAST
  84.        return(Last);
  85. #else
  86.        yyerror ("illegal character: %s",yytext);
  87. #endif
  88.     }
  89. "+"|"-"|";"|"("|")"|"{"|"}"|"["|"]"|","|"^" { yylval.c_value = yytext[0]; 
  90.                           return((int)yytext[0]); }
  91. && { return(AND); }
  92. \|\| { return(OR); }
  93. "!" { return(NOT); }
  94. "*"|"/"|"%" { yylval.c_value = yytext[0]; return(MUL_OP); }
  95. "="|\+=|-=|\*=|\/=|%=|\^=  { yylval.c_value = yytext[0]; return(ASSIGN_OP); }
  96. =\+|=-|=\*|=\/|=%|=\^  { 
  97. #ifdef OLD_EQ_OP
  98.              char warn_save;
  99.              warn_save = warn_not_std;
  100.              warn_not_std = TRUE;
  101.              warn ("Old fashioned =<op>");
  102.              warn_not_std = warn_save;
  103.              yylval.c_value = yytext[1];
  104. #else
  105.              yylval.c_value = '=';
  106.              yyless (1);
  107. #endif
  108.              return(ASSIGN_OP);
  109.                }
  110. ==|\<=|\>=|\!=|"<"|">" { yylval.s_value = strcopyof(yytext); return(REL_OP); }
  111. \+\+|-- { yylval.c_value = yytext[0]; return(INCR_DECR); }
  112. "\n" { line_no++; return(NEWLINE); }
  113. \\\n {  line_no++;  /* ignore a "quoted" newline */ }
  114. [ \t]+  { /* ignore spaces and tabs */ }
  115. "/*"  {
  116.     int c;
  117.  
  118.     for (;;)
  119.       {
  120.         while ( ((c=input()) != '*') && (c != EOF)) 
  121.           /* eat it */
  122.           if (c == '\n') line_no++;
  123.         if (c == '*')
  124.            {
  125.         while ( (c=input()) == '*') /* eat it*/;
  126.         if (c == '/') break; /* at end of comment */
  127.         if (c == '\n') line_no++;
  128.           }
  129.         if (c == EOF)
  130.           {
  131.         fprintf (stderr,"EOF encountered in a comment.\n");
  132.         break;
  133.           }
  134.       }
  135.       }
  136. [a-z][a-z0-9_]* { yylval.s_value = strcopyof(yytext); return(NAME); }
  137. \"[^\"]*\"  {
  138.            unsigned char *look;
  139.           int count = 0;
  140.           yylval.s_value = strcopyof(yytext);
  141.           for (look = yytext; *look != 0; look++)
  142.         {
  143.           if (*look == '\n') line_no++;
  144.           if (*look == '"')  count++;
  145.         }
  146.           if (count != 2) yyerror ("NUL character in string.");
  147.           return(STRING);
  148.         }
  149. {DIGIT}({DIGIT}|\\\n)*("."({DIGIT}|\\\n)*)?|"."(\\\n)*{DIGIT}({DIGIT}|\\\n)* {
  150.           unsigned char *src, *dst;
  151.           int len;
  152.           /* remove a trailing decimal point. */
  153.           len = strlen(yytext);
  154.           if (yytext[len-1] == '.')
  155.             yytext[len-1] = 0;
  156.           /* remove leading zeros. */
  157.           src = yytext;
  158.           dst = yytext;
  159.           while (*src == '0') src++;
  160.           if (*src == 0) src--;
  161.           /* Copy strings removing the newlines. */
  162.           while (*src != 0)
  163.         {
  164.               if (*src == '\\')
  165.             {
  166.               src++; src++;
  167.               line_no++;
  168.             }
  169.           else
  170.             *dst++ = *src++;
  171.             }
  172.           *dst = 0;
  173.           yylval.s_value = strcopyof(yytext); 
  174.           return(NUMBER);
  175.         }
  176. .       {
  177.       if (yytext[0] < ' ')
  178.         yyerror ("illegal character: ^%c",yytext[0] + '@');
  179.       else
  180.         if (yytext[0] > '~')
  181.           yyerror ("illegal character: \\%3d", (int) yytext[0]);
  182.         else
  183.           yyerror ("illegal character: %s",yytext);
  184.     }
  185. %%
  186.  
  187.  
  188.  
  189. /* This is the way to get multiple files input into lex. */
  190.  
  191. int
  192. yywrap()
  193. {
  194.   if (!open_new_file ()) return (1);    /* EOF on standard in. */
  195.   return (0);                /* We have more input. */
  196. }
  197.