home *** CD-ROM | disk | FTP | other *** search
- /* lex (flex) file for AEC, the AE Compiler.
- Lexical analyzer that recognizes the keywords in a schema file.
-
- Copyright (C) 1989, 1990 by James R. Larus (larus@cs.wisc.edu)
-
- NB Must preprocess with cpp -P before giving to lex so that keyword names,
- which are #defines, are expanded.
-
-
- AE and AEC are 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 1, or (at your option) any
- later version.
-
- AE and AEC are 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 GNU CC; see the file COPYING. If not, write to James R.
- Larus, Computer Sciences Department, University of Wisconsin--Madison,
- 1210 West Dayton Street, Madison, WI 53706, USA or to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* $Header: /var/home/larus/AE/AEC/RCS/scanner.l,v 2.0 90/02/09 17:23:48 larus Exp Locker: larus $ */
-
-
- #include "schema.h"
- #include "y.tab.h"
-
- %{
- extern int yylval;
-
- /* Keep track of which line we are reading and where it began. */
-
- int line_no = 1;
-
- char *line_start = NULL;
-
- char *remove_periods ();
-
- #define TOKEN(x) {line_start = yytext; return (x);}
-
- %}
-
- %%
-
- FUNCTION_START {TOKEN (Y_FUNCTION_START);};
- FUNCTION_END {TOKEN (Y_FUNCTION_END);};
-
- BLOCK_START {TOKEN (Y_BLOCK_START);};
- BLOCK_START_TARGET {TOKEN (Y_BLOCK_START_TARGET);};
-
- BLOCK_END {TOKEN (Y_BLOCK_END);};
- BLOCK_END_NEXT_TARGET {TOKEN (Y_BLOCK_END_NEXT_TARGET);};
- BLOCK_END_JUMP {TOKEN (Y_BLOCK_END_JUMP);};
- BLOCK_END_JUMP_NEXT_TARGET {TOKEN (Y_BLOCK_END_JUMP_NEXT_TARGET);};
- BLOCK_END_CJUMP {TOKEN (Y_BLOCK_END_CJUMP);};
-
- LOOP_ENTRY {TOKEN (Y_LOOP_ENTRY);};
- LOOP_BACK {TOKEN (Y_LOOP_BACK);};
- LOOP_EXIT {TOKEN (Y_LOOP_EXIT);};
-
- UNEVENTFUL_INST {TOKEN (Y_UNEVENTFUL_INST);};
-
- STORE_INST {TOKEN (Y_STORE_INST);};
- STORE_D_INST {TOKEN (Y_STORE_D_INST);};
- STORE_UNKNOWN_INST {TOKEN (Y_STORE_UNKNOWN_INST);};
-
- LOAD_INST {TOKEN (Y_LOAD_INST);};
- LOAD_D_INST {TOKEN (Y_LOAD_D_INST);};
- LOAD_UNKNOWN_INST {TOKEN (Y_LOAD_UNKNOWN_INST);};
-
- COMPUTE_DEFN_0 {TOKEN (Y_COMPUTE_DEFN_0);};
- COMPUTE_DEFN_1 {TOKEN (Y_COMPUTE_DEFN_1);};
- COMPUTE_DEFN_2 {TOKEN (Y_COMPUTE_DEFN_2);};
- UNKNOWN_DEFN {TOKEN (Y_UNKNOWN_DEFN);};
-
- CALL_INST {TOKEN (Y_CALL_INST);};
- CALL_INDIRECT_INST {TOKEN (Y_CALL_INDIRECT_INST);};
-
-
- [ \t] ;
-
- [\n] {return (Y_NL);}
-
- (-[0-9]+)|([0-9]+) {yylval = atoi (yytext);
- if (line_start == NULL) line_start = yytext;
- return (Y_INT);};
-
- R[0-9]+ {yylval = atoi (yytext + 1);
- return (Y_REG);};
-
- [a-zA-Z_.][a-zA-Z0-9_.]* {yylval = (int) remove_periods (yytext);
- if (line_start == NULL) line_start = yytext;
- return (Y_ID);};
-
- "#"[a-zA-Z0-9_.-]* {yylval = strcpy (malloc (strlen (yytext) + 1),
- yytext);
- return (Y_LIT);};
-
- "-"|[+*/%&|~]|"<<"|">>" {yylval = strcpy (malloc (strlen (yytext) + 1),
- yytext);
- return (Y_OP);};
-
- "(" {return (Y_LPAREN);};
- ")" {return (Y_RPAREN);};
-
- %%
-
- void
- initialize_scanner (in_file)
- FILE *in_file;
- {
- yyin = in_file;
- #ifdef FLEX_SCANNER
- yy_init = 1;
- #endif
- line_no = 1;
- line_start = NULL;
- }
-
-
- #ifndef FLEX_SCANNER
- /* We don't use -ll */
- int yywrap () {return 1;}
- #endif
-
-
- /* When the parser has successfully parsed a line, step these
- counters. They are driven by the parser since they are used to report
- parser error messages. */
-
- void
- scanner_nl ()
- {
- line_no ++;
- line_start = yytext + 1;
- }
-
-
- /* On a parse error, write out the current line and print a caret (^)
- below the point at which the error occured. Also, reset input stream
- to begining of next line. */
-
- void
- print_erroneous_line (err_file)
- FILE *err_file;
- {
- int prefix_length = yytext - line_start;
- int i, c;
-
- fprintf (err_file, " ");
- fwrite (line_start, sizeof (char), prefix_length, err_file);
- fprintf (err_file, "%s", yytext);
-
- /* Flush the rest of the line. */
- if (*yytext != '\n')
- {
- while ((c = input ()) != '\n' && c != EOF) fputc (c, err_file);
- fputc ('\n', err_file);
- }
-
- fprintf (err_file, " ");
- for (i = 0; i < prefix_length; i ++) fputc (' ', err_file);
- fprintf (err_file, "^\n");
- }
-
-
- /* Some implementation build internal names with periods. These names are
- invalid identifiers in C (since dot is a structure selector). Translate
- a period to _DoT_. */
-
- static char *
- remove_periods (str)
- char *str;
- {
- int num_dots = 0;
- register char *s, *new_str, *n, *x;
-
- for (s = str; *s != '\0'; s ++) if (*s == '.') num_dots += 1;
- new_str = (char *) malloc (strlen (str) + 1 + 5 * num_dots);
- for (s = str, n = new_str; *s != '\0'; s ++)
- if (*s == '.')
- for (x = "_DoT_"; *x != '\0'; ) *n ++ = *x ++;
- else
- *n ++ = *s;
-
- *n = '\0';
- return (new_str);
- }
-