home *** CD-ROM | disk | FTP | other *** search
- %{
- /*
- * NAME
- * lexer.l -- source for the C-INTERCAL lexical analyzer.
- *
- LICENSE TERMS
- Copyright (C) 1996 Eric S. Raymond
-
- 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; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <memory.h>
- #include "ick.h"
- #include "y.tab.h"
- #include "lose.h"
-
- #define YY_NO_UNPUT
-
- #ifndef yywrap
- static int yywrap(void)
- {
- return 1;
- }
- #endif /* yywrap */
-
- #ifdef YYLINENO_BY_HAND
- int yylineno = 1;
- #endif /* YYLINENO_BY_HAND */
-
- #ifdef MAIN
- YYSTYPE yylval;
- #endif /* MAIN */
-
- char *textlines[MAXLINES];
- int politesse = 0;
- int stbeginline = 0;
-
- #ifdef FLEX_SCANNER
- static char linebuf[YY_BUF_SIZE];
- #else /* FLEX_SCANNER */
- static char linebuf[YYLMAX];
- #endif /* FLEX_SCANNER */
-
- static char *lineptr = linebuf;
-
- bool re_send_token = FALSE;
-
- int lexer(void);
- static int myatoi(char *text);
-
- #define SETLINENO \
- {if (stbeginline == 0) stbeginline = yylineno; \
- else if (stbeginline < 0) stbeginline = 0;}
-
- /*
- * The spectacular ugliness of INTERCAL syntax requires that the lexical
- * analyzer have two levels. One, embedded in the getc() function, handles
- * logical-line continuation and the ! abbrev, and stashes each logical
- * line away in a buffer accessible to the code generator (this is necessary
- * for the * construct to be interpreted correctly). The upper level is
- * generated by lex(1) and does normal tokenizing.
- */
-
- #undef getc(s)
- int getc(FILE *fp)
- {
- extern FILE* yyin;
-
- static bool bangflag = FALSE;
- static bool backflag = FALSE;
-
- if (bangflag)
- {
- bangflag = FALSE;
- /* *lineptr++ = '!'; */
- return('.');
- }
- else if (backflag) /* converting ctrl-H (backspace) to two chars "^H" */
- {
- backflag = FALSE;
- /* *lineptr++ = '\010'; */
- return('H');
- }
- else
- {
- int c = fgetc(fp);
-
- if (feof(yyin))
- {
- *lineptr = '\0';
- return(EOF);
- }
- #ifdef BACKSLASH_CONTINUATION
- else if (c == '\\')
- {
- do {
- c = fgetc(fp);
- #ifdef YYLINENO_BY_HAND
- if( c == '\n' ) yylineno++;
- #endif /* YYLINENO_BY_HAND */
- } while
- (c != '\\' && isspace(c));
- }
- #endif /* BACKSLASH_CONTINUATION */
- if (c == '!')
- {
- *lineptr++ = '!';
- bangflag = TRUE;
- return(c = '\'');
- }
- else if (c == '\010') /* convert ctrl-H (backspace) to
- two chars "^" and "H" so lex can take it */
- {
- *lineptr++ = '\010';
- backflag = TRUE;
- return(c = '^');
- }
- else if (c == '\n')
- {
- *lineptr = '\0';
- lineptr = linebuf;
- textlines[yylineno] = strcpy((char *)malloc(1+strlen(linebuf)),linebuf);
- #ifdef YYLINENO_BY_HAND
- yylineno++;
- #endif /* YYLINENO_BY_HAND */
- return('\n');
- }
- else
- {
- #ifdef ACCEPT_LOWERCASE
- if (islower(c))
- c = toupper(c);
- #endif /* ACCEPT_LOWERCASE */
- return(*lineptr++ = c);
- }
- }
- }
-
- /* replace YY_INPUT so that it uses our getc function. */
- #undef YY_INPUT
- #define YY_INPUT(buf,result,max_size) \
- { \
- int c = getc(yyin); \
- if (c == EOF) { \
- if (ferror(yyin)) \
- YY_FATAL_ERROR("input in flex scanner failed"); \
- result = YY_NULL; \
- } else { \
- buf[0] = c; \
- result = 1; \
- } \
- }
-
- %}
-
- W [\ \t\n]*
- D [0-9][\ \t\n0-9]*
-
- %%
-
- {D} {yylval.numval = myatoi(yytext); return(NUMBER);}
- \. {return(ONESPOT);}
- \: {return(TWOSPOT);}
- \, {return(TAIL);}
- \; {return(HYBRID);}
- \# {return(MESH);}
-
- \$ {return(MINGLE);}
- \~ {return(SELECT);}
-
- \& {yylval.numval = AND; return(UNARY);}
- V {yylval.numval = OR; return(UNARY);}
- "V^H-" |
- \? {yylval.numval = XOR; return(UNARY);}
- \^ {yylval.numval = FIN; return(UNARY);}
- @ {yylval.numval = WHIRL; return(UNARY);}
- [2-5]{W}@ {yylval.numval = WHIRL + myatoi(yytext) - 1; return(UNARY);}
-
- \' {return(SPARK);}
- \" {return(EARS);}
-
- \({W}{D}\) {SETLINENO; yylval.numval = myatoi(yytext); return(LABEL);}
-
- DO {SETLINENO; return(DO);}
- PLEASE {SETLINENO; politesse++; return(DO);}
- DO{W}PLEASE {SETLINENO; politesse++; return(DO);}
- PLEASE{W}DO {SETLINENO; politesse++; return(DO);}
- NOT {return(NOT);}
- N\'T {return(NOT);}
-
- \%{W}{D} {yylval.numval = myatoi(yytext);
- if (yylval.numval && yylval.numval < 100)
- return(OHOHSEVEN);
- else
- lose(E017, yylineno, (char *)NULL);}
- SUB {return(SUB);}
- BY {return(BY);}
-
- \<- {return(GETS);}
- CALCULATING {yylval.numval = GETS; return(GERUND);}
-
- NEXT {stbeginline = 0; return(NEXT);}
- NEXTING {yylval.numval = NEXT; return(GERUND);}
- FORGET {return(FORGET);}
- FORGETTING {yylval.numval = FORGET; return(GERUND);}
- RESUME {return(RESUME);}
- RESUMING {yylval.numval = RESUME; return(GERUND);}
- STASH {return(STASH);}
- STASHING {yylval.numval = STASH; return(GERUND);}
- RETRIEVE {return(RETRIEVE);}
- RETRIEVING {yylval.numval = RETRIEVE; return(GERUND);}
- IGNORE {return(IGNORE);}
- IGNORING {yylval.numval = IGNORE; return(GERUND);}
- REMEMBER {return(REMEMBER);}
- REMEMBERING {yylval.numval = REMEMBER; return(GERUND);}
- ABSTAIN{W}FROM {return(ABSTAIN);}
- ABSTAINING {yylval.numval = ABSTAIN; return(GERUND);}
- REINSTATE {return(REINSTATE);}
- REINSTATING {yylval.numval = REINSTATE; return(GERUND);}
- READ{W}OUT {return(READ_OUT);}
- READING{W}OUT {yylval.numval = READ_OUT; return(GERUND);}
- WRITE{W}IN {return(WRITE_IN);}
- WRITING{W}IN {yylval.numval = WRITE_IN; return(GERUND);}
- COME{W}FROM {stbeginline = -stbeginline; return(COME_FROM);}
- COMING{W}FROM {yylval.numval = COME_FROM; return(GERUND);}
- GIVE{W}UP {return(GIVE_UP);}
-
- \+ {return(INTERSECTION);}
-
- {W} ;
- . {yylval.numval = yytext[0]; return(BADCHAR);}
-
-
- %%
-
- int lexer(void)
- {
- static int tok = BADCHAR;
-
- if (re_send_token)
- re_send_token = FALSE;
- else
- {
- tok = yylex();
- #ifdef YYDEBUG
- if (yydebug)
- (void) fprintf(stdout, "yylex: returning token %d\n", tok);
- #endif /* YYDEBUG */
- }
-
- #ifdef YYDEBUG
- if (yydebug)
- (void) fprintf(stdout, "lexer: returning token %d\n", tok);
- #endif /* YYDEBUG */
- return(tok);
- }
-
- static int myatoi(char *text)
- {
- #define MAXTEXT 100
- static char buf[MAXTEXT];
- register int i;
-
- for(buf[i = 0] = '\0';*text && i < MAXTEXT;text++) {
- if(isdigit(*text)) {
- buf[i++] = *text;
- }
- }
- buf[i] = '\0';
- return atoi(buf);
- }
-
- void yyerror(char *errtype)
- {
- #ifdef MAIN
- (void) printf("lextest: lexer error: %s.\n", errtype);
- #else /* MAIN */
- /* lose(E017, yylineno, (char *)NULL); */
- (void) errtype;
- #endif /* MAIN */
- }
-
- #ifdef MAIN
- int main(void)
- {
- int t;
-
- while ((t = yylex()) > 0)
- {
- (void) printf("%03d %09d\n", t, yylval.numval);
- yylval.numval = 0;
- }
- return 0;
- }
- #endif /* MAIN */