From:	HENRY::IN%"info-ada-request%ada20.isi.edu%ada20.isi.edu%csnet-relay.CSNET%relay.cs.net@RCA.COM" 27-SEP-1987 06:39
To:	info-ada@ada20.isi.edu
Subj:	Ada YACC & LEX (Part 3 of 3)


%{
/*------------------------------------------------------------------------*/
/* Lexical input for LEX for LALR(1) Grammar for ANSI Ada                 */
/*                                                                        */
/*              Herman Fischer                                            */
/*            Litton Data Systems                                         */
/*              March 26, 1984                                            */
/*                                                                        */
/* Rewrite:  To a version that a non-supercomputer can handle (8^) by:	  */
/*           Jeff Wabik, Control Data Corporation, September 1987	  */ 
/*	     { umn-cs!shamash!jwabik }				 	  */
/*                                                                        */
/*------------------------------------------------------------------------*/
#include "y.tab.h"
#include <stdio.h>
#include <ctype.h>

#define Token(a)	(int)a

%}

StringLetter		([^\n']|'')
WS			([\t\n ])
Word			([^\n^ ^\t']|'')

%START IDENT Z

%%
"--".*  ECHO;       		/* ignore comments to end-of-line */
[\ \t\n]		ECHO;  	/* ignore spaces and tabs */
"=>"    		{ECHO; BEGIN Z; return(ARROW_);}
".."    		{ECHO; BEGIN Z; return(DBLDOT_);}
"**"    		{ECHO; BEGIN Z; return(EXP_);}
":="    		{ECHO; BEGIN Z; return(ASSIGN_);}
"/="    		{ECHO; BEGIN Z; return(NOTEQL_);}
">="    		{ECHO; BEGIN Z; return(GTEQL_);}
"<="    		{ECHO; BEGIN Z; return(LTEQ_);}
"<<"    		{ECHO; BEGIN Z; return(L_LBL_);}
">>"    		{ECHO; BEGIN Z; return(R_LBL_);}
"<>"    		{ECHO; BEGIN Z; return(BOX_);}
"&"     		{ECHO; BEGIN Z; return('&'); }
"("     		{ECHO; BEGIN Z; return('('); }
")"     		{ECHO; BEGIN IDENT; return(')'); }
"*"     		{ECHO; BEGIN Z; return('*'); }
"+"     		{ECHO; BEGIN Z; return('+'); }
","     		{ECHO; BEGIN Z; return(','); }
"-"     		{ECHO; BEGIN Z; return('-'); }
"."     		{ECHO; BEGIN Z; return('.'); }
"/"     		{ECHO; BEGIN Z; return('/'); }
":"     		{ECHO; BEGIN Z; return(':'); }
";"     		{ECHO; BEGIN Z; return(';'); }
"<"     		{ECHO; BEGIN Z; return('<'); }
"="     		{ECHO; BEGIN Z; return('='); }
">"     		{ECHO; BEGIN Z; return('>'); }
"|"     		{ECHO; BEGIN Z; return('|'); }
<IDENT>\'  		{ECHO; BEGIN Z; return('\'');}   /* type mark only */


[a-z_A-Z][a-z_A-Z0-9]*  	{ ECHO; BEGIN IDENT; return(LookUp(yytext));}

[0-9][0-9_]*([.][0-9_]+)?([Ee][-+]?[0-9_]+)?  
				{ ECHO; BEGIN Z; return(NUMERIC_LITERAL);}

[0-9][0-9_]*#[0-9a-fA-F_]+([.][0-9a-fA-F_]+)?#([Ee][-+]?[0-9_]+)? 
				{ ECHO; BEGIN Z; return(NUMERIC_LITERAL);}


\"([^"]*(\"\")*)*\" 		{ECHO; BEGIN Z; return(STRING_LITERAL);}

<Z>\'([^']|\'\')\'    		{ECHO; BEGIN Z; return(CHARACTER_LITERAL);}


.       			{ECHO; 
				 printf("Syntax error \"%s\" at line %d.\n\t",
					 yytext,yylineno); }
%%

typedef struct token_struct {
   char *token;
   int tokval;
} TOKEN;

yywrap() {
	return(1);
}

LookUp(key) 
char *key; 
/*
	 Compare what was just read in by LEX to the literal form
	 of the reserved word..  If its OK, return the TOKEN of the 
	 reserved word, else return the IDENTIFIER token.
*/
{
	 TOKEN *tokpnt;
	 extern TOKEN tokens[];
	 extern unsigned num_tokens;
	 int TokenCmp();
	 extern char *MakeUpper();

	 if ((tokpnt = (TOKEN *)bsearch(MakeUpper(key), tokens,num_tokens,
	      sizeof(TOKEN), TokenCmp)) != NULL)
	    return(tokpnt->tokval);
	 else {
	    yylval.y_str = (char *) calloc(strlen(yytext)+1,sizeof(char));
	    strcpy(yylval.y_str,yytext);
	    return(IDENTIFIER);
	 }
}

int TokenCmp(str,tab_ele)
char str[];
TOKEN *tab_ele;
{
	 return(strcmp(str,tab_ele->token));
}

char *MakeUpper(str)
char str[];
{

	 register int i;
	 static char up_str[256];

	 for (i=0; str[i] != '\0'; i++)
	    if (islower(str[i]))
	       up_str[i] = toupper(str[i]);
	    else
	       up_str[i] = str[i];
	 up_str[i] = '\0';
	 return up_str;
}

TOKEN tokens[] = {
   "ABORT", Token(ABORT_),
   "ABS", Token(ABS_),
   "ACCEPT", Token(ACCEPT_),
   "ACCESS", Token(ACCESS_),
   "ALL", Token(ALL_),
   "AND", Token(AND_),
   "ARRAY", Token(ARRAY_),
   "AT", Token(AT_),
   "BEGIN", Token(BEGIN_),
   "BODY", Token(BODY_),
   "CASE", Token(CASE_),
   "CONSTANT", Token(CONSTANT_),
   "DECLARE", Token(DECLARE_),
   "DELAY", Token(DELAY_),
   "DELTA", Token(DELTA_),
   "DIGITS", Token(DIGITS_),
   "DO", Token(DO_),
   "ELSE", Token(ELSE_),
   "ELSIF", Token(ELSIF_),
   "END", Token(END_),
   "ENTRY", Token(ENTRY_),
   "EXCEPTION", Token(EXCEPTION_),
   "EXIT", Token(EXIT_),
   "FOR", Token(FOR_),
   "FUNCTION", Token(FUNCTION_),
   "GENERIC", Token(GENERIC_),
   "GOTO", Token(GOTO_),
   "IF", Token(IF_),
   "IN", Token(IN_),
   "IS", Token(IS_),
   "LIMITED", Token(LIMITED_),
   "LOOP", Token(LOOP_),
   "MOD", Token(MOD_),
   "NEW", Token(NEW_),
   "NOT", Token(NOT_),
   "NULL", Token(NULL_),
   "OF", Token(OF_),
   "OR", Token(OR_),
   "OTHERS", Token(OTHERS_),
   "OUT", Token(OUT_),
   "PACKAGE", Token(PACKAGE_),
   "PRAGMA", Token(PRAGMA_),
   "PRIVATE", Token(PRIVATE_),
   "PROCEDURE", Token(PROCEDURE_),
   "RAISE", Token(RAISE_),
   "RANGE", Token(RANGE_),
   "RECORD", Token(RECORD_),
   "REM", Token(REM_),
   "RENAMES", Token(RENAMES_),
   "RETURN", Token(RETURN_),
   "REVERSE", Token(REVERSE_),
   "SELECT", Token(SELECT_),
   "SEPARATE", Token(SEPARATE_),
   "SUBTYPE", Token(SUBTYPE_),
   "TASK", Token(TASK_),
   "TERMINATE", Token(TERMINATE_),
   "THEN", Token(THEN_),
   "TYPE", Token(TYPE_),
   "USE", Token(USE_),
   "WHEN", Token(WHEN_),
   "WHILE", Token(WHILE_),
   "WITH", Token(WITH_),
   "XOR", Token(XOR_),
};

unsigned num_tokens = sizeof(tokens)/sizeof(TOKEN);
