home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / ae / AEC / scanner.l < prev    next >
Encoding:
Text File  |  1990-02-28  |  4.9 KB  |  193 lines

  1. /* lex (flex) file for AEC, the AE Compiler.
  2.    Lexical analyzer that recognizes the keywords in a schema file.
  3.  
  4.    Copyright (C) 1989, 1990 by James R. Larus (larus@cs.wisc.edu)
  5.  
  6.    NB Must preprocess with cpp -P before giving to lex so that keyword names,
  7.    which are #defines, are expanded.
  8.  
  9.  
  10.    AE and AEC are free software; you can redistribute it and/or modify it
  11.    under the terms of the GNU General Public License as published by the
  12.    Free Software Foundation; either version 1, or (at your option) any
  13.    later version.
  14.  
  15.    AE and AEC are distributed in the hope that it will be useful, but
  16.    WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18.    General Public License for more details.
  19.  
  20.    You should have received a copy of the GNU General Public License
  21.    along with GNU CC; see the file COPYING.  If not, write to James R.
  22.    Larus, Computer Sciences Department, University of Wisconsin--Madison,
  23.    1210 West Dayton Street, Madison, WI 53706, USA or to the Free
  24.    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  25.  
  26. /* $Header: /var/home/larus/AE/AEC/RCS/scanner.l,v 2.0 90/02/09 17:23:48 larus Exp Locker: larus $ */
  27.  
  28.  
  29. #include "schema.h"
  30. #include "y.tab.h"
  31.  
  32. %{
  33. extern int yylval;
  34.  
  35. /* Keep track of which line we are reading and where it began. */
  36.  
  37. int line_no = 1;
  38.  
  39. char *line_start = NULL;
  40.  
  41. char *remove_periods ();
  42.  
  43. #define TOKEN(x) {line_start = yytext; return (x);}
  44.  
  45. %}
  46.  
  47. %%
  48.  
  49. FUNCTION_START        {TOKEN (Y_FUNCTION_START);};
  50. FUNCTION_END        {TOKEN (Y_FUNCTION_END);};
  51.  
  52. BLOCK_START        {TOKEN (Y_BLOCK_START);};
  53. BLOCK_START_TARGET    {TOKEN (Y_BLOCK_START_TARGET);};
  54.  
  55. BLOCK_END        {TOKEN (Y_BLOCK_END);};
  56. BLOCK_END_NEXT_TARGET    {TOKEN (Y_BLOCK_END_NEXT_TARGET);};
  57. BLOCK_END_JUMP        {TOKEN (Y_BLOCK_END_JUMP);};
  58. BLOCK_END_JUMP_NEXT_TARGET    {TOKEN (Y_BLOCK_END_JUMP_NEXT_TARGET);};
  59. BLOCK_END_CJUMP        {TOKEN (Y_BLOCK_END_CJUMP);};
  60.  
  61. LOOP_ENTRY        {TOKEN (Y_LOOP_ENTRY);};
  62. LOOP_BACK        {TOKEN (Y_LOOP_BACK);};
  63. LOOP_EXIT        {TOKEN (Y_LOOP_EXIT);};
  64.  
  65. UNEVENTFUL_INST        {TOKEN (Y_UNEVENTFUL_INST);};
  66.  
  67. STORE_INST        {TOKEN (Y_STORE_INST);};
  68. STORE_D_INST        {TOKEN (Y_STORE_D_INST);};
  69. STORE_UNKNOWN_INST    {TOKEN (Y_STORE_UNKNOWN_INST);};
  70.  
  71. LOAD_INST        {TOKEN (Y_LOAD_INST);};
  72. LOAD_D_INST        {TOKEN (Y_LOAD_D_INST);};
  73. LOAD_UNKNOWN_INST    {TOKEN (Y_LOAD_UNKNOWN_INST);};
  74.  
  75. COMPUTE_DEFN_0        {TOKEN (Y_COMPUTE_DEFN_0);};
  76. COMPUTE_DEFN_1        {TOKEN (Y_COMPUTE_DEFN_1);};
  77. COMPUTE_DEFN_2        {TOKEN (Y_COMPUTE_DEFN_2);};
  78. UNKNOWN_DEFN        {TOKEN (Y_UNKNOWN_DEFN);};
  79.  
  80. CALL_INST        {TOKEN (Y_CALL_INST);};
  81. CALL_INDIRECT_INST    {TOKEN (Y_CALL_INDIRECT_INST);};
  82.  
  83.  
  84. [ \t]            ;
  85.  
  86. [\n]            {return (Y_NL);}
  87.  
  88. (-[0-9]+)|([0-9]+)    {yylval = atoi (yytext);
  89.              if (line_start == NULL) line_start = yytext;
  90.              return (Y_INT);};
  91.  
  92. R[0-9]+            {yylval = atoi (yytext + 1);
  93.              return (Y_REG);};
  94.  
  95. [a-zA-Z_.][a-zA-Z0-9_.]*    {yylval = (int) remove_periods (yytext);
  96.              if (line_start == NULL) line_start = yytext;
  97.              return (Y_ID);};
  98.  
  99. "#"[a-zA-Z0-9_.-]*    {yylval = strcpy (malloc (strlen (yytext) + 1),
  100.                       yytext);
  101.              return (Y_LIT);};
  102.  
  103. "-"|[+*/%&|~]|"<<"|">>"    {yylval = strcpy (malloc (strlen (yytext) + 1),
  104.                       yytext);
  105.              return (Y_OP);};
  106.  
  107. "("            {return (Y_LPAREN);};
  108. ")"            {return (Y_RPAREN);};
  109.  
  110. %%
  111.  
  112. void
  113. initialize_scanner (in_file)
  114.      FILE *in_file;
  115. {
  116.   yyin = in_file;
  117. #ifdef FLEX_SCANNER
  118.   yy_init = 1;
  119. #endif
  120.   line_no = 1;
  121.   line_start = NULL;
  122. }
  123.  
  124.  
  125. #ifndef FLEX_SCANNER
  126. /* We don't use -ll */
  127. int yywrap () {return 1;}
  128. #endif
  129.  
  130.  
  131. /* When the parser has successfully parsed a line, step these
  132.    counters.  They are driven by the parser since they are used to report
  133.    parser error messages. */
  134.  
  135. void
  136. scanner_nl ()
  137. {
  138.   line_no ++;
  139.   line_start = yytext + 1;
  140. }
  141.  
  142.  
  143. /* On a parse error, write out the current line and print a caret (^)
  144.    below the point at which the error occured.  Also, reset input stream
  145.    to begining of next line. */
  146.  
  147. void
  148. print_erroneous_line (err_file)
  149.      FILE *err_file;
  150. {
  151.   int prefix_length = yytext - line_start;
  152.   int i, c;
  153.  
  154.   fprintf (err_file, "    ");
  155.   fwrite (line_start, sizeof (char), prefix_length, err_file);
  156.   fprintf (err_file, "%s", yytext);
  157.  
  158.   /* Flush the rest of the line. */
  159.   if (*yytext != '\n')
  160.     {
  161.       while ((c = input ()) != '\n' && c != EOF) fputc (c, err_file);
  162.       fputc ('\n', err_file);
  163.     }
  164.  
  165.   fprintf (err_file, "    ");
  166.   for (i = 0; i < prefix_length; i ++) fputc (' ', err_file);
  167.   fprintf (err_file, "^\n");
  168. }
  169.  
  170.  
  171. /* Some implementation build internal names with periods.  These names are
  172.    invalid identifiers in C (since dot is a structure selector).  Translate
  173.    a period to _DoT_. */
  174.  
  175. static char *
  176. remove_periods (str)
  177.      char *str;
  178. {
  179.   int num_dots = 0;
  180.   register char *s, *new_str, *n, *x;
  181.  
  182.   for (s = str; *s != '\0'; s ++) if (*s == '.') num_dots += 1;
  183.   new_str = (char *) malloc (strlen (str) + 1 + 5 * num_dots);
  184.   for (s = str, n = new_str; *s != '\0'; s ++)
  185.     if (*s == '.')
  186.       for (x = "_DoT_"; *x != '\0'; ) *n ++ = *x ++;
  187.     else
  188.       *n ++ = *s;
  189.  
  190.   *n = '\0';
  191.   return (new_str);
  192. }
  193.