%{
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1996 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
%}
%{
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
%}
%{
/* All Rights Reserved */
%}
%Start A str chc sc reg comment
%{
#include "awk.h"
#include "awk.def"
#undef input /* defeat lex */
extern int yylval;
extern int mustfld;
long long lineno = 1;
#ifdef DEBUG
# define RETURN(x) {if (dbg) ptoken(x); return (x); }
#else
# define RETURN(x) return (x)
#endif
#define CADD { cbuf[clen++]=yytext[0]; if (clen>=CBUFLEN-1) { yyerror(\
"string too long", cbuf); BEGIN A; } }
#define CBUFLEN 150
wchar_t cbuf[CBUFLEN];
int clen, cflag;
%}
%a 50000
%o 50000
A [a-zA-Z_]
B [a-zA-Z0-9_]
D [0-9]
WS [ \t]
%%
switch (yybgin-yysvec-1) { /* witchcraft */
case 0:
BEGIN A;
break;
case sc:
BEGIN A;
RETURN('}');
}
^\n lineno++;
^{WS}*#.*\n lineno++; /* strip comment lines */
{WS} /* dummy for cstyle */;
"\\"\n lineno++;
"\\"\n lineno++;
"||" RETURN(BOR);
BEGIN RETURN(XBEGIN);
END RETURN(XEND);
PROGEND RETURN(EOF);
"&&" RETURN(AND);
"!" RETURN(NOT);
"!=" { yylval = NE; RETURN(RELOP); }
"~" { yylval = MATCH; RETURN(MATCHOP); }
"!~" { yylval = NOTMATCH; RETURN(MATCHOP); }
"<" { yylval = LT; RETURN(RELOP); }
"<=" { yylval = LE; RETURN(RELOP); }
"==" { yylval = EQ; RETURN(RELOP); }
">=" { yylval = GE; RETURN(RELOP); }
">" { yylval = GT; RETURN(RELOP); }
">>" { yylval = APPEND; RETURN(RELOP); }
"++" { yylval = INCR; RETURN(INCR); }
"--" { yylval = DECR; RETURN(DECR); }
"+=" { yylval = ADDEQ; RETURN(ASGNOP); }
"-=" { yylval = SUBEQ; RETURN(ASGNOP); }
"*=" { yylval = MULTEQ; RETURN(ASGNOP); }
"/=" { yylval = DIVEQ; RETURN(ASGNOP); }
"%=" { yylval = MODEQ; RETURN(ASGNOP); }
"=" { yylval = ASSIGN; RETURN(ASGNOP); }
"$"{D}+ {
static wchar_t L_record[] = L"$record";
if (watoi(yytext+1)==0) {
yylval = (int)lookup(L_record, symtab, 0);
RETURN(STRING);
} else {
yylval = fieldadr(watoi(yytext+1));
RETURN(FIELD);
}
}
"$"{WS}* { RETURN(INDIRECT); }
NF { mustfld=1;
yylval = (int)setsymtab(yytext, NULL, 0.0, NUM, symtab);
RETURN(VAR); }
({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)? {
yylval = (int)setsymtab(yytext, NULL, watof(yytext),
CON|NUM, symtab); RETURN(NUMBER); }
"}"{WS}*\n { BEGIN sc; lineno++; RETURN(';'); }
"}" { BEGIN sc; RETURN(';'); }
";"\n { lineno++; RETURN(';'); }
\n { lineno++; RETURN(NL); }
while RETURN(WHILE);
for RETURN(FOR);
if RETURN(IF);
else RETURN(ELSE);
next RETURN(NEXT);
exit RETURN(EXIT);
break RETURN(BREAK);
continue RETURN(CONTINUE);
print { yylval = PRINT; RETURN(PRINT); }
printf { yylval = PRINTF; RETURN(PRINTF); }
sprintf { yylval = SPRINTF; RETURN(SPRINTF); }
split { yylval = SPLIT; RETURN(SPLIT); }
substr RETURN(SUBSTR);
index RETURN(INDEX);
in RETURN(IN);
getline RETURN(GETLINE);
length { yylval = FLENGTH; RETURN(FNCN); }
log { yylval = FLOG; RETURN(FNCN); }
int { yylval = FINT; RETURN(FNCN); }
exp { yylval = FEXP; RETURN(FNCN); }
sqrt { yylval = FSQRT; RETURN(FNCN); }
{A}{B}* {
static wchar_t L_0[] = { 0 };
yylval = (int)setsymtab(yytext, tostring(L_0), 0.0, STR|NUM,
symtab);
RETURN(VAR);
}
\" { BEGIN str; clen=0; }
# { BEGIN comment; }
\n { BEGIN A; lineno++; RETURN(NL); }
. /* dummy */;
. { yylval = yytext[0]; RETURN(yytext[0]); }
"[" { BEGIN chc; clen=0; cflag=0; }
"[^" { BEGIN chc; clen=0; cflag=1; }
"?" RETURN(QUEST);
"+" RETURN(PLUS);
"*" RETURN(STAR);
"|" RETURN(OR);
"." RETURN(DOT);
"(" RETURN('(');
")" RETURN(')');
"^" RETURN('^');
"$" RETURN('$');
\\{D}{D}{D} { wsscanf(yytext+1, "%o", &yylval); RETURN(CHAR); }
\\. { if (yytext[1]=='n') yylval = '\n';
else if (yytext[1] == 't') yylval = '\t';
else if (yytext[1] == 'b') yylval = '\b';
else if (yytext[1] == 'r') yylval = '\r';
else if (yytext[1] == 'f') yylval = '\f';
else yylval = yytext[1];
RETURN(CHAR);
}
"/" { BEGIN A; unput('/'); }
\n { yyerror("newline in regular expression"); lineno++; BEGIN A; }
. { yylval = yytext[0]; RETURN(CHAR); }
\" { wchar_t *s; BEGIN A; cbuf[clen]=0; s = tostring(cbuf);
cbuf[clen] = ' '; cbuf[++clen] = 0;
yylval = (int)setsymtab(cbuf, s, 0.0, CON|STR, symtab);
RETURN(STRING); }
\n { yyerror("newline in string"); lineno++; BEGIN A; }
"\\\"" { cbuf[clen++]='"'; }
"\\"n { cbuf[clen++]='\n'; }
"\\"n { cbuf[clen++]='\n'; }
"\\"t { cbuf[clen++]='\t'; }
"\\"t { cbuf[clen++]='\t'; }
"\\"b { cbuf[clen++]='\b'; }
"\\"b { cbuf[clen++]='\b'; }
"\\"r { cbuf[clen++]='\r'; }
"\\"r { cbuf[clen++]='\r'; }
"\\"f { cbuf[clen++]='\f'; }
"\\"f { cbuf[clen++]='\f'; }
"\\\\" { cbuf[clen++]='\\'; }
"\\\\" { cbuf[clen++]='\\'; }
. { CADD; }
"\\""]" { cbuf[clen++]=']'; }
"]" { BEGIN reg; cbuf[clen]=0; yylval = (int)tostring(cbuf);
if (cflag==0) { RETURN(CCL); }
else { RETURN(NCCL); } }
\n { yyerror("newline in character class"); lineno++; BEGIN A; }
. { CADD; }
%%
int
input()
{
int c;
extern wchar_t *lexprog;
if (yysptr > yysbuf)
c = U(*--yysptr);
else if (yyin == NULL)
c = *lexprog++;
else
c = getwc(yyin);
if (c == '\n')
yylineno++;
else if (c == EOF)
c = 0;
return (c);
}
void
startreg()
{
BEGIN reg;
}