home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
awk
/
awk320sr.zip
/
AWKLEX.L
< prev
next >
Wrap
Text File
|
1991-04-25
|
7KB
|
281 lines
%{
/*
* Awk lexical analyser
*
* Copyright (C) 1988, 1989, 1990, 1991 by Rob Duff
* All rights reserved
*/
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <alloc.h>
#include "awk.h"
#include "awklex.h"
#include "awkyacc.h"
#undef input
#pragma warn-rch
int input(void);
struct func {
char *name;
char type, code;
} *funcp, func[] = {
0,0,0
};
static int comment(void);
static void string(int);
static void newline(void);
static void eatspace(void);
%}
%%
"\\\n" ;
[ \t] eatspace();
'\n' {
newline();
return T_EOL;
}
'#' {
comment();
newline();
return T_EOL;
}
"BEGIN" return T_BEGIN;
"END" return T_END;
"if" return T_IF;
"in" return T_IN;
"do" return T_DO;
"for" return T_FOR;
"else" return T_ELSE;
"while" return yydone?T_DONE:T_WHILE;
"break" return T_BREAK;
"continue" return T_CONTINUE;
"function" return T_FUNCTION;
"return" return T_RETURN;
"next" return T_NEXT;
"exit" return T_EXIT;
"close" return T_CLOSE;
"print" return T_PRINT;
"printf" return T_PRINTF;
"getline" return T_GETLINE;
"delete" return T_DELETE;
"index" return T_INDEX;
"match" return T_MATCH;
"split" return T_SPLIT;
"substr" return T_SUBSTR;
"sprintf" return T_SPRINTF;
"srand" return T_SRAND;
"sub" { yylval.ival = P_LSUB; return T_SUB; }
"gsub" { yylval.ival = P_GSUB; return T_SUB; }
"rand" { yylval.ival = C_RAND; return T_FUNC0; }
"system" { yylval.ival = C_SYS; return T_FUNC1; }
"length" { yylval.ival = C_LEN; return T_FUNC1; }
"toupper" { yylval.ival = C_UPR; return T_FUNC1; }
"tolower" { yylval.ival = C_LWR; return T_FUNC1; }
"cos" { yylval.ival = C_COS; return T_FUNC1; }
"exp" { yylval.ival = C_EXP; return T_FUNC1; }
"int" { yylval.ival = C_INT; return T_FUNC1; }
"log" { yylval.ival = C_LOG; return T_FUNC1; }
"sin" { yylval.ival = C_SIN; return T_FUNC1; }
"sqrt" { yylval.ival = C_SQRT; return T_FUNC1; }
"atan2" { yylval.ival = C_ATAN2; return T_FUNC2; }
[a-zA-Z_][0-9a-zA-Z_]* {
funcp = func;
while (funcp->name != 0) {
if (strcmp(yytext, funcp->name) == 0) {
yylval.ival = funcp->code;
return funcp->type;
}
funcp++;
}
yylval.vptr = lookup(yytext);
if (yypeek() == '(')
return T_USER;
return T_NAME;
}
[0-9]+ |
[0-9]+\.[0-9]+ |
[0-9]+[Ee][-+]?[0-9]+ |
[0-9]+\.[0-9]+[Ee][-+]?[0-9]+ {
yylval.dval = atof(yytext);
return T_DCON;
}
">>" return T_APPEND;
"!~" return T_NOMATCH;
"&&" return T_LAND;
"||" return T_LIOR;
"!=" { yylval.ival = C_NE; return T_RELOP; }
"==" { yylval.ival = C_EQ; return T_RELOP; }
"<=" { yylval.ival = C_LE; return T_RELOP; }
">=" { yylval.ival = C_GE; return T_RELOP; }
"++" { yylval.ival = C_ADD; return T_INCOP; }
"--" { yylval.ival = C_SUB; return T_INCOP; }
"^=" { yylval.ival = C_POW; return T_STORE; }
"*=" { yylval.ival = C_MUL; return T_STORE; }
"/=" { yylval.ival = C_DIV; return T_STORE; }
"%=" { yylval.ival = C_MOD; return T_STORE; }
"+=" { yylval.ival = C_ADD; return T_STORE; }
"-=" { yylval.ival = C_SUB; return T_STORE; }
"=" { yylval.ival = 0; return T_STORE; }
"}" {
yyback('\n');
return '}';
}
"-" return '-';
"]" return ']';
[{[$!?:;,^~/*%+<>()] {
return *yytext;
}
'"' {
string('"');
return T_SCON;
}
. return ERROR;
%%
static void string(int ec)
{
register int len;
register c;
buffer[0] = '\377';
for (len = 1; len < 79 && (c = yymapc(ec, '\\')) != EOF; len++)
buffer[len] = c;
buffer[len] = '\0';
if (len == 1)
yylval.sptr = (char near *)nullstr;
else {
yylval.sptr = yyalloc(len+1);
strcpy(yylval.sptr, buffer);
}
}
static int comment()
{
register int ch;
while ((ch = yynext()) != EOF && ch != '\n')
;
return ch;
}
static void newline()
{
register int ch;
while ((ch = yynext()) != EOF) {
if (ch == '#')
ch = comment();
if (ch != ' ' && ch != '\t' && ch != '\n') {
yyback(ch);
break;
}
}
}
static void eatspace()
{
register int ch;
while ((ch = yynext()) == ' ' || ch == '\t')
;
yyback(ch);
}
int
input()
{
if (lineptr == NULL) {
if (awklist != NULL) {
yyline = 0;
yyname = awklist->name;
if (yyname == awkstdin)
awkfile = stdin;
else {
awkfile = fopen(yyname ,"r");
if (awkfile == NULL)
error("Can't open program file %s", yyname);
}
awklist = awklist->next;
lineptr = linebuf;
*lineptr = '\0';
}
else {
awkeof = 1;
return(EOF);
}
}
if (*lineptr == '\0') {
if (awkeof)
return(EOF);
lineptr = fgets(linebuf, 128, awkfile);
if (lineptr != linebuf) {
lineptr = NULL;
return('\n');
}
yyline++;
genline();
if (linebuf[0] == '.' && linebuf[1] == '\n') {
awkeof = 1;
lineptr = NULL;
return(EOF);
}
}
return(*lineptr++);
}
IDENT *lookup(char *name)
{
char *sp;
IDENT *vp;
for (vp = ident; vp != NULL; vp = vp->vnext)
if (strcmp(name, vp->vname) == 0)
return vp;
if (nextvar >= vartab+MAXNAME)
yyerror("Too many variables");
sp = yyalloc(strlen(name) + 1);
strcpy(sp, name);
vp = yyalloc(sizeof(IDENT));
vp->vitem = NULL;
vp->vname = sp;
vp->vfunc = NULL;
vp->vnext = ident;
ident = vp;
return vp;
}
void *
yyalloc(size)
unsigned int size;
{
void *mp;
mp = malloc(size);
if (mp == NULL)
yyerror("out of memory");
memset(mp, 0, size);
return(mp);
}
void
yyerror(str)
char *str;
{
char *lp, *ep;
fprintf(stderr, "%s", linebuf);
if ((char near *)lineptr != NULL) {
ep = (char near *)lineptr - 1 - yylook();
for (lp = linebuf; lp < ep; lp++)
fputc(*lp=='\t'?'\t':' ', stderr);
fprintf(stderr, "^\n");
}
error(str, NULL);
}