awk: import from sources
diff --git a/src/cmd/awk/README b/src/cmd/awk/README
new file mode 100644
index 0000000..bcf4612
--- /dev/null
+++ b/src/cmd/awk/README
@@ -0,0 +1,13 @@
+This 'awk' source is directly downloaded from the Plan 9 source
+
+http://cm.bell-labs.com/sources/plan9/sys/src/cmd/awk/
+
+as such, it's copyright is held by Lucent Technologies and distributed under the
+Lucent Public License version 1.02 [http://www.opensource.org/licenses/lucent1.02.php].
+
+Modifications were made by Jeff Sickel in order to build using Plan 9 from User
+Space [http://swtch.com/plan9port/] to the following files:
+
+    mkfile
+    re.c
+
diff --git a/src/cmd/awk/awk.h b/src/cmd/awk/awk.h
new file mode 100644
index 0000000..1853381
--- /dev/null
+++ b/src/cmd/awk/awk.h
@@ -0,0 +1,185 @@
+/*
+Copyright (c) Lucent Technologies 1997
+	All Rights Reserved
+
+*/
+
+typedef double	Awkfloat;
+
+/* unsigned char is more trouble than it's worth */
+
+typedef	unsigned char uschar;
+
+#define	xfree(a)	{ if ((a) != NULL) { free((char *) a); a = NULL; } }
+
+#define	DEBUG
+#ifdef	DEBUG
+			/* uses have to be doubly parenthesized */
+#	define	dprintf(x)	if (dbg) printf x
+#else
+#	define	dprintf(x)
+#endif
+
+extern	char	errbuf[];
+
+extern int	compile_time;	/* 1 if compiling, 0 if running */
+extern int	safe;		/* 0 => unsafe, 1 => safe */
+
+#define	RECSIZE	(8 * 1024)	/* sets limit on records, fields, etc., etc. */
+extern int	recsize;	/* size of current record, orig RECSIZE */
+
+extern char	**FS;
+extern char	**RS;
+extern char	**ORS;
+extern char	**OFS;
+extern char	**OFMT;
+extern Awkfloat *NR;
+extern Awkfloat *FNR;
+extern Awkfloat *NF;
+extern char	**FILENAME;
+extern char	**SUBSEP;
+extern Awkfloat *RSTART;
+extern Awkfloat *RLENGTH;
+
+extern char	*record;	/* points to $0 */
+extern int	lineno;		/* line number in awk program */
+extern int	errorflag;	/* 1 if error has occurred */
+extern int	donefld;	/* 1 if record broken into fields */
+extern int	donerec;	/* 1 if record is valid (no fld has changed */
+extern char	inputFS[];	/* FS at time of input, for field splitting */
+
+extern int	dbg;
+
+extern	char	*patbeg;	/* beginning of pattern matched */
+extern	int	patlen;		/* length of pattern matched.  set in b.c */
+
+/* Cell:  all information about a variable or constant */
+
+typedef struct Cell {
+	uschar	ctype;		/* OCELL, OBOOL, OJUMP, etc. */
+	uschar	csub;		/* CCON, CTEMP, CFLD, etc. */
+	char	*nval;		/* name, for variables only */
+	char	*sval;		/* string value */
+	Awkfloat fval;		/* value as number */
+	int	 tval;		/* type info: STR|NUM|ARR|FCN|FLD|CON|DONTFREE */
+	struct Cell *cnext;	/* ptr to next if chained */
+} Cell;
+
+typedef struct Array {		/* symbol table array */
+	int	nelem;		/* elements in table right now */
+	int	size;		/* size of tab */
+	Cell	**tab;		/* hash table pointers */
+} Array;
+
+#define	NSYMTAB	50	/* initial size of a symbol table */
+extern Array	*symtab;
+
+extern Cell	*nrloc;		/* NR */
+extern Cell	*fnrloc;	/* FNR */
+extern Cell	*nfloc;		/* NF */
+extern Cell	*rstartloc;	/* RSTART */
+extern Cell	*rlengthloc;	/* RLENGTH */
+
+/* Cell.tval values: */
+#define	NUM	01	/* number value is valid */
+#define	STR	02	/* string value is valid */
+#define DONTFREE 04	/* string space is not freeable */
+#define	CON	010	/* this is a constant */
+#define	ARR	020	/* this is an array */
+#define	FCN	040	/* this is a function name */
+#define FLD	0100	/* this is a field $1, $2, ... */
+#define	REC	0200	/* this is $0 */
+
+
+/* function types */
+#define	FLENGTH	1
+#define	FSQRT	2
+#define	FEXP	3
+#define	FLOG	4
+#define	FINT	5
+#define	FSYSTEM	6
+#define	FRAND	7
+#define	FSRAND	8
+#define	FSIN	9
+#define	FCOS	10
+#define	FATAN	11
+#define	FTOUPPER 12
+#define	FTOLOWER 13
+#define	FFLUSH	14
+#define	FUTF	15
+
+/* Node:  parse tree is made of nodes, with Cell's at bottom */
+
+typedef struct Node {
+	int	ntype;
+	struct	Node *nnext;
+	int	lineno;
+	int	nobj;
+	struct	Node *narg[1];	/* variable: actual size set by calling malloc */
+} Node;
+
+#define	NIL	((Node *) 0)
+
+extern Node	*winner;
+extern Node	*nullstat;
+extern Node	*nullnode;
+
+/* ctypes */
+#define OCELL	1
+#define OBOOL	2
+#define OJUMP	3
+
+/* Cell subtypes: csub */
+#define	CFREE	7
+#define CCOPY	6
+#define CCON	5
+#define CTEMP	4
+#define CNAME	3 
+#define CVAR	2
+#define CFLD	1
+#define	CUNK	0
+
+/* bool subtypes */
+#define BTRUE	11
+#define BFALSE	12
+
+/* jump subtypes */
+#define JEXIT	21
+#define JNEXT	22
+#define	JBREAK	23
+#define	JCONT	24
+#define	JRET	25
+#define	JNEXTFILE	26
+
+/* node types */
+#define NVALUE	1
+#define NSTAT	2
+#define NEXPR	3
+
+
+extern	int	pairstack[], paircnt;
+
+#define notlegal(n)	(n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN] == nullproc)
+#define isvalue(n)	((n)->ntype == NVALUE)
+#define isexpr(n)	((n)->ntype == NEXPR)
+#define isjump(n)	((n)->ctype == OJUMP)
+#define isexit(n)	((n)->csub == JEXIT)
+#define	isbreak(n)	((n)->csub == JBREAK)
+#define	iscont(n)	((n)->csub == JCONT)
+#define	isnext(n)	((n)->csub == JNEXT)
+#define	isnextfile(n)	((n)->csub == JNEXTFILE)
+#define	isret(n)	((n)->csub == JRET)
+#define isrec(n)	((n)->tval & REC)
+#define isfld(n)	((n)->tval & FLD)
+#define isstr(n)	((n)->tval & STR)
+#define isnum(n)	((n)->tval & NUM)
+#define isarr(n)	((n)->tval & ARR)
+#define isfcn(n)	((n)->tval & FCN)
+#define istrue(n)	((n)->csub == BTRUE)
+#define istemp(n)	((n)->csub == CTEMP)
+#define	isargument(n)	((n)->nobj == ARG)
+/* #define freeable(p)	(!((p)->tval & DONTFREE)) */
+#define freeable(p)	( ((p)->tval & (STR|DONTFREE)) == STR )
+
+#include "proto.h"
+
diff --git a/src/cmd/awk/awkgram.y b/src/cmd/awk/awkgram.y
new file mode 100644
index 0000000..31e188c
--- /dev/null
+++ b/src/cmd/awk/awkgram.y
@@ -0,0 +1,489 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+%{
+#include <stdio.h>
+#include <string.h>
+#include "awk.h"
+
+#define	makedfa(a,b)	compre(a)
+
+void checkdup(Node *list, Cell *item);
+int yywrap(void) { return(1); }
+
+Node	*beginloc = 0;
+Node	*endloc = 0;
+int	infunc	= 0;	/* = 1 if in arglist or body of func */
+int	inloop	= 0;	/* = 1 if in while, for, do */
+char	*curfname = 0;	/* current function name */
+Node	*arglist = 0;	/* list of args for current function */
+%}
+
+%union {
+	Node	*p;
+	Cell	*cp;
+	int	i;
+	char	*s;
+}
+
+%token	<i>	FIRSTTOKEN	/* must be first */
+%token	<p>	PROGRAM PASTAT PASTAT2 XBEGIN XEND
+%token	<i>	NL ',' '{' '(' '|' ';' '/' ')' '}' '[' ']'
+%token	<i>	ARRAY
+%token	<i>	MATCH NOTMATCH MATCHOP
+%token	<i>	FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS
+%token	<i>	AND BOR APPEND EQ GE GT LE LT NE IN
+%token	<i>	ARG BLTIN BREAK CLOSE CONTINUE DELETE DO EXIT FOR FUNC 
+%token	<i>	SUB GSUB IF INDEX LSUBSTR MATCHFCN NEXT NEXTFILE
+%token	<i>	ADD MINUS MULT DIVIDE MOD
+%token	<i>	ASSIGN ASGNOP ADDEQ SUBEQ MULTEQ DIVEQ MODEQ POWEQ
+%token	<i>	PRINT PRINTF SPRINTF
+%token	<p>	ELSE INTEST CONDEXPR
+%token	<i>	POSTINCR PREINCR POSTDECR PREDECR
+%token	<cp>	VAR IVAR VARNF CALL NUMBER STRING
+%token	<s>	REGEXPR
+
+%type	<p>	pas pattern ppattern plist pplist patlist prarg term re
+%type	<p>	pa_pat pa_stat pa_stats
+%type	<s>	reg_expr
+%type	<p>	simple_stmt opt_simple_stmt stmt stmtlist
+%type	<p>	var varname funcname varlist
+%type	<p>	for if else while
+%type	<i>	do st
+%type	<i>	pst opt_pst lbrace rbrace rparen comma nl opt_nl and bor
+%type	<i>	subop print
+
+%right	ASGNOP
+%right	'?'
+%right	':'
+%left	BOR
+%left	AND
+%left	GETLINE
+%nonassoc APPEND EQ GE GT LE LT NE MATCHOP IN '|'
+%left	ARG BLTIN BREAK CALL CLOSE CONTINUE DELETE DO EXIT FOR FUNC 
+%left	GSUB IF INDEX LSUBSTR MATCHFCN NEXT NUMBER
+%left	PRINT PRINTF RETURN SPLIT SPRINTF STRING SUB SUBSTR
+%left	REGEXPR VAR VARNF IVAR WHILE '('
+%left	CAT
+%left	'+' '-'
+%left	'*' '/' '%'
+%left	NOT UMINUS
+%right	POWER
+%right	DECR INCR
+%left	INDIRECT
+%token	LASTTOKEN	/* must be last */
+
+%%
+
+program:
+	  pas	{ if (errorflag==0)
+			winner = (Node *)stat3(PROGRAM, beginloc, $1, endloc); }
+	| error	{ yyclearin; bracecheck(); SYNTAX("bailing out"); }
+	;
+
+and:
+	  AND | and NL
+	;
+
+bor:
+	  BOR | bor NL
+	;
+
+comma:
+	  ',' | comma NL
+	;
+
+do:
+	  DO | do NL
+	;
+
+else:
+	  ELSE | else NL
+	;
+
+for:
+	  FOR '(' opt_simple_stmt ';' opt_nl pattern ';' opt_nl opt_simple_stmt rparen {inloop++;} stmt
+		{ --inloop; $$ = stat4(FOR, $3, notnull($6), $9, $12); }
+	| FOR '(' opt_simple_stmt ';'  ';' opt_nl opt_simple_stmt rparen {inloop++;} stmt
+		{ --inloop; $$ = stat4(FOR, $3, NIL, $7, $10); }
+	| FOR '(' varname IN varname rparen {inloop++;} stmt
+		{ --inloop; $$ = stat3(IN, $3, makearr($5), $8); }
+	;
+
+funcname:
+	  VAR	{ setfname($1); }
+	| CALL	{ setfname($1); }
+	;
+
+if:
+	  IF '(' pattern rparen		{ $$ = notnull($3); }
+	;
+
+lbrace:
+	  '{' | lbrace NL
+	;
+
+nl:
+	  NL | nl NL
+	;
+
+opt_nl:
+	  /* empty */	{ $$ = 0; }
+	| nl
+	;
+
+opt_pst:
+	  /* empty */	{ $$ = 0; }
+	| pst
+	;
+
+
+opt_simple_stmt:
+	  /* empty */			{ $$ = 0; }
+	| simple_stmt
+	;
+
+pas:
+	  opt_pst			{ $$ = 0; }
+	| opt_pst pa_stats opt_pst	{ $$ = $2; }
+	;
+
+pa_pat:
+	  pattern	{ $$ = notnull($1); }
+	;
+
+pa_stat:
+	  pa_pat			{ $$ = stat2(PASTAT, $1, stat2(PRINT, rectonode(), NIL)); }
+	| pa_pat lbrace stmtlist '}'	{ $$ = stat2(PASTAT, $1, $3); }
+	| pa_pat ',' pa_pat		{ $$ = pa2stat($1, $3, stat2(PRINT, rectonode(), NIL)); }
+	| pa_pat ',' pa_pat lbrace stmtlist '}'	{ $$ = pa2stat($1, $3, $5); }
+	| lbrace stmtlist '}'		{ $$ = stat2(PASTAT, NIL, $2); }
+	| XBEGIN lbrace stmtlist '}'
+		{ beginloc = linkum(beginloc, $3); $$ = 0; }
+	| XEND lbrace stmtlist '}'
+		{ endloc = linkum(endloc, $3); $$ = 0; }
+	| FUNC funcname '(' varlist rparen {infunc++;} lbrace stmtlist '}'
+		{ infunc--; curfname=0; defn((Cell *)$2, $4, $8); $$ = 0; }
+	;
+
+pa_stats:
+	  pa_stat
+	| pa_stats opt_pst pa_stat	{ $$ = linkum($1, $3); }
+	;
+
+patlist:
+	  pattern
+	| patlist comma pattern		{ $$ = linkum($1, $3); }
+	;
+
+ppattern:
+	  var ASGNOP ppattern		{ $$ = op2($2, $1, $3); }
+	| ppattern '?' ppattern ':' ppattern %prec '?'
+	 	{ $$ = op3(CONDEXPR, notnull($1), $3, $5); }
+	| ppattern bor ppattern %prec BOR
+		{ $$ = op2(BOR, notnull($1), notnull($3)); }
+	| ppattern and ppattern %prec AND
+		{ $$ = op2(AND, notnull($1), notnull($3)); }
+	| ppattern MATCHOP reg_expr	{ $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
+	| ppattern MATCHOP ppattern
+		{ if (constnode($3))
+			$$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
+		  else
+			$$ = op3($2, (Node *)1, $1, $3); }
+	| ppattern IN varname		{ $$ = op2(INTEST, $1, makearr($3)); }
+	| '(' plist ')' IN varname	{ $$ = op2(INTEST, $2, makearr($5)); }
+	| ppattern term %prec CAT	{ $$ = op2(CAT, $1, $2); }
+	| re
+	| term
+	;
+
+pattern:
+	  var ASGNOP pattern		{ $$ = op2($2, $1, $3); }
+	| pattern '?' pattern ':' pattern %prec '?'
+	 	{ $$ = op3(CONDEXPR, notnull($1), $3, $5); }
+	| pattern bor pattern %prec BOR
+		{ $$ = op2(BOR, notnull($1), notnull($3)); }
+	| pattern and pattern %prec AND
+		{ $$ = op2(AND, notnull($1), notnull($3)); }
+	| pattern EQ pattern		{ $$ = op2($2, $1, $3); }
+	| pattern GE pattern		{ $$ = op2($2, $1, $3); }
+	| pattern GT pattern		{ $$ = op2($2, $1, $3); }
+	| pattern LE pattern		{ $$ = op2($2, $1, $3); }
+	| pattern LT pattern		{ $$ = op2($2, $1, $3); }
+	| pattern NE pattern		{ $$ = op2($2, $1, $3); }
+	| pattern MATCHOP reg_expr	{ $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
+	| pattern MATCHOP pattern
+		{ if (constnode($3))
+			$$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
+		  else
+			$$ = op3($2, (Node *)1, $1, $3); }
+	| pattern IN varname		{ $$ = op2(INTEST, $1, makearr($3)); }
+	| '(' plist ')' IN varname	{ $$ = op2(INTEST, $2, makearr($5)); }
+	| pattern '|' GETLINE var	{ 
+			if (safe) SYNTAX("cmd | getline is unsafe");
+			else $$ = op3(GETLINE, $4, itonp($2), $1); }
+	| pattern '|' GETLINE		{ 
+			if (safe) SYNTAX("cmd | getline is unsafe");
+			else $$ = op3(GETLINE, (Node*)0, itonp($2), $1); }
+	| pattern term %prec CAT	{ $$ = op2(CAT, $1, $2); }
+	| re
+	| term
+	;
+
+plist:
+	  pattern comma pattern		{ $$ = linkum($1, $3); }
+	| plist comma pattern		{ $$ = linkum($1, $3); }
+	;
+
+pplist:
+	  ppattern
+	| pplist comma ppattern		{ $$ = linkum($1, $3); }
+	;
+
+prarg:
+	  /* empty */			{ $$ = rectonode(); }
+	| pplist
+	| '(' plist ')'			{ $$ = $2; }
+	;
+
+print:
+	  PRINT | PRINTF
+	;
+
+pst:
+	  NL | ';' | pst NL | pst ';'
+	;
+
+rbrace:
+	  '}' | rbrace NL
+	;
+
+re:
+	   reg_expr
+		{ $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); }
+	| NOT re	{ $$ = op1(NOT, notnull($2)); }
+	;
+
+reg_expr:
+	  '/' {startreg();} REGEXPR '/'		{ $$ = $3; }
+	;
+
+rparen:
+	  ')' | rparen NL
+	;
+
+simple_stmt:
+	  print prarg '|' term		{ 
+			if (safe) SYNTAX("print | is unsafe");
+			else $$ = stat3($1, $2, itonp($3), $4); }
+	| print prarg APPEND term	{
+			if (safe) SYNTAX("print >> is unsafe");
+			else $$ = stat3($1, $2, itonp($3), $4); }
+	| print prarg GT term		{
+			if (safe) SYNTAX("print > is unsafe");
+			else $$ = stat3($1, $2, itonp($3), $4); }
+	| print prarg			{ $$ = stat3($1, $2, NIL, NIL); }
+	| DELETE varname '[' patlist ']' { $$ = stat2(DELETE, makearr($2), $4); }
+	| DELETE varname		 { $$ = stat2(DELETE, makearr($2), 0); }
+	| pattern			{ $$ = exptostat($1); }
+	| error				{ yyclearin; SYNTAX("illegal statement"); }
+	;
+
+st:
+	  nl
+	| ';' opt_nl
+	;
+
+stmt:
+	  BREAK st		{ if (!inloop) SYNTAX("break illegal outside of loops");
+				  $$ = stat1(BREAK, NIL); }
+	| CLOSE pattern st	{ $$ = stat1(CLOSE, $2); }
+	| CONTINUE st		{  if (!inloop) SYNTAX("continue illegal outside of loops");
+				  $$ = stat1(CONTINUE, NIL); }
+	| do {inloop++;} stmt {--inloop;} WHILE '(' pattern ')' st
+		{ $$ = stat2(DO, $3, notnull($7)); }
+	| EXIT pattern st	{ $$ = stat1(EXIT, $2); }
+	| EXIT st		{ $$ = stat1(EXIT, NIL); }
+	| for
+	| if stmt else stmt	{ $$ = stat3(IF, $1, $2, $4); }
+	| if stmt		{ $$ = stat3(IF, $1, $2, NIL); }
+	| lbrace stmtlist rbrace { $$ = $2; }
+	| NEXT st	{ if (infunc)
+				SYNTAX("next is illegal inside a function");
+			  $$ = stat1(NEXT, NIL); }
+	| NEXTFILE st	{ if (infunc)
+				SYNTAX("nextfile is illegal inside a function");
+			  $$ = stat1(NEXTFILE, NIL); }
+	| RETURN pattern st	{ $$ = stat1(RETURN, $2); }
+	| RETURN st		{ $$ = stat1(RETURN, NIL); }
+	| simple_stmt st
+	| while {inloop++;} stmt	{ --inloop; $$ = stat2(WHILE, $1, $3); }
+	| ';' opt_nl		{ $$ = 0; }
+	;
+
+stmtlist:
+	  stmt
+	| stmtlist stmt		{ $$ = linkum($1, $2); }
+	;
+
+subop:
+	  SUB | GSUB
+	;
+
+term:
+ 	  term '/' ASGNOP term		{ $$ = op2(DIVEQ, $1, $4); }
+ 	| term '+' term			{ $$ = op2(ADD, $1, $3); }
+	| term '-' term			{ $$ = op2(MINUS, $1, $3); }
+	| term '*' term			{ $$ = op2(MULT, $1, $3); }
+	| term '/' term			{ $$ = op2(DIVIDE, $1, $3); }
+	| term '%' term			{ $$ = op2(MOD, $1, $3); }
+	| term POWER term		{ $$ = op2(POWER, $1, $3); }
+	| '-' term %prec UMINUS		{ $$ = op1(UMINUS, $2); }
+	| '+' term %prec UMINUS		{ $$ = $2; }
+	| NOT term %prec UMINUS		{ $$ = op1(NOT, notnull($2)); }
+	| BLTIN '(' ')'			{ $$ = op2(BLTIN, itonp($1), rectonode()); }
+	| BLTIN '(' patlist ')'		{ $$ = op2(BLTIN, itonp($1), $3); }
+	| BLTIN				{ $$ = op2(BLTIN, itonp($1), rectonode()); }
+	| CALL '(' ')'			{ $$ = op2(CALL, celltonode($1,CVAR), NIL); }
+	| CALL '(' patlist ')'		{ $$ = op2(CALL, celltonode($1,CVAR), $3); }
+	| DECR var			{ $$ = op1(PREDECR, $2); }
+	| INCR var			{ $$ = op1(PREINCR, $2); }
+	| var DECR			{ $$ = op1(POSTDECR, $1); }
+	| var INCR			{ $$ = op1(POSTINCR, $1); }
+	| GETLINE var LT term		{ $$ = op3(GETLINE, $2, itonp($3), $4); }
+	| GETLINE LT term		{ $$ = op3(GETLINE, NIL, itonp($2), $3); }
+	| GETLINE var			{ $$ = op3(GETLINE, $2, NIL, NIL); }
+	| GETLINE			{ $$ = op3(GETLINE, NIL, NIL, NIL); }
+	| INDEX '(' pattern comma pattern ')'
+		{ $$ = op2(INDEX, $3, $5); }
+	| INDEX '(' pattern comma reg_expr ')'
+		{ SYNTAX("index() doesn't permit regular expressions");
+		  $$ = op2(INDEX, $3, (Node*)$5); }
+	| '(' pattern ')'		{ $$ = $2; }
+	| MATCHFCN '(' pattern comma reg_expr ')'
+		{ $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa($5, 1)); }
+	| MATCHFCN '(' pattern comma pattern ')'
+		{ if (constnode($5))
+			$$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa(strnode($5), 1));
+		  else
+			$$ = op3(MATCHFCN, (Node *)1, $3, $5); }
+	| NUMBER			{ $$ = celltonode($1, CCON); }
+	| SPLIT '(' pattern comma varname comma pattern ')'     /* string */
+		{ $$ = op4(SPLIT, $3, makearr($5), $7, (Node*)STRING); }
+	| SPLIT '(' pattern comma varname comma reg_expr ')'    /* const /regexp/ */
+		{ $$ = op4(SPLIT, $3, makearr($5), (Node*)makedfa($7, 1), (Node *)REGEXPR); }
+	| SPLIT '(' pattern comma varname ')'
+		{ $$ = op4(SPLIT, $3, makearr($5), NIL, (Node*)STRING); }  /* default */
+	| SPRINTF '(' patlist ')'	{ $$ = op1($1, $3); }
+	| STRING	 		{ $$ = celltonode($1, CCON); }
+	| subop '(' reg_expr comma pattern ')'
+		{ $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, rectonode()); }
+	| subop '(' pattern comma pattern ')'
+		{ if (constnode($3))
+			$$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, rectonode());
+		  else
+			$$ = op4($1, (Node *)1, $3, $5, rectonode()); }
+	| subop '(' reg_expr comma pattern comma var ')'
+		{ $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, $7); }
+	| subop '(' pattern comma pattern comma var ')'
+		{ if (constnode($3))
+			$$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, $7);
+		  else
+			$$ = op4($1, (Node *)1, $3, $5, $7); }
+	| SUBSTR '(' pattern comma pattern comma pattern ')'
+		{ $$ = op3(SUBSTR, $3, $5, $7); }
+	| SUBSTR '(' pattern comma pattern ')'
+		{ $$ = op3(SUBSTR, $3, $5, NIL); }
+	| var
+	;
+
+var:
+	  varname
+	| varname '[' patlist ']'	{ $$ = op2(ARRAY, makearr($1), $3); }
+	| IVAR				{ $$ = op1(INDIRECT, celltonode($1, CVAR)); }
+	| INDIRECT term	 		{ $$ = op1(INDIRECT, $2); }
+	;	
+
+varlist:
+	  /* nothing */		{ arglist = $$ = 0; }
+	| VAR			{ arglist = $$ = celltonode($1,CVAR); }
+	| varlist comma VAR	{
+			checkdup($1, $3);
+			arglist = $$ = linkum($1,celltonode($3,CVAR)); }
+	;
+
+varname:
+	  VAR			{ $$ = celltonode($1, CVAR); }
+	| ARG 			{ $$ = op1(ARG, itonp($1)); }
+	| VARNF			{ $$ = op1(VARNF, (Node *) $1); }
+	;
+
+
+while:
+	  WHILE '(' pattern rparen	{ $$ = notnull($3); }
+	;
+
+%%
+
+void setfname(Cell *p)
+{
+	if (isarr(p))
+		SYNTAX("%s is an array, not a function", p->nval);
+	else if (isfcn(p))
+		SYNTAX("you can't define function %s more than once", p->nval);
+	curfname = p->nval;
+}
+
+int constnode(Node *p)
+{
+	return isvalue(p) && ((Cell *) (p->narg[0]))->csub == CCON;
+}
+
+char *strnode(Node *p)
+{
+	return ((Cell *)(p->narg[0]))->sval;
+}
+
+Node *notnull(Node *n)
+{
+	switch (n->nobj) {
+	case LE: case LT: case EQ: case NE: case GT: case GE:
+	case BOR: case AND: case NOT:
+		return n;
+	default:
+		return op2(NE, n, nullnode);
+	}
+}
+
+void checkdup(Node *vl, Cell *cp)	/* check if name already in list */
+{
+	char *s = cp->nval;
+	for ( ; vl; vl = vl->nnext) {
+		if (strcmp(s, ((Cell *)(vl->narg[0]))->nval) == 0) {
+			SYNTAX("duplicate argument %s", s);
+			break;
+		}
+	}
+}
+
diff --git a/src/cmd/awk/lex.c b/src/cmd/awk/lex.c
new file mode 100644
index 0000000..74a9903
--- /dev/null
+++ b/src/cmd/awk/lex.c
@@ -0,0 +1,570 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "awk.h"
+#include "y.tab.h"
+
+extern YYSTYPE	yylval;
+extern int	infunc;
+
+int	lineno	= 1;
+int	bracecnt = 0;
+int	brackcnt  = 0;
+int	parencnt = 0;
+
+typedef struct Keyword {
+	char	*word;
+	int	sub;
+	int	type;
+} Keyword;
+
+Keyword keywords[] ={	/* keep sorted: binary searched */
+	{ "BEGIN",	XBEGIN,		XBEGIN },
+	{ "END",	XEND,		XEND },
+	{ "NF",		VARNF,		VARNF },
+	{ "atan2",	FATAN,		BLTIN },
+	{ "break",	BREAK,		BREAK },
+	{ "close",	CLOSE,		CLOSE },
+	{ "continue",	CONTINUE,	CONTINUE },
+	{ "cos",	FCOS,		BLTIN },
+	{ "delete",	DELETE,		DELETE },
+	{ "do",		DO,		DO },
+	{ "else",	ELSE,		ELSE },
+	{ "exit",	EXIT,		EXIT },
+	{ "exp",	FEXP,		BLTIN },
+	{ "fflush",	FFLUSH,		BLTIN },
+	{ "for",	FOR,		FOR },
+	{ "func",	FUNC,		FUNC },
+	{ "function",	FUNC,		FUNC },
+	{ "getline",	GETLINE,	GETLINE },
+	{ "gsub",	GSUB,		GSUB },
+	{ "if",		IF,		IF },
+	{ "in",		IN,		IN },
+	{ "index",	INDEX,		INDEX },
+	{ "int",	FINT,		BLTIN },
+	{ "length",	FLENGTH,	BLTIN },
+	{ "log",	FLOG,		BLTIN },
+	{ "match",	MATCHFCN,	MATCHFCN },
+	{ "next",	NEXT,		NEXT },
+	{ "nextfile",	NEXTFILE,	NEXTFILE },
+	{ "print",	PRINT,		PRINT },
+	{ "printf",	PRINTF,		PRINTF },
+	{ "rand",	FRAND,		BLTIN },
+	{ "return",	RETURN,		RETURN },
+	{ "sin",	FSIN,		BLTIN },
+	{ "split",	SPLIT,		SPLIT },
+	{ "sprintf",	SPRINTF,	SPRINTF },
+	{ "sqrt",	FSQRT,		BLTIN },
+	{ "srand",	FSRAND,		BLTIN },
+	{ "sub",	SUB,		SUB },
+	{ "substr",	SUBSTR,		SUBSTR },
+	{ "system",	FSYSTEM,	BLTIN },
+	{ "tolower",	FTOLOWER,	BLTIN },
+	{ "toupper",	FTOUPPER,	BLTIN },
+	{ "utf",	FUTF,		BLTIN },
+	{ "while",	WHILE,		WHILE },
+};
+
+#define DEBUG
+#ifdef	DEBUG
+#define	RET(x)	{ if(dbg)printf("lex %s\n", tokname(x)); return(x); }
+#else
+#define	RET(x)	return(x)
+#endif
+
+int peek(void)
+{
+	int c = input();
+	unput(c);
+	return c;
+}
+
+int gettok(char **pbuf, int *psz)	/* get next input token */
+{
+	int c;
+	char *buf = *pbuf;
+	int sz = *psz;
+	char *bp = buf;
+
+	c = input();
+	if (c == 0)
+		return 0;
+	buf[0] = c;
+	buf[1] = 0;
+	if (!isalnum(c) && c != '.' && c != '_')
+		return c;
+
+	*bp++ = c;
+	if (isalpha(c) || c == '_') {	/* it's a varname */
+		for ( ; (c = input()) != 0; ) {
+			if (bp-buf >= sz)
+				if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, 0))
+					FATAL( "out of space for name %.10s...", buf );
+			if (isalnum(c) || c == '_')
+				*bp++ = c;
+			else {
+				*bp = 0;
+				unput(c);
+				break;
+			}
+		}
+	} else {	/* it's a number */
+		char *rem;
+		/* read input until can't be a number */
+		for ( ; (c = input()) != 0; ) {
+			if (bp-buf >= sz)
+				if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, 0))
+					FATAL( "out of space for number %.10s...", buf );
+			if (isdigit(c) || c == 'e' || c == 'E' 
+			  || c == '.' || c == '+' || c == '-')
+				*bp++ = c;
+			else {
+				unput(c);
+				break;
+			}
+		}
+		*bp = 0;
+		strtod(buf, &rem);	/* parse the number */
+		unputstr(rem);		/* put rest back for later */
+		rem[0] = 0;
+	}
+	*pbuf = buf;
+	*psz = sz;
+	return buf[0];
+}
+
+int	word(char *);
+int	string(void);
+int	regexpr(void);
+int	sc	= 0;	/* 1 => return a } right now */
+int	reg	= 0;	/* 1 => return a REGEXPR now */
+
+int yylex(void)
+{
+	int c;
+	static char *buf = 0;
+	static int bufsize = 500;
+
+	if (buf == 0 && (buf = (char *) malloc(bufsize)) == NULL)
+		FATAL( "out of space in yylex" );
+	if (sc) {
+		sc = 0;
+		RET('}');
+	}
+	if (reg) {
+		reg = 0;
+		return regexpr();
+	}
+	for (;;) {
+		c = gettok(&buf, &bufsize);
+		if (c == 0)
+			return 0;
+		if (isalpha(c) || c == '_')
+			return word(buf);
+		if (isdigit(c) || c == '.') {
+			yylval.cp = setsymtab(buf, tostring(buf), atof(buf), CON|NUM, symtab);
+			/* should this also have STR set? */
+			RET(NUMBER);
+		}
+	
+		yylval.i = c;
+		switch (c) {
+		case '\n':	/* {EOL} */
+			RET(NL);
+		case '\r':	/* assume \n is coming */
+		case ' ':	/* {WS}+ */
+		case '\t':
+			break;
+		case '#':	/* #.* strip comments */
+			while ((c = input()) != '\n' && c != 0)
+				;
+			unput(c);
+			break;
+		case ';':
+			RET(';');
+		case '\\':
+			if (peek() == '\n') {
+				input();
+			} else if (peek() == '\r') {
+				input(); input();	/* \n */
+				lineno++;
+			} else {
+				RET(c);
+			}
+			break;
+		case '&':
+			if (peek() == '&') {
+				input(); RET(AND);
+			} else 
+				RET('&');
+		case '|':
+			if (peek() == '|') {
+				input(); RET(BOR);
+			} else
+				RET('|');
+		case '!':
+			if (peek() == '=') {
+				input(); yylval.i = NE; RET(NE);
+			} else if (peek() == '~') {
+				input(); yylval.i = NOTMATCH; RET(MATCHOP);
+			} else
+				RET(NOT);
+		case '~':
+			yylval.i = MATCH;
+			RET(MATCHOP);
+		case '<':
+			if (peek() == '=') {
+				input(); yylval.i = LE; RET(LE);
+			} else {
+				yylval.i = LT; RET(LT);
+			}
+		case '=':
+			if (peek() == '=') {
+				input(); yylval.i = EQ; RET(EQ);
+			} else {
+				yylval.i = ASSIGN; RET(ASGNOP);
+			}
+		case '>':
+			if (peek() == '=') {
+				input(); yylval.i = GE; RET(GE);
+			} else if (peek() == '>') {
+				input(); yylval.i = APPEND; RET(APPEND);
+			} else {
+				yylval.i = GT; RET(GT);
+			}
+		case '+':
+			if (peek() == '+') {
+				input(); yylval.i = INCR; RET(INCR);
+			} else if (peek() == '=') {
+				input(); yylval.i = ADDEQ; RET(ASGNOP);
+			} else
+				RET('+');
+		case '-':
+			if (peek() == '-') {
+				input(); yylval.i = DECR; RET(DECR);
+			} else if (peek() == '=') {
+				input(); yylval.i = SUBEQ; RET(ASGNOP);
+			} else
+				RET('-');
+		case '*':
+			if (peek() == '=') {	/* *= */
+				input(); yylval.i = MULTEQ; RET(ASGNOP);
+			} else if (peek() == '*') {	/* ** or **= */
+				input();	/* eat 2nd * */
+				if (peek() == '=') {
+					input(); yylval.i = POWEQ; RET(ASGNOP);
+				} else {
+					RET(POWER);
+				}
+			} else
+				RET('*');
+		case '/':
+			RET('/');
+		case '%':
+			if (peek() == '=') {
+				input(); yylval.i = MODEQ; RET(ASGNOP);
+			} else
+				RET('%');
+		case '^':
+			if (peek() == '=') {
+				input(); yylval.i = POWEQ; RET(ASGNOP);
+			} else
+				RET(POWER);
+	
+		case '$':
+			/* BUG: awkward, if not wrong */
+			c = gettok(&buf, &bufsize);
+			if (c == '(' || c == '[' || (infunc && isarg(buf) >= 0)) {
+				unputstr(buf);
+				RET(INDIRECT);
+			} else if (isalpha(c)) {
+				if (strcmp(buf, "NF") == 0) {	/* very special */
+					unputstr("(NF)");
+					RET(INDIRECT);
+				}
+				yylval.cp = setsymtab(buf, "", 0.0, STR|NUM, symtab);
+				RET(IVAR);
+			} else {
+				unputstr(buf);
+				RET(INDIRECT);
+			}
+	
+		case '}':
+			if (--bracecnt < 0)
+				SYNTAX( "extra }" );
+			sc = 1;
+			RET(';');
+		case ']':
+			if (--brackcnt < 0)
+				SYNTAX( "extra ]" );
+			RET(']');
+		case ')':
+			if (--parencnt < 0)
+				SYNTAX( "extra )" );
+			RET(')');
+		case '{':
+			bracecnt++;
+			RET('{');
+		case '[':
+			brackcnt++;
+			RET('[');
+		case '(':
+			parencnt++;
+			RET('(');
+	
+		case '"':
+			return string();	/* BUG: should be like tran.c ? */
+	
+		default:
+			RET(c);
+		}
+	}
+}
+
+int string(void)
+{
+	int c, n;
+	char *s, *bp;
+	static char *buf = 0;
+	static int bufsz = 500;
+
+	if (buf == 0 && (buf = (char *) malloc(bufsz)) == NULL)
+		FATAL("out of space for strings");
+	for (bp = buf; (c = input()) != '"'; ) {
+		if (!adjbuf(&buf, &bufsz, bp-buf+2, 500, &bp, 0))
+			FATAL("out of space for string %.10s...", buf);
+		switch (c) {
+		case '\n':
+		case '\r':
+		case 0:
+			SYNTAX( "non-terminated string %.10s...", buf );
+			lineno++;
+			break;
+		case '\\':
+			c = input();
+			switch (c) {
+			case '"': *bp++ = '"'; break;
+			case 'n': *bp++ = '\n'; break;	
+			case 't': *bp++ = '\t'; break;
+			case 'f': *bp++ = '\f'; break;
+			case 'r': *bp++ = '\r'; break;
+			case 'b': *bp++ = '\b'; break;
+			case 'v': *bp++ = '\v'; break;
+			case 'a': *bp++ = '\007'; break;
+			case '\\': *bp++ = '\\'; break;
+
+			case '0': case '1': case '2': /* octal: \d \dd \ddd */
+			case '3': case '4': case '5': case '6': case '7':
+				n = c - '0';
+				if ((c = peek()) >= '0' && c < '8') {
+					n = 8 * n + input() - '0';
+					if ((c = peek()) >= '0' && c < '8')
+						n = 8 * n + input() - '0';
+				}
+				*bp++ = n;
+				break;
+
+			case 'x':	/* hex  \x0-9a-fA-F + */
+			    {	char xbuf[100], *px;
+				for (px = xbuf; (c = input()) != 0 && px-xbuf < 100-2; ) {
+					if (isdigit(c)
+					 || (c >= 'a' && c <= 'f')
+					 || (c >= 'A' && c <= 'F'))
+						*px++ = c;
+					else
+						break;
+				}
+				*px = 0;
+				unput(c);
+	  			sscanf(xbuf, "%x", &n);
+				*bp++ = n;
+				break;
+			    }
+
+			default: 
+				*bp++ = c;
+				break;
+			}
+			break;
+		default:
+			*bp++ = c;
+			break;
+		}
+	}
+	*bp = 0; 
+	s = tostring(buf);
+	*bp++ = ' '; *bp++ = 0;
+	yylval.cp = setsymtab(buf, s, 0.0, CON|STR|DONTFREE, symtab);
+	RET(STRING);
+}
+
+
+int binsearch(char *w, Keyword *kp, int n)
+{
+	int cond, low, mid, high;
+
+	low = 0;
+	high = n - 1;
+	while (low <= high) {
+		mid = (low + high) / 2;
+		if ((cond = strcmp(w, kp[mid].word)) < 0)
+			high = mid - 1;
+		else if (cond > 0)
+			low = mid + 1;
+		else
+			return mid;
+	}
+	return -1;
+}
+
+int word(char *w) 
+{
+	Keyword *kp;
+	int c, n;
+
+	n = binsearch(w, keywords, sizeof(keywords)/sizeof(keywords[0]));
+	kp = keywords + n;
+	if (n != -1) {	/* found in table */
+		yylval.i = kp->sub;
+		switch (kp->type) {	/* special handling */
+		case FSYSTEM:
+			if (safe)
+				SYNTAX( "system is unsafe" );
+			RET(kp->type);
+		case FUNC:
+			if (infunc)
+				SYNTAX( "illegal nested function" );
+			RET(kp->type);
+		case RETURN:
+			if (!infunc)
+				SYNTAX( "return not in function" );
+			RET(kp->type);
+		case VARNF:
+			yylval.cp = setsymtab("NF", "", 0.0, NUM, symtab);
+			RET(VARNF);
+		default:
+			RET(kp->type);
+		}
+	}
+	c = peek();	/* look for '(' */
+	if (c != '(' && infunc && (n=isarg(w)) >= 0) {
+		yylval.i = n;
+		RET(ARG);
+	} else {
+		yylval.cp = setsymtab(w, "", 0.0, STR|NUM|DONTFREE, symtab);
+		if (c == '(') {
+			RET(CALL);
+		} else {
+			RET(VAR);
+		}
+	}
+}
+
+void startreg(void)	/* next call to yyles will return a regular expression */
+{
+	reg = 1;
+}
+
+int regexpr(void)
+{
+	int c;
+	static char *buf = 0;
+	static int bufsz = 500;
+	char *bp;
+
+	if (buf == 0 && (buf = (char *) malloc(bufsz)) == NULL)
+		FATAL("out of space for rex expr");
+	bp = buf;
+	for ( ; (c = input()) != '/' && c != 0; ) {
+		if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, 0))
+			FATAL("out of space for reg expr %.10s...", buf);
+		if (c == '\n') {
+			SYNTAX( "newline in regular expression %.10s...", buf ); 
+			unput('\n');
+			break;
+		} else if (c == '\\') {
+			*bp++ = '\\'; 
+			*bp++ = input();
+		} else {
+			*bp++ = c;
+		}
+	}
+	*bp = 0;
+	yylval.s = tostring(buf);
+	unput('/');
+	RET(REGEXPR);
+}
+
+/* low-level lexical stuff, sort of inherited from lex */
+
+char	ebuf[300];
+char	*ep = ebuf;
+char	yysbuf[100];	/* pushback buffer */
+char	*yysptr = yysbuf;
+FILE	*yyin = 0;
+
+int input(void)	/* get next lexical input character */
+{
+	int c;
+	extern char *lexprog;
+
+	if (yysptr > yysbuf)
+		c = *--yysptr;
+	else if (lexprog != NULL) {	/* awk '...' */
+		if ((c = *lexprog) != 0)
+			lexprog++;
+	} else				/* awk -f ... */
+		c = pgetc();
+	if (c == '\n')
+		lineno++;
+	else if (c == EOF)
+		c = 0;
+	if (ep >= ebuf + sizeof ebuf)
+		ep = ebuf;
+	return *ep++ = c;
+}
+
+void unput(int c)	/* put lexical character back on input */
+{
+	if (c == '\n')
+		lineno--;
+	if (yysptr >= yysbuf + sizeof(yysbuf))
+		FATAL("pushed back too much: %.20s...", yysbuf);
+	*yysptr++ = c;
+	if (--ep < ebuf)
+		ep = ebuf + sizeof(ebuf) - 1;
+}
+
+void unputstr(char *s)	/* put a string back on input */
+{
+	int i;
+
+	for (i = strlen(s)-1; i >= 0; i--)
+		unput(s[i]);
+}
+
diff --git a/src/cmd/awk/lib.c b/src/cmd/awk/lib.c
new file mode 100644
index 0000000..6a6849c
--- /dev/null
+++ b/src/cmd/awk/lib.c
@@ -0,0 +1,713 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+#define DEBUG
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "awk.h"
+#include "y.tab.h"
+
+FILE	*infile	= NULL;
+char	*file	= "";
+char	*record;
+int	recsize	= RECSIZE;
+char	*fields;
+int	fieldssize = RECSIZE;
+
+Cell	**fldtab;	/* pointers to Cells */
+char	inputFS[100] = " ";
+
+#define	MAXFLD	200
+int	nfields	= MAXFLD;	/* last allocated slot for $i */
+
+int	donefld;	/* 1 = implies rec broken into fields */
+int	donerec;	/* 1 = record is valid (no flds have changed) */
+
+int	lastfld	= 0;	/* last used field */
+int	argno	= 1;	/* current input argument number */
+extern	Awkfloat *ARGC;
+
+static Cell dollar0 = { OCELL, CFLD, NULL, "", 0.0, REC|STR|DONTFREE };
+static Cell dollar1 = { OCELL, CFLD, NULL, "", 0.0, FLD|STR|DONTFREE };
+
+void recinit(unsigned int n)
+{
+	record = (char *) malloc(n);
+	fields = (char *) malloc(n);
+	fldtab = (Cell **) malloc((nfields+1) * sizeof(Cell *));
+	if (record == NULL || fields == NULL || fldtab == NULL)
+		FATAL("out of space for $0 and fields");
+	fldtab[0] = (Cell *) malloc(sizeof (Cell));
+	*fldtab[0] = dollar0;
+	fldtab[0]->sval = record;
+	fldtab[0]->nval = tostring("0");
+	makefields(1, nfields);
+}
+
+void makefields(int n1, int n2)		/* create $n1..$n2 inclusive */
+{
+	char temp[50];
+	int i;
+
+	for (i = n1; i <= n2; i++) {
+		fldtab[i] = (Cell *) malloc(sizeof (struct Cell));
+		if (fldtab[i] == NULL)
+			FATAL("out of space in makefields %d", i);
+		*fldtab[i] = dollar1;
+		sprintf(temp, "%d", i);
+		fldtab[i]->nval = tostring(temp);
+	}
+}
+
+void initgetrec(void)
+{
+	int i;
+	char *p;
+
+	for (i = 1; i < *ARGC; i++) {
+		if (!isclvar(p = getargv(i))) {	/* find 1st real filename */
+			setsval(lookup("FILENAME", symtab), getargv(i));
+			return;
+		}
+		setclvar(p);	/* a commandline assignment before filename */
+		argno++;
+	}
+	infile = stdin;		/* no filenames, so use stdin */
+}
+
+int getrec(char **pbuf, int *pbufsize, int isrecord)	/* get next input record */
+{			/* note: cares whether buf == record */
+	int c;
+	static int firsttime = 1;
+	char *buf = *pbuf;
+	int bufsize = *pbufsize;
+
+	if (firsttime) {
+		firsttime = 0;
+		initgetrec();
+	}
+	   dprintf( ("RS=<%s>, FS=<%s>, ARGC=%g, FILENAME=%s\n",
+		*RS, *FS, *ARGC, *FILENAME) );
+	if (isrecord) {
+		donefld = 0;
+		donerec = 1;
+	}
+	buf[0] = 0;
+	while (argno < *ARGC || infile == stdin) {
+		   dprintf( ("argno=%d, file=|%s|\n", argno, file) );
+		if (infile == NULL) {	/* have to open a new file */
+			file = getargv(argno);
+			if (*file == '\0') {	/* it's been zapped */
+				argno++;
+				continue;
+			}
+			if (isclvar(file)) {	/* a var=value arg */
+				setclvar(file);
+				argno++;
+				continue;
+			}
+			*FILENAME = file;
+			   dprintf( ("opening file %s\n", file) );
+			if (*file == '-' && *(file+1) == '\0')
+				infile = stdin;
+			else if ((infile = fopen(file, "r")) == NULL)
+				FATAL("can't open file %s", file);
+			setfval(fnrloc, 0.0);
+		}
+		c = readrec(&buf, &bufsize, infile);
+		if (c != 0 || buf[0] != '\0') {	/* normal record */
+			if (isrecord) {
+				if (freeable(fldtab[0]))
+					xfree(fldtab[0]->sval);
+				fldtab[0]->sval = buf;	/* buf == record */
+				fldtab[0]->tval = REC | STR | DONTFREE;
+				if (is_number(fldtab[0]->sval)) {
+					fldtab[0]->fval = atof(fldtab[0]->sval);
+					fldtab[0]->tval |= NUM;
+				}
+			}
+			setfval(nrloc, nrloc->fval+1);
+			setfval(fnrloc, fnrloc->fval+1);
+			*pbuf = buf;
+			*pbufsize = bufsize;
+			return 1;
+		}
+		/* EOF arrived on this file; set up next */
+		if (infile != stdin)
+			fclose(infile);
+		infile = NULL;
+		argno++;
+	}
+	*pbuf = buf;
+	*pbufsize = bufsize;
+	return 0;	/* true end of file */
+}
+
+void nextfile(void)
+{
+	if (infile != stdin)
+		fclose(infile);
+	infile = NULL;
+	argno++;
+}
+
+int readrec(char **pbuf, int *pbufsize, FILE *inf)	/* read one record into buf */
+{
+	int sep, c;
+	char *rr, *buf = *pbuf;
+	int bufsize = *pbufsize;
+
+	if (strlen(*FS) >= sizeof(inputFS))
+		FATAL("field separator %.10s... is too long", *FS);
+	strcpy(inputFS, *FS);	/* for subsequent field splitting */
+	if ((sep = **RS) == 0) {
+		sep = '\n';
+		while ((c=getc(inf)) == '\n' && c != EOF)	/* skip leading \n's */
+			;
+		if (c != EOF)
+			ungetc(c, inf);
+	}
+	for (rr = buf; ; ) {
+		for (; (c=getc(inf)) != sep && c != EOF; ) {
+			if (rr-buf+1 > bufsize)
+				if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readrec 1"))
+					FATAL("input record `%.30s...' too long", buf);
+			*rr++ = c;
+		}
+		if (**RS == sep || c == EOF)
+			break;
+		if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
+			break;
+		if (!adjbuf(&buf, &bufsize, 2+rr-buf, recsize, &rr, "readrec 2"))
+			FATAL("input record `%.30s...' too long", buf);
+		*rr++ = '\n';
+		*rr++ = c;
+	}
+	if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readrec 3"))
+		FATAL("input record `%.30s...' too long", buf);
+	*rr = 0;
+	   dprintf( ("readrec saw <%s>, returns %d\n", buf, c == EOF && rr == buf ? 0 : 1) );
+	*pbuf = buf;
+	*pbufsize = bufsize;
+	return c == EOF && rr == buf ? 0 : 1;
+}
+
+char *getargv(int n)	/* get ARGV[n] */
+{
+	Cell *x;
+	char *s, temp[50];
+	extern Array *ARGVtab;
+
+	sprintf(temp, "%d", n);
+	x = setsymtab(temp, "", 0.0, STR, ARGVtab);
+	s = getsval(x);
+	   dprintf( ("getargv(%d) returns |%s|\n", n, s) );
+	return s;
+}
+
+void setclvar(char *s)	/* set var=value from s */
+{
+	char *p;
+	Cell *q;
+
+	for (p=s; *p != '='; p++)
+		;
+	*p++ = 0;
+	p = qstring(p, '\0');
+	q = setsymtab(s, p, 0.0, STR, symtab);
+	setsval(q, p);
+	if (is_number(q->sval)) {
+		q->fval = atof(q->sval);
+		q->tval |= NUM;
+	}
+	   dprintf( ("command line set %s to |%s|\n", s, p) );
+}
+
+
+void fldbld(void)	/* create fields from current record */
+{
+	/* this relies on having fields[] the same length as $0 */
+	/* the fields are all stored in this one array with \0's */
+	char *r, *fr, sep;
+	Cell *p;
+	int i, j, n;
+
+	if (donefld)
+		return;
+	if (!isstr(fldtab[0]))
+		getsval(fldtab[0]);
+	r = fldtab[0]->sval;
+	n = strlen(r);
+	if (n > fieldssize) {
+		xfree(fields);
+		if ((fields = (char *) malloc(n+1)) == NULL)
+			FATAL("out of space for fields in fldbld %d", n);
+		fieldssize = n;
+	}
+	fr = fields;
+	i = 0;	/* number of fields accumulated here */
+	if (strlen(inputFS) > 1) {	/* it's a regular expression */
+		i = refldbld(r, inputFS);
+	} else if ((sep = *inputFS) == ' ') {	/* default whitespace */
+		for (i = 0; ; ) {
+			while (*r == ' ' || *r == '\t' || *r == '\n')
+				r++;
+			if (*r == 0)
+				break;
+			i++;
+			if (i > nfields)
+				growfldtab(i);
+			if (freeable(fldtab[i]))
+				xfree(fldtab[i]->sval);
+			fldtab[i]->sval = fr;
+			fldtab[i]->tval = FLD | STR | DONTFREE;
+			do
+				*fr++ = *r++;
+			while (*r != ' ' && *r != '\t' && *r != '\n' && *r != '\0');
+			*fr++ = 0;
+		}
+		*fr = 0;
+	} else if ((sep = *inputFS) == 0) {		/* new: FS="" => 1 char/field */
+		for (i = 0; *r != 0; r++) {
+			char buf[2];
+			i++;
+			if (i > nfields)
+				growfldtab(i);
+			if (freeable(fldtab[i]))
+				xfree(fldtab[i]->sval);
+			buf[0] = *r;
+			buf[1] = 0;
+			fldtab[i]->sval = tostring(buf);
+			fldtab[i]->tval = FLD | STR;
+		}
+		*fr = 0;
+	} else if (*r != 0) {	/* if 0, it's a null field */
+		for (;;) {
+			i++;
+			if (i > nfields)
+				growfldtab(i);
+			if (freeable(fldtab[i]))
+				xfree(fldtab[i]->sval);
+			fldtab[i]->sval = fr;
+			fldtab[i]->tval = FLD | STR | DONTFREE;
+			while (*r != sep && *r != '\n' && *r != '\0')	/* \n is always a separator */
+				*fr++ = *r++;
+			*fr++ = 0;
+			if (*r++ == 0)
+				break;
+		}
+		*fr = 0;
+	}
+	if (i > nfields)
+		FATAL("record `%.30s...' has too many fields; can't happen", r);
+	cleanfld(i+1, lastfld);	/* clean out junk from previous record */
+	lastfld = i;
+	donefld = 1;
+	for (j = 1; j <= lastfld; j++) {
+		p = fldtab[j];
+		if(is_number(p->sval)) {
+			p->fval = atof(p->sval);
+			p->tval |= NUM;
+		}
+	}
+	setfval(nfloc, (Awkfloat) lastfld);
+	if (dbg) {
+		for (j = 0; j <= lastfld; j++) {
+			p = fldtab[j];
+			printf("field %d (%s): |%s|\n", j, p->nval, p->sval);
+		}
+	}
+}
+
+void cleanfld(int n1, int n2)	/* clean out fields n1 .. n2 inclusive */
+{				/* nvals remain intact */
+	Cell *p;
+	int i;
+
+	for (i = n1; i <= n2; i++) {
+		p = fldtab[i];
+		if (freeable(p))
+			xfree(p->sval);
+		p->sval = "";
+		p->tval = FLD | STR | DONTFREE;
+	}
+}
+
+void newfld(int n)	/* add field n after end of existing lastfld */
+{
+	if (n > nfields)
+		growfldtab(n);
+	cleanfld(lastfld+1, n);
+	lastfld = n;
+	setfval(nfloc, (Awkfloat) n);
+}
+
+Cell *fieldadr(int n)	/* get nth field */
+{
+	if (n < 0)
+		FATAL("trying to access field %d", n);
+	if (n > nfields)	/* fields after NF are empty */
+		growfldtab(n);	/* but does not increase NF */
+	return(fldtab[n]);
+}
+
+void growfldtab(int n)	/* make new fields up to at least $n */
+{
+	int nf = 2 * nfields;
+
+	if (n > nf)
+		nf = n;
+	fldtab = (Cell **) realloc(fldtab, (nf+1) * (sizeof (struct Cell *)));
+	if (fldtab == NULL)
+		FATAL("out of space creating %d fields", nf);
+	makefields(nfields+1, nf);
+	nfields = nf;
+}
+
+int refldbld(char *rec, char *fs)	/* build fields from reg expr in FS */
+{
+	/* this relies on having fields[] the same length as $0 */
+	/* the fields are all stored in this one array with \0's */
+	char *fr;
+	void *p;
+	int i, n;
+
+	n = strlen(rec);
+	if (n > fieldssize) {
+		xfree(fields);
+		if ((fields = (char *) malloc(n+1)) == NULL)
+			FATAL("out of space for fields in refldbld %d", n);
+		fieldssize = n;
+	}
+	fr = fields;
+	*fr = '\0';
+	if (*rec == '\0')
+		return 0;
+	p = compre(fs);
+	   dprintf( ("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs) );
+	for (i = 1; ; i++) {
+		if (i > nfields)
+			growfldtab(i);
+		if (freeable(fldtab[i]))
+			xfree(fldtab[i]->sval);
+		fldtab[i]->tval = FLD | STR | DONTFREE;
+		fldtab[i]->sval = fr;
+		   dprintf( ("refldbld: i=%d\n", i) );
+		if (nematch(p, rec, rec)) {
+			   dprintf( ("match %s (%d chars)\n", patbeg, patlen) );
+			strncpy(fr, rec, patbeg-rec);
+			fr += patbeg - rec + 1;
+			*(fr-1) = '\0';
+			rec = patbeg + patlen;
+		} else {
+			   dprintf( ("no match %s\n", rec) );
+			strcpy(fr, rec);
+			break;
+		}
+	}
+	return i;		
+}
+
+void recbld(void)	/* create $0 from $1..$NF if necessary */
+{
+	int i;
+	char *r, *p;
+
+	if (donerec == 1)
+		return;
+	r = record;
+	for (i = 1; i <= *NF; i++) {
+		p = getsval(fldtab[i]);
+		if (!adjbuf(&record, &recsize, 1+strlen(p)+r-record, recsize, &r, "recbld 1"))
+			FATAL("created $0 `%.30s...' too long", record);
+		while ((*r = *p++) != 0)
+			r++;
+		if (i < *NF) {
+			if (!adjbuf(&record, &recsize, 2+strlen(*OFS)+r-record, recsize, &r, "recbld 2"))
+				FATAL("created $0 `%.30s...' too long", record);
+			for (p = *OFS; (*r = *p++) != 0; )
+				r++;
+		}
+	}
+	if (!adjbuf(&record, &recsize, 2+r-record, recsize, &r, "recbld 3"))
+		FATAL("built giant record `%.30s...'", record);
+	*r = '\0';
+	   dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, fldtab[0]) );
+
+	if (freeable(fldtab[0]))
+		xfree(fldtab[0]->sval);
+	fldtab[0]->tval = REC | STR | DONTFREE;
+	fldtab[0]->sval = record;
+
+	   dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, fldtab[0]) );
+	   dprintf( ("recbld = |%s|\n", record) );
+	donerec = 1;
+}
+
+int	errorflag	= 0;
+
+void yyerror(char *s)
+{
+	SYNTAX(s);
+}
+
+void SYNTAX(char *fmt, ...)
+{
+	extern char *cmdname, *curfname;
+	static int been_here = 0;
+	va_list varg;
+
+	if (been_here++ > 2)
+		return;
+	fprintf(stderr, "%s: ", cmdname);
+	va_start(varg, fmt);
+	vfprintf(stderr, fmt, varg);
+	va_end(varg);
+	if(compile_time == 1 && cursource() != NULL)
+		fprintf(stderr, " at %s:%d", cursource(), lineno);
+	else
+		fprintf(stderr, " at line %d", lineno);
+	if (curfname != NULL)
+		fprintf(stderr, " in function %s", curfname);
+	fprintf(stderr, "\n");
+	errorflag = 2;
+	eprint();
+}
+
+void fpecatch(int n)
+{
+	FATAL("floating point exception %d", n);
+}
+
+extern int bracecnt, brackcnt, parencnt;
+
+void bracecheck(void)
+{
+	int c;
+	static int beenhere = 0;
+
+	if (beenhere++)
+		return;
+	while ((c = input()) != EOF && c != '\0')
+		bclass(c);
+	bcheck2(bracecnt, '{', '}');
+	bcheck2(brackcnt, '[', ']');
+	bcheck2(parencnt, '(', ')');
+}
+
+void bcheck2(int n, int c1, int c2)
+{
+	if (n == 1)
+		fprintf(stderr, "\tmissing %c\n", c2);
+	else if (n > 1)
+		fprintf(stderr, "\t%d missing %c's\n", n, c2);
+	else if (n == -1)
+		fprintf(stderr, "\textra %c\n", c2);
+	else if (n < -1)
+		fprintf(stderr, "\t%d extra %c's\n", -n, c2);
+}
+
+void FATAL(char *fmt, ...)
+{
+	extern char *cmdname;
+	va_list varg;
+
+	fflush(stdout);
+	fprintf(stderr, "%s: ", cmdname);
+	va_start(varg, fmt);
+	vfprintf(stderr, fmt, varg);
+	va_end(varg);
+	error();
+	if (dbg > 1)		/* core dump if serious debugging on */
+		abort();
+	exit(2);
+}
+
+void WARNING(char *fmt, ...)
+{
+	extern char *cmdname;
+	va_list varg;
+
+	fflush(stdout);
+	fprintf(stderr, "%s: ", cmdname);
+	va_start(varg, fmt);
+	vfprintf(stderr, fmt, varg);
+	va_end(varg);
+	error();
+}
+
+void error()
+{
+	extern Node *curnode;
+	int line;
+
+	fprintf(stderr, "\n");
+	if (compile_time != 2 && NR && *NR > 0) {
+		if (strcmp(*FILENAME, "-") != 0)
+			fprintf(stderr, " input record %s:%d", *FILENAME, (int) (*FNR));
+		else
+			fprintf(stderr, " input record number %d", (int) (*FNR));
+		fprintf(stderr, "\n");
+	}
+	if (compile_time != 2 && curnode)
+		line = curnode->lineno;
+	else if (compile_time != 2 && lineno)
+		line = lineno;
+	else
+		line = -1;
+	if (compile_time == 1 && cursource() != NULL){
+		if(line >= 0)
+			fprintf(stderr, " source %s:%d", cursource(), line);
+		else
+			fprintf(stderr, " source file %s", cursource());
+	}else if(line >= 0)
+		fprintf(stderr, " source line %d", line);
+	fprintf(stderr, "\n");
+	eprint();
+}
+
+void eprint(void)	/* try to print context around error */
+{
+	char *p, *q;
+	int c;
+	static int been_here = 0;
+	extern char ebuf[], *ep;
+
+	if (compile_time == 2 || compile_time == 0 || been_here++ > 0)
+		return;
+	p = ep - 1;
+	if (p > ebuf && *p == '\n')
+		p--;
+	for ( ; p > ebuf && *p != '\n' && *p != '\0'; p--)
+		;
+	while (*p == '\n')
+		p++;
+	fprintf(stderr, " context is\n\t");
+	for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)
+		;
+	for ( ; p < q; p++)
+		if (*p)
+			putc(*p, stderr);
+	fprintf(stderr, " >>> ");
+	for ( ; p < ep; p++)
+		if (*p)
+			putc(*p, stderr);
+	fprintf(stderr, " <<< ");
+	if (*ep)
+		while ((c = input()) != '\n' && c != '\0' && c != EOF) {
+			putc(c, stderr);
+			bclass(c);
+		}
+	putc('\n', stderr);
+	ep = ebuf;
+}
+
+void bclass(int c)
+{
+	switch (c) {
+	case '{': bracecnt++; break;
+	case '}': bracecnt--; break;
+	case '[': brackcnt++; break;
+	case ']': brackcnt--; break;
+	case '(': parencnt++; break;
+	case ')': parencnt--; break;
+	}
+}
+
+double errcheck(double x, char *s)
+{
+
+	if (errno == EDOM) {
+		errno = 0;
+		WARNING("%s argument out of domain", s);
+		x = 1;
+	} else if (errno == ERANGE) {
+		errno = 0;
+		WARNING("%s result out of range", s);
+		x = 1;
+	}
+	return x;
+}
+
+int isclvar(char *s)	/* is s of form var=something ? */
+{
+	char *os = s;
+
+	if (!isalpha(*s) && *s != '_')
+		return 0;
+	for ( ; *s; s++)
+		if (!(isalnum(*s) || *s == '_'))
+			break;
+	return *s == '=' && s > os && *(s+1) != '=';
+}
+
+/* strtod is supposed to be a proper test of what's a valid number */
+
+#include <math.h>
+int is_number(char *s)
+{
+	double r;
+	char *ep;
+
+	/*
+	 * fast could-it-be-a-number check before calling strtod,
+	 * which takes a surprisingly long time to reject non-numbers.
+	 */
+	switch (*s) {
+	case '0': case '1': case '2': case '3': case '4':
+	case '5': case '6': case '7': case '8': case '9':
+	case '\t':
+	case '\n':
+	case '\v':
+	case '\f':
+	case '\r':
+	case ' ':
+	case '-':
+	case '+':
+	case '.':
+	case 'n':		/* nans */
+	case 'N':
+	case 'i':		/* infs */
+	case 'I':
+		break;
+	default:
+		return 0;	/* can't be a number */
+	}
+
+	errno = 0;
+	r = strtod(s, &ep);
+	if (ep == s || r == HUGE_VAL || errno == ERANGE)
+		return 0;
+	while (*ep == ' ' || *ep == '\t' || *ep == '\n')
+		ep++;
+	if (*ep == '\0')
+		return 1;
+	else
+		return 0;
+}
+
diff --git a/src/cmd/awk/main.c b/src/cmd/awk/main.c
new file mode 100644
index 0000000..ea20f63
--- /dev/null
+++ b/src/cmd/awk/main.c
@@ -0,0 +1,198 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+char	*version = "version 19990602";
+
+#define DEBUG
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include "awk.h"
+#include "y.tab.h"
+
+extern	char	**environ;
+extern	int	nfields;
+
+int	dbg	= 0;
+char	*cmdname;	/* gets argv[0] for error messages */
+extern	FILE	*yyin;	/* lex input file */
+char	*lexprog;	/* points to program argument if it exists */
+extern	int errorflag;	/* non-zero if any syntax errors; set by yyerror */
+int	compile_time = 2;	/* for error printing: */
+				/* 2 = cmdline, 1 = compile, 0 = running */
+
+char	*pfile[20];	/* program filenames from -f's */
+int	npfile = 0;	/* number of filenames */
+int	curpfile = 0;	/* current filename */
+
+int	safe	= 0;	/* 1 => "safe" mode */
+
+int main(int argc, char *argv[])
+{
+	char *fs = NULL, *marg;
+	int temp;
+
+	cmdname = argv[0];
+	if (argc == 1) {
+		fprintf(stderr, "Usage: %s [-F fieldsep] [-mf n] [-mr n] [-v var=value] [-f programfile | 'program'] [file ...]\n", cmdname);
+		exit(1);
+	}
+	signal(SIGFPE, fpecatch);
+	yyin = NULL;
+	symtab = makesymtab(NSYMTAB);
+	while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
+		if (strcmp(argv[1], "--") == 0) {	/* explicit end of args */
+			argc--;
+			argv++;
+			break;
+		}
+		switch (argv[1][1]) {
+		case 's':
+			if (strcmp(argv[1], "-safe") == 0)
+				safe = 1;
+			break;
+		case 'f':	/* next argument is program filename */
+			argc--;
+			argv++;
+			if (argc <= 1)
+				FATAL("no program filename");
+			pfile[npfile++] = argv[1];
+			break;
+		case 'F':	/* set field separator */
+			if (argv[1][2] != 0) {	/* arg is -Fsomething */
+				if (argv[1][2] == 't' && argv[1][3] == 0)	/* wart: t=>\t */
+					fs = "\t";
+				else if (argv[1][2] != 0)
+					fs = &argv[1][2];
+			} else {		/* arg is -F something */
+				argc--; argv++;
+				if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0)	/* wart: t=>\t */
+					fs = "\t";
+				else if (argc > 1 && argv[1][0] != 0)
+					fs = &argv[1][0];
+			}
+			if (fs == NULL || *fs == '\0')
+				WARNING("field separator FS is empty");
+			break;
+		case 'v':	/* -v a=1 to be done NOW.  one -v for each */
+			if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
+				setclvar(argv[1]);
+			break;
+		case 'm':	/* more memory: -mr=record, -mf=fields */
+				/* no longer needed */
+			marg = argv[1];
+			if (argv[1][3])
+				temp = atoi(&argv[1][3]);
+			else {
+				argv++; argc--;
+				temp = atoi(&argv[1][0]);
+			}
+			switch (marg[2]) {
+			case 'r':	recsize = temp; break;
+			case 'f':	nfields = temp; break;
+			default: FATAL("unknown option %s\n", marg);
+			}
+			break;
+		case 'd':
+			dbg = atoi(&argv[1][2]);
+			if (dbg == 0)
+				dbg = 1;
+			printf("awk %s\n", version);
+			break;
+		case 'V':	/* added for exptools "standard" */
+			printf("awk %s\n", version);
+			exit(0);
+			break;
+		default:
+			WARNING("unknown option %s ignored", argv[1]);
+			break;
+		}
+		argc--;
+		argv++;
+	}
+	/* argv[1] is now the first argument */
+	if (npfile == 0) {	/* no -f; first argument is program */
+		if (argc <= 1) {
+			if (dbg)
+				exit(0);
+			FATAL("no program given");
+		}
+		   dprintf( ("program = |%s|\n", argv[1]) );
+		lexprog = argv[1];
+		argc--;
+		argv++;
+	}
+	recinit(recsize);
+	syminit();
+	compile_time = 1;
+	argv[0] = cmdname;	/* put prog name at front of arglist */
+	   dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
+	arginit(argc, argv);
+	if (!safe)
+		envinit(environ);
+	yyparse();
+	if (fs)
+		*FS = qstring(fs, '\0');
+	   dprintf( ("errorflag=%d\n", errorflag) );
+	if (errorflag == 0) {
+		compile_time = 0;
+		run(winner);
+	} else
+		bracecheck();
+	return(errorflag);
+}
+
+int pgetc(void)		/* get 1 character from awk program */
+{
+	int c;
+
+	for (;;) {
+		if (yyin == NULL) {
+			if (curpfile >= npfile)
+				return EOF;
+			if (strcmp(pfile[curpfile], "-") == 0)
+				yyin = stdin;
+			else if ((yyin = fopen(pfile[curpfile], "r")) == NULL)
+				FATAL("can't open file %s", pfile[curpfile]);
+			lineno = 1;
+		}
+		if ((c = getc(yyin)) != EOF)
+			return c;
+		if (yyin != stdin)
+			fclose(yyin);
+		yyin = NULL;
+		curpfile++;
+	}
+}
+
+char *cursource(void)	/* current source file name */
+{
+	if (npfile > 0)
+		return pfile[curpfile];
+	else
+		return NULL;
+}
+
diff --git a/src/cmd/awk/maketab.c b/src/cmd/awk/maketab.c
new file mode 100644
index 0000000..50908ce
--- /dev/null
+++ b/src/cmd/awk/maketab.c
@@ -0,0 +1,169 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+/*
+ * this program makes the table to link function names
+ * and type indices that is used by execute() in run.c.
+ * it finds the indices in y.tab.h, produced by yacc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "awk.h"
+#include "y.tab.h"
+
+struct xx
+{	int token;
+	char *name;
+	char *pname;
+} proc[] = {
+	{ PROGRAM, "program", NULL },
+	{ BOR, "boolop", " || " },
+	{ AND, "boolop", " && " },
+	{ NOT, "boolop", " !" },
+	{ NE, "relop", " != " },
+	{ EQ, "relop", " == " },
+	{ LE, "relop", " <= " },
+	{ LT, "relop", " < " },
+	{ GE, "relop", " >= " },
+	{ GT, "relop", " > " },
+	{ ARRAY, "array", NULL },
+	{ INDIRECT, "indirect", "$(" },
+	{ SUBSTR, "substr", "substr" },
+	{ SUB, "sub", "sub" },
+	{ GSUB, "gsub", "gsub" },
+	{ INDEX, "sindex", "sindex" },
+	{ SPRINTF, "awksprintf", "sprintf " },
+	{ ADD, "arith", " + " },
+	{ MINUS, "arith", " - " },
+	{ MULT, "arith", " * " },
+	{ DIVIDE, "arith", " / " },
+	{ MOD, "arith", " % " },
+	{ UMINUS, "arith", " -" },
+	{ POWER, "arith", " **" },
+	{ PREINCR, "incrdecr", "++" },
+	{ POSTINCR, "incrdecr", "++" },
+	{ PREDECR, "incrdecr", "--" },
+	{ POSTDECR, "incrdecr", "--" },
+	{ CAT, "cat", " " },
+	{ PASTAT, "pastat", NULL },
+	{ PASTAT2, "dopa2", NULL },
+	{ MATCH, "matchop", " ~ " },
+	{ NOTMATCH, "matchop", " !~ " },
+	{ MATCHFCN, "matchop", "matchop" },
+	{ INTEST, "intest", "intest" },
+	{ PRINTF, "awkprintf", "printf" },
+	{ PRINT, "printstat", "print" },
+	{ CLOSE, "closefile", "closefile" },
+	{ DELETE, "awkdelete", "awkdelete" },
+	{ SPLIT, "split", "split" },
+	{ ASSIGN, "assign", " = " },
+	{ ADDEQ, "assign", " += " },
+	{ SUBEQ, "assign", " -= " },
+	{ MULTEQ, "assign", " *= " },
+	{ DIVEQ, "assign", " /= " },
+	{ MODEQ, "assign", " %= " },
+	{ POWEQ, "assign", " ^= " },
+	{ CONDEXPR, "condexpr", " ?: " },
+	{ IF, "ifstat", "if(" },
+	{ WHILE, "whilestat", "while(" },
+	{ FOR, "forstat", "for(" },
+	{ DO, "dostat", "do" },
+	{ IN, "instat", "instat" },
+	{ NEXT, "jump", "next" },
+	{ NEXTFILE, "jump", "nextfile" },
+	{ EXIT, "jump", "exit" },
+	{ BREAK, "jump", "break" },
+	{ CONTINUE, "jump", "continue" },
+	{ RETURN, "jump", "ret" },
+	{ BLTIN, "bltin", "bltin" },
+	{ CALL, "call", "call" },
+	{ ARG, "arg", "arg" },
+	{ VARNF, "getnf", "NF" },
+	{ GETLINE, "getline", "getline" },
+	{ 0, "", "" },
+};
+
+#define SIZE	(LASTTOKEN - FIRSTTOKEN + 1)
+char *table[SIZE];
+char *names[SIZE];
+
+int main(int argc, char *argv[])
+{
+	struct xx *p;
+	int i, n, tok;
+	char c;
+	FILE *fp;
+	char buf[200], name[200], def[200];
+
+	printf("#include <stdio.h>\n");
+	printf("#include \"awk.h\"\n");
+	printf("#include \"y.tab.h\"\n\n");
+	for (i = SIZE; --i >= 0; )
+		names[i] = "";
+
+	if ((fp = fopen("y.tab.h", "r")) == NULL) {
+		fprintf(stderr, "maketab can't open y.tab.h!\n");
+		exit(1);
+	}
+	printf("static char *printname[%d] = {\n", SIZE);
+	i = 0;
+	while (fgets(buf, sizeof buf, fp) != NULL) {
+		n = sscanf(buf, "%1c %s %s %d", &c, def, name, &tok);
+		if (c != '#' || (n != 4 && strcmp(def,"define") != 0))	/* not a valid #define */
+			continue;
+		if (tok < FIRSTTOKEN || tok > LASTTOKEN) {
+			fprintf(stderr, "maketab funny token %d %s\n", tok, buf);
+			exit(1);
+		}
+		names[tok-FIRSTTOKEN] = (char *) malloc(strlen(name)+1);
+		strcpy(names[tok-FIRSTTOKEN], name);
+		printf("\t(char *) \"%s\",\t/* %d */\n", name, tok);
+		i++;
+	}
+	printf("};\n\n");
+
+	for (p=proc; p->token!=0; p++)
+		table[p->token-FIRSTTOKEN] = p->name;
+	printf("\nCell *(*proctab[%d])(Node **, int) = {\n", SIZE);
+	for (i=0; i<SIZE; i++)
+		if (table[i]==0)
+			printf("\tnullproc,\t/* %s */\n", names[i]);
+		else
+			printf("\t%s,\t/* %s */\n", table[i], names[i]);
+	printf("};\n\n");
+
+	printf("char *tokname(int n)\n");	/* print a tokname() function */
+	printf("{\n");
+	printf("	static char buf[100];\n\n");
+	printf("	if (n < FIRSTTOKEN || n > LASTTOKEN) {\n");
+	printf("		sprintf(buf, \"token %%d\", n);\n");
+	printf("		return buf;\n");
+	printf("	}\n");
+	printf("	return printname[n-FIRSTTOKEN];\n");
+	printf("}\n");
+	return 0;
+}
+
diff --git a/src/cmd/awk/mkfile b/src/cmd/awk/mkfile
new file mode 100644
index 0000000..a31472e
--- /dev/null
+++ b/src/cmd/awk/mkfile
@@ -0,0 +1,35 @@
+<$PLAN9/src/mkhdr
+
+TARG=awk
+OFILES=re.$O\
+	lex.$O\
+	main.$O\
+	parse.$O\
+	proctab.$O\
+	tran.$O\
+	lib.$O\
+	run.$O\
+	y.tab.$O\
+
+HFILES=awk.h\
+	y.tab.h\
+	proto.h\
+
+YFILES=awkgram.y
+
+CLEANFILES=$CLEANFILES proctab.c $O.maketab
+
+<$PLAN9/src/mkone
+
+# CFLAGS=-c -D_REGEXP_EXTENSION -D_RESEARCH_SOURCE -D_BSD_EXTENSION -DUTF
+
+YFLAGS=-S -d -v
+
+proctab.c: $O.maketab
+    ./$O.maketab >proctab.c
+
+maketab.$O: maketab.c
+    $CC $CFLAGS maketab.c
+
+$O.maketab:V: y.tab.h maketab.$O
+    $LD -o $O.maketab maketab.$O
diff --git a/src/cmd/awk/parse.c b/src/cmd/awk/parse.c
new file mode 100644
index 0000000..d4c8832
--- /dev/null
+++ b/src/cmd/awk/parse.c
@@ -0,0 +1,272 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+#define DEBUG
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "awk.h"
+#include "y.tab.h"
+
+Node *nodealloc(int n)
+{
+	Node *x;
+
+	x = (Node *) malloc(sizeof(Node) + (n-1)*sizeof(Node *));
+	if (x == NULL)
+		FATAL("out of space in nodealloc");
+	x->nnext = NULL;
+	x->lineno = lineno;
+	return(x);
+}
+
+Node *exptostat(Node *a)
+{
+	a->ntype = NSTAT;
+	return(a);
+}
+
+Node *node1(int a, Node *b)
+{
+	Node *x;
+
+	x = nodealloc(1);
+	x->nobj = a;
+	x->narg[0]=b;
+	return(x);
+}
+
+Node *node2(int a, Node *b, Node *c)
+{
+	Node *x;
+
+	x = nodealloc(2);
+	x->nobj = a;
+	x->narg[0] = b;
+	x->narg[1] = c;
+	return(x);
+}
+
+Node *node3(int a, Node *b, Node *c, Node *d)
+{
+	Node *x;
+
+	x = nodealloc(3);
+	x->nobj = a;
+	x->narg[0] = b;
+	x->narg[1] = c;
+	x->narg[2] = d;
+	return(x);
+}
+
+Node *node4(int a, Node *b, Node *c, Node *d, Node *e)
+{
+	Node *x;
+
+	x = nodealloc(4);
+	x->nobj = a;
+	x->narg[0] = b;
+	x->narg[1] = c;
+	x->narg[2] = d;
+	x->narg[3] = e;
+	return(x);
+}
+
+Node *stat1(int a, Node *b)
+{
+	Node *x;
+
+	x = node1(a,b);
+	x->ntype = NSTAT;
+	return(x);
+}
+
+Node *stat2(int a, Node *b, Node *c)
+{
+	Node *x;
+
+	x = node2(a,b,c);
+	x->ntype = NSTAT;
+	return(x);
+}
+
+Node *stat3(int a, Node *b, Node *c, Node *d)
+{
+	Node *x;
+
+	x = node3(a,b,c,d);
+	x->ntype = NSTAT;
+	return(x);
+}
+
+Node *stat4(int a, Node *b, Node *c, Node *d, Node *e)
+{
+	Node *x;
+
+	x = node4(a,b,c,d,e);
+	x->ntype = NSTAT;
+	return(x);
+}
+
+Node *op1(int a, Node *b)
+{
+	Node *x;
+
+	x = node1(a,b);
+	x->ntype = NEXPR;
+	return(x);
+}
+
+Node *op2(int a, Node *b, Node *c)
+{
+	Node *x;
+
+	x = node2(a,b,c);
+	x->ntype = NEXPR;
+	return(x);
+}
+
+Node *op3(int a, Node *b, Node *c, Node *d)
+{
+	Node *x;
+
+	x = node3(a,b,c,d);
+	x->ntype = NEXPR;
+	return(x);
+}
+
+Node *op4(int a, Node *b, Node *c, Node *d, Node *e)
+{
+	Node *x;
+
+	x = node4(a,b,c,d,e);
+	x->ntype = NEXPR;
+	return(x);
+}
+
+Node *celltonode(Cell *a, int b)
+{
+	Node *x;
+
+	a->ctype = OCELL;
+	a->csub = b;
+	x = node1(0, (Node *) a);
+	x->ntype = NVALUE;
+	return(x);
+}
+
+Node *rectonode(void)	/* make $0 into a Node */
+{
+	extern Cell *literal0;
+	return op1(INDIRECT, celltonode(literal0, CUNK));
+}
+
+Node *makearr(Node *p)
+{
+	Cell *cp;
+
+	if (isvalue(p)) {
+		cp = (Cell *) (p->narg[0]);
+		if (isfcn(cp))
+			SYNTAX( "%s is a function, not an array", cp->nval );
+		else if (!isarr(cp)) {
+			xfree(cp->sval);
+			cp->sval = (char *) makesymtab(NSYMTAB);
+			cp->tval = ARR;
+		}
+	}
+	return p;
+}
+
+#define PA2NUM	50	/* max number of pat,pat patterns allowed */
+int	paircnt;		/* number of them in use */
+int	pairstack[PA2NUM];	/* state of each pat,pat */
+
+Node *pa2stat(Node *a, Node *b, Node *c)	/* pat, pat {...} */
+{
+	Node *x;
+
+	x = node4(PASTAT2, a, b, c, itonp(paircnt));
+	if (paircnt++ >= PA2NUM)
+		SYNTAX( "limited to %d pat,pat statements", PA2NUM );
+	x->ntype = NSTAT;
+	return(x);
+}
+
+Node *linkum(Node *a, Node *b)
+{
+	Node *c;
+
+	if (errorflag)	/* don't link things that are wrong */
+		return a;
+	if (a == NULL)
+		return(b);
+	else if (b == NULL)
+		return(a);
+	for (c = a; c->nnext != NULL; c = c->nnext)
+		;
+	c->nnext = b;
+	return(a);
+}
+
+void defn(Cell *v, Node *vl, Node *st)	/* turn on FCN bit in definition, */
+{					/*   body of function, arglist */
+	Node *p;
+	int n;
+
+	if (isarr(v)) {
+		SYNTAX( "`%s' is an array name and a function name", v->nval );
+		return;
+	}
+	v->tval = FCN;
+	v->sval = (char *) st;
+	n = 0;	/* count arguments */
+	for (p = vl; p; p = p->nnext)
+		n++;
+	v->fval = n;
+	dprintf( ("defining func %s (%d args)\n", v->nval, n) );
+}
+
+int isarg(char *s)		/* is s in argument list for current function? */
+{			/* return -1 if not, otherwise arg # */
+	extern Node *arglist;
+	Node *p = arglist;
+	int n;
+
+	for (n = 0; p != 0; p = p->nnext, n++)
+		if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
+			return n;
+	return -1;
+}
+
+int ptoi(void *p)	/* convert pointer to integer */
+{
+	return (int) (long) p;	/* swearing that p fits, of course */
+}
+
+Node *itonp(int i)	/* and vice versa */
+{
+	return (Node *) (long) i;
+}
+
diff --git a/src/cmd/awk/proto.h b/src/cmd/awk/proto.h
new file mode 100644
index 0000000..1a50145
--- /dev/null
+++ b/src/cmd/awk/proto.h
@@ -0,0 +1,178 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+extern	int	yywrap(void);
+extern	void	setfname(Cell *);
+extern	int	constnode(Node *);
+extern	char	*strnode(Node *);
+extern	Node	*notnull(Node *);
+extern	int	yyparse(void);
+
+extern	int	yylex(void);
+extern	void	startreg(void);
+extern	int	input(void);
+extern	void	unput(int);
+extern	void	unputstr(char *);
+extern	int	yylook(void);
+extern	int	yyback(int *, int);
+extern	int	yyinput(void);
+
+extern	void	*compre(char *);
+extern	int	hexstr(char **);
+extern	void	quoted(char **, char **, char *);
+extern	int	match(void *, char *, char *);
+extern	int	pmatch(void *, char *, char *);
+extern	int	nematch(void *, char *, char *);
+extern	int	countposn(char *, int);
+extern	void	overflow(void);
+
+extern	int	pgetc(void);
+extern	char	*cursource(void);
+
+extern	Node	*nodealloc(int);
+extern	Node	*exptostat(Node *);
+extern	Node	*node1(int, Node *);
+extern	Node	*node2(int, Node *, Node *);
+extern	Node	*node3(int, Node *, Node *, Node *);
+extern	Node	*node4(int, Node *, Node *, Node *, Node *);
+extern	Node	*stat3(int, Node *, Node *, Node *);
+extern	Node	*op2(int, Node *, Node *);
+extern	Node	*op1(int, Node *);
+extern	Node	*stat1(int, Node *);
+extern	Node	*op3(int, Node *, Node *, Node *);
+extern	Node	*op4(int, Node *, Node *, Node *, Node *);
+extern	Node	*stat2(int, Node *, Node *);
+extern	Node	*stat4(int, Node *, Node *, Node *, Node *);
+extern	Node	*celltonode(Cell *, int);
+extern	Node	*rectonode(void);
+extern	Node	*makearr(Node *);
+extern	Node	*pa2stat(Node *, Node *, Node *);
+extern	Node	*linkum(Node *, Node *);
+extern	void	defn(Cell *, Node *, Node *);
+extern	int	isarg(char *);
+extern	char	*tokname(int);
+extern	Cell	*(*proctab[])(Node **, int);
+extern	int	ptoi(void *);
+extern	Node	*itonp(int);
+
+extern	void	syminit(void);
+extern	void	arginit(int, char **);
+extern	void	envinit(char **);
+extern	Array	*makesymtab(int);
+extern	void	freesymtab(Cell *);
+extern	void	freeelem(Cell *, char *);
+extern	Cell	*setsymtab(char *, char *, double, unsigned int, Array *);
+extern	int	hash(char *, int);
+extern	void	rehash(Array *);
+extern	Cell	*lookup(char *, Array *);
+extern	double	setfval(Cell *, double);
+extern	void	funnyvar(Cell *, char *);
+extern	char	*setsval(Cell *, char *);
+extern	double	getfval(Cell *);
+extern	char	*getsval(Cell *);
+extern	char	*tostring(char *);
+extern	char	*qstring(char *, int);
+
+extern	void	recinit(unsigned int);
+extern	void	initgetrec(void);
+extern	void	makefields(int, int);
+extern	void	growfldtab(int n);
+extern	int	getrec(char **, int *, int);
+extern	void	nextfile(void);
+extern	int	readrec(char **buf, int *bufsize, FILE *inf);
+extern	char	*getargv(int);
+extern	void	setclvar(char *);
+extern	void	fldbld(void);
+extern	void	cleanfld(int, int);
+extern	void	newfld(int);
+extern	int	refldbld(char *, char *);
+extern	void	recbld(void);
+extern	Cell	*fieldadr(int);
+extern	void	yyerror(char *);
+extern	void	fpecatch(int);
+extern	void	bracecheck(void);
+extern	void	bcheck2(int, int, int);
+extern	void	SYNTAX(char *, ...);
+extern	void	FATAL(char *, ...);
+extern	void	WARNING(char *, ...);
+extern	void	error(void);
+extern	void	eprint(void);
+extern	void	bclass(int);
+extern	double	errcheck(double, char *);
+extern	int	isclvar(char *);
+extern	int	is_number(char *);
+
+extern	int	adjbuf(char **pb, int *sz, int min, int q, char **pbp, char *what);
+extern	void	run(Node *);
+extern	Cell	*execute(Node *);
+extern	Cell	*program(Node **, int);
+extern	Cell	*call(Node **, int);
+extern	Cell	*copycell(Cell *);
+extern	Cell	*arg(Node **, int);
+extern	Cell	*jump(Node **, int);
+extern	Cell	*getline(Node **, int);
+extern	Cell	*getnf(Node **, int);
+extern	Cell	*array(Node **, int);
+extern	Cell	*awkdelete(Node **, int);
+extern	Cell	*intest(Node **, int);
+extern	Cell	*matchop(Node **, int);
+extern	Cell	*boolop(Node **, int);
+extern	Cell	*relop(Node **, int);
+extern	void	tfree(Cell *);
+extern	Cell	*gettemp(void);
+extern	Cell	*field(Node **, int);
+extern	Cell	*indirect(Node **, int);
+extern	Cell	*substr(Node **, int);
+extern	Cell	*sindex(Node **, int);
+extern	int	format(char **, int *, char *, Node *);
+extern	Cell	*awksprintf(Node **, int);
+extern	Cell	*awkprintf(Node **, int);
+extern	Cell	*arith(Node **, int);
+extern	double	ipow(double, int);
+extern	Cell	*incrdecr(Node **, int);
+extern	Cell	*assign(Node **, int);
+extern	Cell	*cat(Node **, int);
+extern	Cell	*pastat(Node **, int);
+extern	Cell	*dopa2(Node **, int);
+extern	Cell	*split(Node **, int);
+extern	Cell	*condexpr(Node **, int);
+extern	Cell	*ifstat(Node **, int);
+extern	Cell	*whilestat(Node **, int);
+extern	Cell	*dostat(Node **, int);
+extern	Cell	*forstat(Node **, int);
+extern	Cell	*instat(Node **, int);
+extern	Cell	*bltin(Node **, int);
+extern	Cell	*printstat(Node **, int);
+extern	Cell	*nullproc(Node **, int);
+extern	FILE	*redirect(int, Node *);
+extern	FILE	*openfile(int, char *);
+extern	char	*filename(FILE *);
+extern	Cell	*closefile(Node **, int);
+extern	void	closeall(void);
+extern	Cell	*sub(Node **, int);
+extern	Cell	*gsub(Node **, int);
+
+extern	FILE	*popen(const char *, const char *);
+extern	int	pclose(FILE *);
+
diff --git a/src/cmd/awk/re.c b/src/cmd/awk/re.c
new file mode 100644
index 0000000..a15d2f4
--- /dev/null
+++ b/src/cmd/awk/re.c
@@ -0,0 +1,325 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+
+#define DEBUG
+#include <stdio.h>
+#include <u.h>
+#include <libc.h>
+#include <ctype.h>
+#include <bio.h>
+#include <regexp.h>
+#include "awk.h"
+#include "y.tab.h"
+
+	/* This file provides the interface between the main body of
+	 * awk and the pattern matching package.  It preprocesses
+	 * patterns prior to compilation to provide awk-like semantics
+	 * to character sequences not supported by the pattern package.
+	 * The following conversions are performed:
+	 *
+	 *	"()"		->	"[]"
+	 *	"[-"		->	"[\-"
+	 *	"[^-"		->	"[^\-"
+	 *	"-]"		->	"\-]"
+	 *	"[]"		->	"[]*"
+	 *	"\xdddd"	->	"\z" where 'z' is the UTF sequence
+	 *					for the hex value
+	 *	"\ddd"		->	"\o" where 'o' is a char octal value
+	 *	"\b"		->	"\B"	where 'B' is backspace
+	 *	"\t"		->	"\T"	where 'T' is tab
+	 *	"\f"		->	"\F"	where 'F' is form feed
+	 *	"\n"		->	"\N"	where 'N' is newline
+	 *	"\r"		->	"\r"	where 'C' is cr
+	 */
+
+#define	MAXRE	512
+
+static char	re[MAXRE];	/* copy buffer */
+
+char	*patbeg;
+int	patlen;			/* number of chars in pattern */
+
+#define	NPATS	20		/* number of slots in pattern cache */
+
+static struct pat_list		/* dynamic pattern cache */
+{
+	char	*re;
+	int	use;
+	Reprog	*program;
+} pattern[NPATS];
+
+static int npats;		/* cache fill level */
+
+	/* Compile a pattern */
+void
+*compre(char *pat)
+{
+	int i, j, inclass;
+	char c, *p, *s;
+	Reprog *program;
+
+	if (!compile_time) {	/* search cache for dynamic pattern */
+		for (i = 0; i < npats; i++)
+			if (!strcmp(pat, pattern[i].re)) {
+				pattern[i].use++;
+				return((void *) pattern[i].program);
+			}
+	}
+		/* Preprocess Pattern for compilation */
+	p = re;
+	s = pat;
+	inclass = 0;
+	while (c = *s++) {
+		if (c == '\\') {
+			quoted(&s, &p, re+MAXRE);
+			continue;
+		}
+		else if (!inclass && c == '(' && *s == ')') {
+			if (p < re+MAXRE-2) {	/* '()' -> '[]*' */
+				*p++ = '[';
+				*p++ = ']';
+				c = '*';
+				s++;
+			}
+			else overflow();
+		}
+		else if (c == '['){			/* '[-' -> '[\-' */
+			inclass = 1;
+			if (*s == '-') {
+				if (p < re+MAXRE-2) {
+					*p++ = '[';
+					*p++ = '\\';
+					c = *s++;
+				}
+				else overflow();
+			}				/* '[^-' -> '[^\-'*/
+			else if (*s == '^' && s[1] == '-'){
+				if (p < re+MAXRE-3) {
+					*p++ = '[';
+					*p++ = *s++;
+					*p++ = '\\';
+					c = *s++;
+				}
+				else overflow();
+			}
+			else if (*s == '['){		/* skip '[[' */
+				if (p < re+MAXRE-1)
+					*p++ = c;
+				else overflow();
+				c = *s++;
+			}
+			else if (*s == '^' && s[1] == '[') {	/* skip '[^['*/
+				if (p < re+MAXRE-2) {
+					*p++ = c;
+					*p++ = *s++;
+					c = *s++;
+				}
+				else overflow();
+			}
+			else if (*s == ']') {		/* '[]' -> '[]*' */
+				if (p < re+MAXRE-2) {
+					*p++ = c;
+					*p++ = *s++;
+					c = '*';
+					inclass = 0;
+				}
+				else overflow();
+			}
+		}
+		else if (c == '-' && *s == ']') {	/* '-]' -> '\-]' */
+			if (p < re+MAXRE-1)
+				*p++ = '\\';
+			else overflow();
+		}
+		else if (c == ']')
+			inclass = 0;
+		if (p < re+MAXRE-1)
+			*p++ = c;
+		else overflow();
+	}
+	*p = 0;
+	program = regcomp(re);		/* compile pattern */
+	if (!compile_time) {
+		if (npats < NPATS)	/* Room in cache */
+			i = npats++;
+		else {			/* Throw out least used */
+			int use = pattern[0].use;
+			i = 0;
+			for (j = 1; j < NPATS; j++) {
+				if (pattern[j].use < use) {
+					use = pattern[j].use;
+					i = j;
+				}
+			}
+			xfree(pattern[i].program);
+			xfree(pattern[i].re);
+		}
+		pattern[i].re = tostring(pat);
+		pattern[i].program = program;
+		pattern[i].use = 1;
+	}
+	return((void *) program);
+}
+
+	/* T/F match indication - matched string not exported */
+int
+match(void *p, char *s, char *start)
+{
+	return regexec((Reprog *) p, (char *) s, 0, 0);
+}
+
+	/* match and delimit the matched string */
+int
+pmatch(void *p, char *s, char *start)
+{
+	Resub m;
+
+	m.s.sp = start;
+	m.e.ep = 0;
+	if (regexec((Reprog *) p, (char *) s, &m, 1)) {
+		patbeg = m.s.sp;
+		patlen = m.e.ep-m.s.sp;
+		return 1;
+	}
+	patlen = -1;
+	patbeg = start;
+	return 0;
+}
+
+	/* perform a non-empty match */
+int
+nematch(void *p, char *s, char *start)
+{
+	if (pmatch(p, s, start) == 1 && patlen > 0)
+		return 1;
+	patlen = -1;
+	patbeg = start; 
+	return 0;
+}
+/* in the parsing of regular expressions, metacharacters like . have */
+/* to be seen literally;  \056 is not a metacharacter. */
+
+int
+hexstr(char **pp)	/* find and eval hex string at pp, return new p */
+{
+	char c;
+	int n = 0;
+	int i;
+
+	for (i = 0, c = (*pp)[i]; i < 4 && isxdigit(c); i++, c = (*pp)[i]) {
+		if (isdigit(c))
+			n = 16 * n + c - '0';
+		else if ('a' <= c && c <= 'f')
+			n = 16 * n + c - 'a' + 10;
+		else if ('A' <= c && c <= 'F')
+			n = 16 * n + c - 'A' + 10;
+	}
+	*pp += i;
+	return n;
+}
+
+	/* look for awk-specific escape sequences */
+
+#define isoctdigit(c) ((c) >= '0' && (c) <= '7') /* multiple use of arg */
+
+void
+quoted(char **s, char **to, char *end)	/* handle escaped sequence */
+{
+	char *p = *s;
+	char *t = *to;
+	wchar_t c;
+
+	switch(c = *p++) {
+	case 't':
+		c = '\t';
+		break;
+	case 'n':
+		c = '\n';
+		break;
+	case 'f':
+		c = '\f';
+		break;
+	case 'r':
+		c = '\r';
+		break;
+	case 'b':
+		c = '\b';
+		break;
+	default:
+		if (t < end-1)		/* all else must be escaped */
+			*t++ = '\\';
+		if (c == 'x') {		/* hexadecimal goo follows */
+			c = hexstr(&p);
+			if (t < end-MB_CUR_MAX)
+				t += wctomb(t, c);
+			else overflow();
+			*to = t;
+			*s = p;
+			return;
+		} else if (isoctdigit(c)) {	/* \d \dd \ddd */
+			c -= '0';
+			if (isoctdigit(*p)) {
+				c = 8 * c + *p++ - '0';
+				if (isoctdigit(*p))
+					c = 8 * c + *p++ - '0';
+			}
+		}
+		break;
+	}
+	if (t < end-1)
+		*t++ = c;
+	*s = p;
+	*to = t;
+}
+	/* count rune positions */
+int
+countposn(char *s, int n)
+{
+	int i, j;
+	char *end;
+
+	for (i = 0, end = s+n; *s && s < end; i++){
+		j = mblen(s, n);
+		if(j <= 0)
+			j = 1;
+		s += j;
+	}
+	return(i);
+}
+
+	/* pattern package error handler */
+
+void
+regerror(char *s)
+{
+	FATAL("%s", s);
+}
+
+void
+overflow(void)
+{
+	FATAL("%s", "regular expression too big");
+}
+
diff --git a/src/cmd/awk/run.c b/src/cmd/awk/run.c
new file mode 100644
index 0000000..b99ef58
--- /dev/null
+++ b/src/cmd/awk/run.c
@@ -0,0 +1,1899 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+#define DEBUG
+#include <stdio.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include "awk.h"
+#include "y.tab.h"
+
+#define tempfree(x)	if (istemp(x)) tfree(x); else
+
+/*
+#undef tempfree
+
+void tempfree(Cell *p) {
+	if (p->ctype == OCELL && (p->csub < CUNK || p->csub > CFREE)) {
+		WARNING("bad csub %d in Cell %d %s",
+			p->csub, p->ctype, p->sval);
+	}
+	if (istemp(p))
+		tfree(p);
+}
+*/
+
+#ifdef _NFILE
+#ifndef FOPEN_MAX
+#define FOPEN_MAX _NFILE
+#endif
+#endif
+
+#ifndef	FOPEN_MAX
+#define	FOPEN_MAX	40	/* max number of open files */
+#endif
+
+#ifndef RAND_MAX
+#define RAND_MAX	32767	/* all that ansi guarantees */
+#endif
+
+jmp_buf env;
+extern	int	pairstack[];
+
+Node	*winner = NULL;	/* root of parse tree */
+Cell	*tmps;		/* free temporary cells for execution */
+
+static Cell	truecell	={ OBOOL, BTRUE, 0, 0, 1.0, NUM };
+Cell	*True	= &truecell;
+static Cell	falsecell	={ OBOOL, BFALSE, 0, 0, 0.0, NUM };
+Cell	*False	= &falsecell;
+static Cell	breakcell	={ OJUMP, JBREAK, 0, 0, 0.0, NUM };
+Cell	*jbreak	= &breakcell;
+static Cell	contcell	={ OJUMP, JCONT, 0, 0, 0.0, NUM };
+Cell	*jcont	= &contcell;
+static Cell	nextcell	={ OJUMP, JNEXT, 0, 0, 0.0, NUM };
+Cell	*jnext	= &nextcell;
+static Cell	nextfilecell	={ OJUMP, JNEXTFILE, 0, 0, 0.0, NUM };
+Cell	*jnextfile	= &nextfilecell;
+static Cell	exitcell	={ OJUMP, JEXIT, 0, 0, 0.0, NUM };
+Cell	*jexit	= &exitcell;
+static Cell	retcell		={ OJUMP, JRET, 0, 0, 0.0, NUM };
+Cell	*jret	= &retcell;
+static Cell	tempcell	={ OCELL, CTEMP, 0, "", 0.0, NUM|STR|DONTFREE };
+
+Node	*curnode = NULL;	/* the node being executed, for debugging */
+
+/* buffer memory management */
+int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr,
+	char *whatrtn)
+/* pbuf:    address of pointer to buffer being managed
+ * psiz:    address of buffer size variable
+ * minlen:  minimum length of buffer needed
+ * quantum: buffer size quantum
+ * pbptr:   address of movable pointer into buffer, or 0 if none
+ * whatrtn: name of the calling routine if failure should cause fatal error
+ *
+ * return   0 for realloc failure, !=0 for success
+ */
+{
+	if (minlen > *psiz) {
+		char *tbuf;
+		int rminlen = quantum ? minlen % quantum : 0;
+		int boff = pbptr ? *pbptr - *pbuf : 0;
+		/* round up to next multiple of quantum */
+		if (rminlen)
+			minlen += quantum - rminlen;
+		tbuf = (char *) realloc(*pbuf, minlen);
+		if (tbuf == NULL) {
+			if (whatrtn)
+				FATAL("out of memory in %s", whatrtn);
+			return 0;
+		}
+		*pbuf = tbuf;
+		*psiz = minlen;
+		if (pbptr)
+			*pbptr = tbuf + boff;
+	}
+	return 1;
+}
+
+void run(Node *a)	/* execution of parse tree starts here */
+{
+	extern void stdinit(void);
+
+	stdinit();
+	execute(a);
+	closeall();
+}
+
+Cell *execute(Node *u)	/* execute a node of the parse tree */
+{
+	int nobj;
+	Cell *(*proc)(Node **, int);
+	Cell *x;
+	Node *a;
+
+	if (u == NULL)
+		return(True);
+	for (a = u; ; a = a->nnext) {
+		curnode = a;
+		if (isvalue(a)) {
+			x = (Cell *) (a->narg[0]);
+			if (isfld(x) && !donefld)
+				fldbld();
+			else if (isrec(x) && !donerec)
+				recbld();
+			return(x);
+		}
+		nobj = a->nobj;
+		if (notlegal(nobj))	/* probably a Cell* but too risky to print */
+			FATAL("illegal statement");
+		proc = proctab[nobj-FIRSTTOKEN];
+		x = (*proc)(a->narg, nobj);
+		if (isfld(x) && !donefld)
+			fldbld();
+		else if (isrec(x) && !donerec)
+			recbld();
+		if (isexpr(a))
+			return(x);
+		if (isjump(x))
+			return(x);
+		if (a->nnext == NULL)
+			return(x);
+		tempfree(x);
+	}
+}
+
+
+Cell *program(Node **a, int n)	/* execute an awk program */
+{				/* a[0] = BEGIN, a[1] = body, a[2] = END */
+	Cell *x;
+
+	if (setjmp(env) != 0)
+		goto ex;
+	if (a[0]) {		/* BEGIN */
+		x = execute(a[0]);
+		if (isexit(x))
+			return(True);
+		if (isjump(x))
+			FATAL("illegal break, continue, next or nextfile from BEGIN");
+		tempfree(x);
+	}
+	if (a[1] || a[2])
+		while (getrec(&record, &recsize, 1) > 0) {
+			x = execute(a[1]);
+			if (isexit(x))
+				break;
+			tempfree(x);
+		}
+  ex:
+	if (setjmp(env) != 0)	/* handles exit within END */
+		goto ex1;
+	if (a[2]) {		/* END */
+		x = execute(a[2]);
+		if (isbreak(x) || isnext(x) || iscont(x))
+			FATAL("illegal break, continue, next or nextfile from END");
+		tempfree(x);
+	}
+  ex1:
+	return(True);
+}
+
+struct Frame {	/* stack frame for awk function calls */
+	int nargs;	/* number of arguments in this call */
+	Cell *fcncell;	/* pointer to Cell for function */
+	Cell **args;	/* pointer to array of arguments after execute */
+	Cell *retval;	/* return value */
+};
+
+#define	NARGS	50	/* max args in a call */
+
+struct Frame *frame = NULL;	/* base of stack frames; dynamically allocated */
+int	nframe = 0;		/* number of frames allocated */
+struct Frame *fp = NULL;	/* frame pointer. bottom level unused */
+
+Cell *call(Node **a, int n)	/* function call.  very kludgy and fragile */
+{
+	static Cell newcopycell = { OCELL, CCOPY, 0, "", 0.0, NUM|STR|DONTFREE };
+	int i, ncall, ndef;
+	Node *x;
+	Cell *args[NARGS], *oargs[NARGS];	/* BUG: fixed size arrays */
+	Cell *y, *z, *fcn;
+	char *s;
+
+	fcn = execute(a[0]);	/* the function itself */
+	s = fcn->nval;
+	if (!isfcn(fcn))
+		FATAL("calling undefined function %s", s);
+	if (frame == NULL) {
+		fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame));
+		if (frame == NULL)
+			FATAL("out of space for stack frames calling %s", s);
+	}
+	for (ncall = 0, x = a[1]; x != NULL; x = x->nnext)	/* args in call */
+		ncall++;
+	ndef = (int) fcn->fval;			/* args in defn */
+	   dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, (int) (fp-frame)) );
+	if (ncall > ndef)
+		WARNING("function %s called with %d args, uses only %d",
+			s, ncall, ndef);
+	if (ncall + ndef > NARGS)
+		FATAL("function %s has %d arguments, limit %d", s, ncall+ndef, NARGS);
+	for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) {	/* get call args */
+		   dprintf( ("evaluate args[%d], fp=%d:\n", i, (int) (fp-frame)) );
+		y = execute(x);
+		oargs[i] = y;
+		   dprintf( ("args[%d]: %s %f <%s>, t=%o\n",
+			   i, y->nval, y->fval, isarr(y) ? "(array)" : y->sval, y->tval) );
+		if (isfcn(y))
+			FATAL("can't use function %s as argument in %s", y->nval, s);
+		if (isarr(y))
+			args[i] = y;	/* arrays by ref */
+		else
+			args[i] = copycell(y);
+		tempfree(y);
+	}
+	for ( ; i < ndef; i++) {	/* add null args for ones not provided */
+		args[i] = gettemp();
+		*args[i] = newcopycell;
+	}
+	fp++;	/* now ok to up frame */
+	if (fp >= frame + nframe) {
+		int dfp = fp - frame;	/* old index */
+		frame = (struct Frame *)
+			realloc((char *) frame, (nframe += 100) * sizeof(struct Frame));
+		if (frame == NULL)
+			FATAL("out of space for stack frames in %s", s);
+		fp = frame + dfp;
+	}
+	fp->fcncell = fcn;
+	fp->args = args;
+	fp->nargs = ndef;	/* number defined with (excess are locals) */
+	fp->retval = gettemp();
+
+	   dprintf( ("start exec of %s, fp=%d\n", s, (int) (fp-frame)) );
+	y = execute((Node *)(fcn->sval));	/* execute body */
+	   dprintf( ("finished exec of %s, fp=%d\n", s, (int) (fp-frame)) );
+
+	for (i = 0; i < ndef; i++) {
+		Cell *t = fp->args[i];
+		if (isarr(t)) {
+			if (t->csub == CCOPY) {
+				if (i >= ncall) {
+					freesymtab(t);
+					t->csub = CTEMP;
+					tempfree(t);
+				} else {
+					oargs[i]->tval = t->tval;
+					oargs[i]->tval &= ~(STR|NUM|DONTFREE);
+					oargs[i]->sval = t->sval;
+					tempfree(t);
+				}
+			}
+		} else if (t != y) {	/* kludge to prevent freeing twice */
+			t->csub = CTEMP;
+			tempfree(t);
+		}
+	}
+	tempfree(fcn);
+	if (isexit(y) || isnext(y) || isnextfile(y))
+		return y;
+	tempfree(y);		/* this can free twice! */
+	z = fp->retval;			/* return value */
+	   dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) );
+	fp--;
+	return(z);
+}
+
+Cell *copycell(Cell *x)	/* make a copy of a cell in a temp */
+{
+	Cell *y;
+
+	y = gettemp();
+	y->csub = CCOPY;	/* prevents freeing until call is over */
+	y->nval = x->nval;	/* BUG? */
+	y->sval = x->sval ? tostring(x->sval) : NULL;
+	y->fval = x->fval;
+	y->tval = x->tval & ~(CON|FLD|REC|DONTFREE);	/* copy is not constant or field */
+							/* is DONTFREE right? */
+	return y;
+}
+
+Cell *arg(Node **a, int n)	/* nth argument of a function */
+{
+
+	n = ptoi(a[0]);	/* argument number, counting from 0 */
+	   dprintf( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) );
+	if (n+1 > fp->nargs)
+		FATAL("argument #%d of function %s was not supplied",
+			n+1, fp->fcncell->nval);
+	return fp->args[n];
+}
+
+Cell *jump(Node **a, int n)	/* break, continue, next, nextfile, return */
+{
+	Cell *y;
+
+	switch (n) {
+	case EXIT:
+		if (a[0] != NULL) {
+			y = execute(a[0]);
+			errorflag = (int) getfval(y);
+			tempfree(y);
+		}
+		longjmp(env, 1);
+	case RETURN:
+		if (a[0] != NULL) {
+			y = execute(a[0]);
+			if ((y->tval & (STR|NUM)) == (STR|NUM)) {
+				setsval(fp->retval, getsval(y));
+				fp->retval->fval = getfval(y);
+				fp->retval->tval |= NUM;
+			}
+			else if (y->tval & STR)
+				setsval(fp->retval, getsval(y));
+			else if (y->tval & NUM)
+				setfval(fp->retval, getfval(y));
+			else		/* can't happen */
+				FATAL("bad type variable %d", y->tval);
+			tempfree(y);
+		}
+		return(jret);
+	case NEXT:
+		return(jnext);
+	case NEXTFILE:
+		nextfile();
+		return(jnextfile);
+	case BREAK:
+		return(jbreak);
+	case CONTINUE:
+		return(jcont);
+	default:	/* can't happen */
+		FATAL("illegal jump type %d", n);
+	}
+	return 0;	/* not reached */
+}
+
+Cell *getline(Node **a, int n)	/* get next line from specific input */
+{		/* a[0] is variable, a[1] is operator, a[2] is filename */
+	Cell *r, *x;
+	extern Cell **fldtab;
+	FILE *fp;
+	char *buf;
+	int bufsize = recsize;
+	int mode;
+
+	if ((buf = (char *) malloc(bufsize)) == NULL)
+		FATAL("out of memory in getline");
+
+	fflush(stdout);	/* in case someone is waiting for a prompt */
+	r = gettemp();
+	if (a[1] != NULL) {		/* getline < file */
+		x = execute(a[2]);		/* filename */
+		mode = ptoi(a[1]);
+		if (mode == '|')		/* input pipe */
+			mode = LE;	/* arbitrary flag */
+		fp = openfile(mode, getsval(x));
+		tempfree(x);
+		if (fp == NULL)
+			n = -1;
+		else
+			n = readrec(&buf, &bufsize, fp);
+		if (n <= 0) {
+			;
+		} else if (a[0] != NULL) {	/* getline var <file */
+			x = execute(a[0]);
+			setsval(x, buf);
+			tempfree(x);
+		} else {			/* getline <file */
+			setsval(fldtab[0], buf);
+			if (is_number(fldtab[0]->sval)) {
+				fldtab[0]->fval = atof(fldtab[0]->sval);
+				fldtab[0]->tval |= NUM;
+			}
+		}
+	} else {			/* bare getline; use current input */
+		if (a[0] == NULL)	/* getline */
+			n = getrec(&record, &recsize, 1);
+		else {			/* getline var */
+			n = getrec(&buf, &bufsize, 0);
+			x = execute(a[0]);
+			setsval(x, buf);
+			tempfree(x);
+		}
+	}
+	setfval(r, (Awkfloat) n);
+	free(buf);
+	return r;
+}
+
+Cell *getnf(Node **a, int n)	/* get NF */
+{
+	if (donefld == 0)
+		fldbld();
+	return (Cell *) a[0];
+}
+
+Cell *array(Node **a, int n)	/* a[0] is symtab, a[1] is list of subscripts */
+{
+	Cell *x, *y, *z;
+	char *s;
+	Node *np;
+	char *buf;
+	int bufsz = recsize;
+	int nsub = strlen(*SUBSEP);
+
+	if ((buf = (char *) malloc(bufsz)) == NULL)
+		FATAL("out of memory in array");
+
+	x = execute(a[0]);	/* Cell* for symbol table */
+	buf[0] = 0;
+	for (np = a[1]; np; np = np->nnext) {
+		y = execute(np);	/* subscript */
+		s = getsval(y);
+		if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, 0))
+			FATAL("out of memory for %s[%s...]", x->nval, buf);
+		strcat(buf, s);
+		if (np->nnext)
+			strcat(buf, *SUBSEP);
+		tempfree(y);
+	}
+	if (!isarr(x)) {
+		   dprintf( ("making %s into an array\n", x->nval) );
+		if (freeable(x))
+			xfree(x->sval);
+		x->tval &= ~(STR|NUM|DONTFREE);
+		x->tval |= ARR;
+		x->sval = (char *) makesymtab(NSYMTAB);
+	}
+	z = setsymtab(buf, "", 0.0, STR|NUM, (Array *) x->sval);
+	z->ctype = OCELL;
+	z->csub = CVAR;
+	tempfree(x);
+	free(buf);
+	return(z);
+}
+
+Cell *awkdelete(Node **a, int n)	/* a[0] is symtab, a[1] is list of subscripts */
+{
+	Cell *x, *y;
+	Node *np;
+	char *s;
+	int nsub = strlen(*SUBSEP);
+
+	x = execute(a[0]);	/* Cell* for symbol table */
+	if (!isarr(x))
+		return True;
+	if (a[1] == 0) {	/* delete the elements, not the table */
+		freesymtab(x);
+		x->tval &= ~STR;
+		x->tval |= ARR;
+		x->sval = (char *) makesymtab(NSYMTAB);
+	} else {
+		int bufsz = recsize;
+		char *buf;
+		if ((buf = (char *) malloc(bufsz)) == NULL)
+			FATAL("out of memory in adelete");
+		buf[0] = 0;
+		for (np = a[1]; np; np = np->nnext) {
+			y = execute(np);	/* subscript */
+			s = getsval(y);
+			if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, 0))
+				FATAL("out of memory deleting %s[%s...]", x->nval, buf);
+			strcat(buf, s);	
+			if (np->nnext)
+				strcat(buf, *SUBSEP);
+			tempfree(y);
+		}
+		freeelem(x, buf);
+		free(buf);
+	}
+	tempfree(x);
+	return True;
+}
+
+Cell *intest(Node **a, int n)	/* a[0] is index (list), a[1] is symtab */
+{
+	Cell *x, *ap, *k;
+	Node *p;
+	char *buf;
+	char *s;
+	int bufsz = recsize;
+	int nsub = strlen(*SUBSEP);
+
+	ap = execute(a[1]);	/* array name */
+	if (!isarr(ap)) {
+		   dprintf( ("making %s into an array\n", ap->nval) );
+		if (freeable(ap))
+			xfree(ap->sval);
+		ap->tval &= ~(STR|NUM|DONTFREE);
+		ap->tval |= ARR;
+		ap->sval = (char *) makesymtab(NSYMTAB);
+	}
+	if ((buf = (char *) malloc(bufsz)) == NULL) {
+		FATAL("out of memory in intest");
+	}
+	buf[0] = 0;
+	for (p = a[0]; p; p = p->nnext) {
+		x = execute(p);	/* expr */
+		s = getsval(x);
+		if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, 0))
+			FATAL("out of memory deleting %s[%s...]", x->nval, buf);
+		strcat(buf, s);
+		tempfree(x);
+		if (p->nnext)
+			strcat(buf, *SUBSEP);
+	}
+	k = lookup(buf, (Array *) ap->sval);
+	tempfree(ap);
+	free(buf);
+	if (k == NULL)
+		return(False);
+	else
+		return(True);
+}
+
+
+Cell *matchop(Node **a, int n)	/* ~ and match() */
+{
+	Cell *x, *y;
+	char *s, *t;
+	int i;
+	void *p;
+
+	x = execute(a[1]);	/* a[1] = target text */
+	s = getsval(x);
+	if (a[0] == 0)		/* a[1] == 0: already-compiled reg expr */
+		p = (void *) a[2];
+	else {
+		y = execute(a[2]);	/* a[2] = regular expr */
+		t = getsval(y);
+		p = compre(t);
+		tempfree(y);
+	}
+	if (n == MATCHFCN)
+		i = pmatch(p, s, s);
+	else
+		i = match(p, s, s);
+	tempfree(x);
+	if (n == MATCHFCN) {
+		int start = countposn(s, patbeg-s)+1;
+		if (patlen < 0)
+			start = 0;
+		setfval(rstartloc, (Awkfloat) start);
+		setfval(rlengthloc, (Awkfloat) countposn(patbeg, patlen));
+		x = gettemp();
+		x->tval = NUM;
+		x->fval = start;
+		return x;
+	} else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0))
+		return(True);
+	else
+		return(False);
+}
+
+
+Cell *boolop(Node **a, int n)	/* a[0] || a[1], a[0] && a[1], !a[0] */
+{
+	Cell *x, *y;
+	int i;
+
+	x = execute(a[0]);
+	i = istrue(x);
+	tempfree(x);
+	switch (n) {
+	case BOR:
+		if (i) return(True);
+		y = execute(a[1]);
+		i = istrue(y);
+		tempfree(y);
+		if (i) return(True);
+		else return(False);
+	case AND:
+		if ( !i ) return(False);
+		y = execute(a[1]);
+		i = istrue(y);
+		tempfree(y);
+		if (i) return(True);
+		else return(False);
+	case NOT:
+		if (i) return(False);
+		else return(True);
+	default:	/* can't happen */
+		FATAL("unknown boolean operator %d", n);
+	}
+	return 0;	/*NOTREACHED*/
+}
+
+Cell *relop(Node **a, int n)	/* a[0 < a[1], etc. */
+{
+	int i;
+	Cell *x, *y;
+	Awkfloat j;
+
+	x = execute(a[0]);
+	y = execute(a[1]);
+	if (x->tval&NUM && y->tval&NUM) {
+		j = x->fval - y->fval;
+		i = j<0? -1: (j>0? 1: 0);
+	} else {
+		i = strcmp(getsval(x), getsval(y));
+	}
+	tempfree(x);
+	tempfree(y);
+	switch (n) {
+	case LT:	if (i<0) return(True);
+			else return(False);
+	case LE:	if (i<=0) return(True);
+			else return(False);
+	case NE:	if (i!=0) return(True);
+			else return(False);
+	case EQ:	if (i == 0) return(True);
+			else return(False);
+	case GE:	if (i>=0) return(True);
+			else return(False);
+	case GT:	if (i>0) return(True);
+			else return(False);
+	default:	/* can't happen */
+		FATAL("unknown relational operator %d", n);
+	}
+	return 0;	/*NOTREACHED*/
+}
+
+void tfree(Cell *a)	/* free a tempcell */
+{
+	if (freeable(a)) {
+		   dprintf( ("freeing %s %s %o\n", a->nval, a->sval, a->tval) );
+		xfree(a->sval);
+	}
+	if (a == tmps)
+		FATAL("tempcell list is curdled");
+	a->cnext = tmps;
+	tmps = a;
+}
+
+Cell *gettemp(void)	/* get a tempcell */
+{	int i;
+	Cell *x;
+
+	if (!tmps) {
+		tmps = (Cell *) calloc(100, sizeof(Cell));
+		if (!tmps)
+			FATAL("out of space for temporaries");
+		for(i = 1; i < 100; i++)
+			tmps[i-1].cnext = &tmps[i];
+		tmps[i-1].cnext = 0;
+	}
+	x = tmps;
+	tmps = x->cnext;
+	*x = tempcell;
+	return(x);
+}
+
+Cell *indirect(Node **a, int n)	/* $( a[0] ) */
+{
+	Cell *x;
+	int m;
+	char *s;
+
+	x = execute(a[0]);
+	m = (int) getfval(x);
+	if (m == 0 && !is_number(s = getsval(x)))	/* suspicion! */
+		FATAL("illegal field $(%s), name \"%s\"", s, x->nval);
+		/* BUG: can x->nval ever be null??? */
+	tempfree(x);
+	x = fieldadr(m);
+	x->ctype = OCELL;	/* BUG?  why are these needed? */
+	x->csub = CFLD;
+	return(x);
+}
+
+Cell *substr(Node **a, int nnn)		/* substr(a[0], a[1], a[2]) */
+{
+	int k, m, n;
+	char *s, *p;
+	int temp;
+	Cell *x, *y, *z = 0;
+
+	x = execute(a[0]);
+	y = execute(a[1]);
+	if (a[2] != 0)
+		z = execute(a[2]);
+	s = getsval(x);
+	k = countposn(s, strlen(s)) + 1;
+	if (k <= 1) {
+		tempfree(x);
+		tempfree(y);
+		if (a[2] != 0)
+			tempfree(z);
+		x = gettemp();
+		setsval(x, "");
+		return(x);
+	}
+	m = (int) getfval(y);
+	if (m <= 0)
+		m = 1;
+	else if (m > k)
+		m = k;
+	tempfree(y);
+	if (a[2] != 0) {
+		n = (int) getfval(z);
+		tempfree(z);
+	} else
+		n = k - 1;
+	if (n < 0)
+		n = 0;
+	else if (n > k - m)
+		n = k - m;
+	   dprintf( ("substr: m=%d, n=%d, s=%s\n", m, n, s) );
+	y = gettemp();
+	while (*s && --m)
+		 s += mblen(s, k);
+	for (p = s; *p && n--; p += mblen(p, k))
+			;
+	temp = *p;	/* with thanks to John Linderman */
+	*p = '\0';
+	setsval(y, s);
+	*p = temp;
+	tempfree(x);
+	return(y);
+}
+
+Cell *sindex(Node **a, int nnn)		/* index(a[0], a[1]) */
+{
+	Cell *x, *y, *z;
+	char *s1, *s2, *p1, *p2, *q;
+	Awkfloat v = 0.0;
+
+	x = execute(a[0]);
+	s1 = getsval(x);
+	y = execute(a[1]);
+	s2 = getsval(y);
+
+	z = gettemp();
+	for (p1 = s1; *p1 != '\0'; p1++) {
+		for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++)
+			;
+		if (*p2 == '\0') {
+			v = (Awkfloat) countposn(s1, p1-s1) + 1;	/* origin 1 */
+			break;
+		}
+	}
+	tempfree(x);
+	tempfree(y);
+	setfval(z, v);
+	return(z);
+}
+
+#define	MAXNUMSIZE	50
+
+int format(char **pbuf, int *pbufsize, char *s, Node *a)	/* printf-like conversions */
+{
+	char *fmt;
+	char *p, *t, *os;
+	Cell *x;
+	int flag = 0, n;
+	int fmtwd; /* format width */
+	int fmtsz = recsize;
+	char *buf = *pbuf;
+	int bufsize = *pbufsize;
+
+	os = s;
+	p = buf;
+	if ((fmt = (char *) malloc(fmtsz)) == NULL)
+		FATAL("out of memory in format()");
+	while (*s) {
+		adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format");
+		if (*s != '%') {
+			*p++ = *s++;
+			continue;
+		}
+		if (*(s+1) == '%') {
+			*p++ = '%';
+			s += 2;
+			continue;
+		}
+		/* have to be real careful in case this is a huge number, eg, %100000d */
+		fmtwd = atoi(s+1);
+		if (fmtwd < 0)
+			fmtwd = -fmtwd;
+		adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");
+		for (t = fmt; (*t++ = *s) != '\0'; s++) {
+			if (!adjbuf(&fmt, &fmtsz, MAXNUMSIZE+1+t-fmt, recsize, &t, 0))
+				FATAL("format item %.30s... ran format() out of memory", os);
+			if (isalpha(*s) && *s != 'l' && *s != 'h' && *s != 'L')
+				break;	/* the ansi panoply */
+			if (*s == '*') {
+				x = execute(a);
+				a = a->nnext;
+				sprintf(t-1, "%d", fmtwd=(int) getfval(x));
+				if (fmtwd < 0)
+					fmtwd = -fmtwd;
+				adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");
+				t = fmt + strlen(fmt);
+				tempfree(x);
+			}
+		}
+		*t = '\0';
+		if (fmtwd < 0)
+			fmtwd = -fmtwd;
+		adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");
+
+		switch (*s) {
+		case 'f': case 'e': case 'g': case 'E': case 'G':
+			flag = 1;
+			break;
+		case 'd': case 'i':
+			flag = 2;
+			if(*(s-1) == 'l') break;
+			*(t-1) = 'l';
+			*t = 'd';
+			*++t = '\0';
+			break;
+		case 'o': case 'x': case 'X': case 'u':
+			flag = *(s-1) == 'l' ? 2 : 3;
+			break;
+		case 's':
+			flag = 4;
+			break;
+		case 'c':
+			flag = 5;
+			break;
+		default:
+			WARNING("weird printf conversion %s", fmt);
+			flag = 0;
+			break;
+		}
+		if (a == NULL)
+			FATAL("not enough args in printf(%s)", os);
+		x = execute(a);
+		a = a->nnext;
+		n = MAXNUMSIZE;
+		if (fmtwd > n)
+			n = fmtwd;
+		adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format");
+		switch (flag) {
+		case 0:	sprintf(p, "%s", fmt);	/* unknown, so dump it too */
+			t = getsval(x);
+			n = strlen(t);
+			if (fmtwd > n)
+				n = fmtwd;
+			adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format");
+			p += strlen(p);
+			sprintf(p, "%s", t);
+			break;
+		case 1:	sprintf(p, fmt, getfval(x)); break;
+		case 2:	sprintf(p, fmt, (long) getfval(x)); break;
+		case 3:	sprintf(p, fmt, (int) getfval(x)); break;
+		case 4:
+			t = getsval(x);
+			n = strlen(t);
+			if (fmtwd > n)
+				n = fmtwd;
+			if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, 0))
+				FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t);
+			sprintf(p, fmt, t);
+			break;
+		case 5:
+			if (isnum(x)) {
+				if (getfval(x))
+					sprintf(p, fmt, (int) getfval(x));
+				else{
+					*p++ = '\0';
+					*p = '\0';
+				}
+			} else
+				sprintf(p, fmt, getsval(x)[0]);
+			break;
+		}
+		tempfree(x);
+		p += strlen(p);
+		s++;
+	}
+	*p = '\0';
+	free(fmt);
+	for ( ; a; a = a->nnext)		/* evaluate any remaining args */
+		execute(a);
+	*pbuf = buf;
+	*pbufsize = bufsize;
+	return p - buf;
+}
+
+Cell *awksprintf(Node **a, int n)		/* sprintf(a[0]) */
+{
+	Cell *x;
+	Node *y;
+	char *buf;
+	int bufsz=3*recsize;
+
+	if ((buf = (char *) malloc(bufsz)) == NULL)
+		FATAL("out of memory in awksprintf");
+	y = a[0]->nnext;
+	x = execute(a[0]);
+	if (format(&buf, &bufsz, getsval(x), y) == -1)
+		FATAL("sprintf string %.30s... too long.  can't happen.", buf);
+	tempfree(x);
+	x = gettemp();
+	x->sval = buf;
+	x->tval = STR;
+	return(x);
+}
+
+Cell *awkprintf(Node **a, int n)		/* printf */
+{	/* a[0] is list of args, starting with format string */
+	/* a[1] is redirection operator, a[2] is redirection file */
+	FILE *fp;
+	Cell *x;
+	Node *y;
+	char *buf;
+	int len;
+	int bufsz=3*recsize;
+
+	if ((buf = (char *) malloc(bufsz)) == NULL)
+		FATAL("out of memory in awkprintf");
+	y = a[0]->nnext;
+	x = execute(a[0]);
+	if ((len = format(&buf, &bufsz, getsval(x), y)) == -1)
+		FATAL("printf string %.30s... too long.  can't happen.", buf);
+	tempfree(x);
+	if (a[1] == NULL) {
+		/* fputs(buf, stdout); */
+		fwrite(buf, len, 1, stdout);
+		if (ferror(stdout))
+			FATAL("write error on stdout");
+	} else {
+		fp = redirect(ptoi(a[1]), a[2]);
+		/* fputs(buf, fp); */
+		fwrite(buf, len, 1, fp);
+		fflush(fp);
+		if (ferror(fp))
+			FATAL("write error on %s", filename(fp));
+	}
+	free(buf);
+	return(True);
+}
+
+Cell *arith(Node **a, int n)	/* a[0] + a[1], etc.  also -a[0] */
+{
+	Awkfloat i, j = 0;
+	double v;
+	Cell *x, *y, *z;
+
+	x = execute(a[0]);
+	i = getfval(x);
+	tempfree(x);
+	if (n != UMINUS) {
+		y = execute(a[1]);
+		j = getfval(y);
+		tempfree(y);
+	}
+	z = gettemp();
+	switch (n) {
+	case ADD:
+		i += j;
+		break;
+	case MINUS:
+		i -= j;
+		break;
+	case MULT:
+		i *= j;
+		break;
+	case DIVIDE:
+		if (j == 0)
+			FATAL("division by zero");
+		i /= j;
+		break;
+	case MOD:
+		if (j == 0)
+			FATAL("division by zero in mod");
+		modf(i/j, &v);
+		i = i - j * v;
+		break;
+	case UMINUS:
+		i = -i;
+		break;
+	case POWER:
+		if (j >= 0 && modf(j, &v) == 0.0)	/* pos integer exponent */
+			i = ipow(i, (int) j);
+		else
+			i = errcheck(pow(i, j), "pow");
+		break;
+	default:	/* can't happen */
+		FATAL("illegal arithmetic operator %d", n);
+	}
+	setfval(z, i);
+	return(z);
+}
+
+double ipow(double x, int n)	/* x**n.  ought to be done by pow, but isn't always */
+{
+	double v;
+
+	if (n <= 0)
+		return 1;
+	v = ipow(x, n/2);
+	if (n % 2 == 0)
+		return v * v;
+	else
+		return x * v * v;
+}
+
+Cell *incrdecr(Node **a, int n)		/* a[0]++, etc. */
+{
+	Cell *x, *z;
+	int k;
+	Awkfloat xf;
+
+	x = execute(a[0]);
+	xf = getfval(x);
+	k = (n == PREINCR || n == POSTINCR) ? 1 : -1;
+	if (n == PREINCR || n == PREDECR) {
+		setfval(x, xf + k);
+		return(x);
+	}
+	z = gettemp();
+	setfval(z, xf);
+	setfval(x, xf + k);
+	tempfree(x);
+	return(z);
+}
+
+Cell *assign(Node **a, int n)	/* a[0] = a[1], a[0] += a[1], etc. */
+{		/* this is subtle; don't muck with it. */
+	Cell *x, *y;
+	Awkfloat xf, yf;
+	double v;
+
+	y = execute(a[1]);
+	x = execute(a[0]);
+	if (n == ASSIGN) {	/* ordinary assignment */
+		if (x == y && !(x->tval & (FLD|REC)))	/* self-assignment: */
+			;		/* leave alone unless it's a field */
+		else if ((y->tval & (STR|NUM)) == (STR|NUM)) {
+			setsval(x, getsval(y));
+			x->fval = getfval(y);
+			x->tval |= NUM;
+		}
+		else if (isstr(y))
+			setsval(x, getsval(y));
+		else if (isnum(y))
+			setfval(x, getfval(y));
+		else
+			funnyvar(y, "read value of");
+		tempfree(y);
+		return(x);
+	}
+	xf = getfval(x);
+	yf = getfval(y);
+	switch (n) {
+	case ADDEQ:
+		xf += yf;
+		break;
+	case SUBEQ:
+		xf -= yf;
+		break;
+	case MULTEQ:
+		xf *= yf;
+		break;
+	case DIVEQ:
+		if (yf == 0)
+			FATAL("division by zero in /=");
+		xf /= yf;
+		break;
+	case MODEQ:
+		if (yf == 0)
+			FATAL("division by zero in %%=");
+		modf(xf/yf, &v);
+		xf = xf - yf * v;
+		break;
+	case POWEQ:
+		if (yf >= 0 && modf(yf, &v) == 0.0)	/* pos integer exponent */
+			xf = ipow(xf, (int) yf);
+		else
+			xf = errcheck(pow(xf, yf), "pow");
+		break;
+	default:
+		FATAL("illegal assignment operator %d", n);
+		break;
+	}
+	tempfree(y);
+	setfval(x, xf);
+	return(x);
+}
+
+Cell *cat(Node **a, int q)	/* a[0] cat a[1] */
+{
+	Cell *x, *y, *z;
+	int n1, n2;
+	char *s;
+
+	x = execute(a[0]);
+	y = execute(a[1]);
+	getsval(x);
+	getsval(y);
+	n1 = strlen(x->sval);
+	n2 = strlen(y->sval);
+	s = (char *) malloc(n1 + n2 + 1);
+	if (s == NULL)
+		FATAL("out of space concatenating %.15s... and %.15s...",
+			x->sval, y->sval);
+	strcpy(s, x->sval);
+	strcpy(s+n1, y->sval);
+	tempfree(y);
+	z = gettemp();
+	z->sval = s;
+	z->tval = STR;
+	tempfree(x);
+	return(z);
+}
+
+Cell *pastat(Node **a, int n)	/* a[0] { a[1] } */
+{
+	Cell *x;
+
+	if (a[0] == 0)
+		x = execute(a[1]);
+	else {
+		x = execute(a[0]);
+		if (istrue(x)) {
+			tempfree(x);
+			x = execute(a[1]);
+		}
+	}
+	return x;
+}
+
+Cell *dopa2(Node **a, int n)	/* a[0], a[1] { a[2] } */
+{
+	Cell *x;
+	int pair;
+
+	pair = ptoi(a[3]);
+	if (pairstack[pair] == 0) {
+		x = execute(a[0]);
+		if (istrue(x))
+			pairstack[pair] = 1;
+		tempfree(x);
+	}
+	if (pairstack[pair] == 1) {
+		x = execute(a[1]);
+		if (istrue(x))
+			pairstack[pair] = 0;
+		tempfree(x);
+		x = execute(a[2]);
+		return(x);
+	}
+	return(False);
+}
+
+Cell *split(Node **a, int nnn)	/* split(a[0], a[1], a[2]); a[3] is type */
+{
+	Cell *x = 0, *y, *ap;
+	char *s;
+	int sep;
+	char *t, temp, num[50], *fs = 0;
+	int n, arg3type;
+
+	y = execute(a[0]);	/* source string */
+	s = getsval(y);
+	arg3type = ptoi(a[3]);
+	if (a[2] == 0)		/* fs string */
+		fs = *FS;
+	else if (arg3type == STRING) {	/* split(str,arr,"string") */
+		x = execute(a[2]);
+		fs = getsval(x);
+	} else if (arg3type == REGEXPR)
+		fs = "(regexpr)";	/* split(str,arr,/regexpr/) */
+	else
+		FATAL("illegal type of split");
+	sep = *fs;
+	ap = execute(a[1]);	/* array name */
+	freesymtab(ap);
+	   dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs) );
+	ap->tval &= ~STR;
+	ap->tval |= ARR;
+	ap->sval = (char *) makesymtab(NSYMTAB);
+
+	n = 0;
+	if ((*s != '\0' && strlen(fs) > 1) || arg3type == REGEXPR) {	/* reg expr */
+		void *p;
+		if (arg3type == REGEXPR) {	/* it's ready already */
+			p = (void *) a[2];
+		} else {
+			p = compre(fs);
+		}
+		t = s;
+		if (nematch(p,s,t)) {
+			do {
+				n++;
+				sprintf(num, "%d", n);
+				temp = *patbeg;
+				*patbeg = '\0';
+				if (is_number(t))
+					setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
+				else
+					setsymtab(num, t, 0.0, STR, (Array *) ap->sval);
+				*patbeg = temp;
+				t = patbeg + patlen;
+				if (t[-1] == 0 || *t == 0) {
+					n++;
+					sprintf(num, "%d", n);
+					setsymtab(num, "", 0.0, STR, (Array *) ap->sval);
+					goto spdone;
+				}
+			} while (nematch(p,s,t));
+		}
+		n++;
+		sprintf(num, "%d", n);
+		if (is_number(t))
+			setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
+		else
+			setsymtab(num, t, 0.0, STR, (Array *) ap->sval);
+  spdone:
+		p = NULL;
+	} else if (sep == ' ') {
+		for (n = 0; ; ) {
+			while (*s == ' ' || *s == '\t' || *s == '\n')
+				s++;
+			if (*s == 0)
+				break;
+			n++;
+			t = s;
+			do
+				s++;
+			while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0');
+			temp = *s;
+			*s = '\0';
+			sprintf(num, "%d", n);
+			if (is_number(t))
+				setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
+			else
+				setsymtab(num, t, 0.0, STR, (Array *) ap->sval);
+			*s = temp;
+			if (*s != 0)
+				s++;
+		}
+	} else if (sep == 0) {	/* new: split(s, a, "") => 1 char/elem */
+		for (n = 0; *s != 0; s++) {
+			char buf[2];
+			n++;
+			sprintf(num, "%d", n);
+			buf[0] = *s;
+			buf[1] = 0;
+			if (isdigit(buf[0]))
+				setsymtab(num, buf, atof(buf), STR|NUM, (Array *) ap->sval);
+			else
+				setsymtab(num, buf, 0.0, STR, (Array *) ap->sval);
+		}
+	} else if (*s != 0) {
+		for (;;) {
+			n++;
+			t = s;
+			while (*s != sep && *s != '\n' && *s != '\0')
+				s++;
+			temp = *s;
+			*s = '\0';
+			sprintf(num, "%d", n);
+			if (is_number(t))
+				setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
+			else
+				setsymtab(num, t, 0.0, STR, (Array *) ap->sval);
+			*s = temp;
+			if (*s++ == 0)
+				break;
+		}
+	}
+	tempfree(ap);
+	tempfree(y);
+	if (a[2] != 0 && arg3type == STRING)
+		tempfree(x);
+	x = gettemp();
+	x->tval = NUM;
+	x->fval = n;
+	return(x);
+}
+
+Cell *condexpr(Node **a, int n)	/* a[0] ? a[1] : a[2] */
+{
+	Cell *x;
+
+	x = execute(a[0]);
+	if (istrue(x)) {
+		tempfree(x);
+		x = execute(a[1]);
+	} else {
+		tempfree(x);
+		x = execute(a[2]);
+	}
+	return(x);
+}
+
+Cell *ifstat(Node **a, int n)	/* if (a[0]) a[1]; else a[2] */
+{
+	Cell *x;
+
+	x = execute(a[0]);
+	if (istrue(x)) {
+		tempfree(x);
+		x = execute(a[1]);
+	} else if (a[2] != 0) {
+		tempfree(x);
+		x = execute(a[2]);
+	}
+	return(x);
+}
+
+Cell *whilestat(Node **a, int n)	/* while (a[0]) a[1] */
+{
+	Cell *x;
+
+	for (;;) {
+		x = execute(a[0]);
+		if (!istrue(x))
+			return(x);
+		tempfree(x);
+		x = execute(a[1]);
+		if (isbreak(x)) {
+			x = True;
+			return(x);
+		}
+		if (isnext(x) || isexit(x) || isret(x))
+			return(x);
+		tempfree(x);
+	}
+}
+
+Cell *dostat(Node **a, int n)	/* do a[0]; while(a[1]) */
+{
+	Cell *x;
+
+	for (;;) {
+		x = execute(a[0]);
+		if (isbreak(x))
+			return True;
+		if (isnext(x) || isnextfile(x) || isexit(x) || isret(x))
+			return(x);
+		tempfree(x);
+		x = execute(a[1]);
+		if (!istrue(x))
+			return(x);
+		tempfree(x);
+	}
+}
+
+Cell *forstat(Node **a, int n)	/* for (a[0]; a[1]; a[2]) a[3] */
+{
+	Cell *x;
+
+	x = execute(a[0]);
+	tempfree(x);
+	for (;;) {
+		if (a[1]!=0) {
+			x = execute(a[1]);
+			if (!istrue(x)) return(x);
+			else tempfree(x);
+		}
+		x = execute(a[3]);
+		if (isbreak(x))		/* turn off break */
+			return True;
+		if (isnext(x) || isexit(x) || isret(x))
+			return(x);
+		tempfree(x);
+		x = execute(a[2]);
+		tempfree(x);
+	}
+}
+
+Cell *instat(Node **a, int n)	/* for (a[0] in a[1]) a[2] */
+{
+	Cell *x, *vp, *arrayp, *cp, *ncp;
+	Array *tp;
+	int i;
+
+	vp = execute(a[0]);
+	arrayp = execute(a[1]);
+	if (!isarr(arrayp)) {
+		return True;
+	}
+	tp = (Array *) arrayp->sval;
+	tempfree(arrayp);
+	for (i = 0; i < tp->size; i++) {	/* this routine knows too much */
+		for (cp = tp->tab[i]; cp != NULL; cp = ncp) {
+			setsval(vp, cp->nval);
+			ncp = cp->cnext;
+			x = execute(a[2]);
+			if (isbreak(x)) {
+				tempfree(vp);
+				return True;
+			}
+			if (isnext(x) || isexit(x) || isret(x)) {
+				tempfree(vp);
+				return(x);
+			}
+			tempfree(x);
+		}
+	}
+	return True;
+}
+
+Cell *bltin(Node **a, int n)	/* builtin functions. a[0] is type, a[1] is arg list */
+{
+	Cell *x, *y;
+	Awkfloat u;
+	int t;
+	wchar_t wc;
+	char *p, *buf;
+	char mbc[50];
+	Node *nextarg;
+	FILE *fp;
+
+	t = ptoi(a[0]);
+	x = execute(a[1]);
+	nextarg = a[1]->nnext;
+	switch (t) {
+	case FLENGTH:
+		p = getsval(x);
+		u = (Awkfloat) countposn(p, strlen(p)); break;
+	case FLOG:
+		u = errcheck(log(getfval(x)), "log"); break;
+	case FINT:
+		modf(getfval(x), &u); break;
+	case FEXP:
+		u = errcheck(exp(getfval(x)), "exp"); break;
+	case FSQRT:
+		u = errcheck(sqrt(getfval(x)), "sqrt"); break;
+	case FSIN:
+		u = sin(getfval(x)); break;
+	case FCOS:
+		u = cos(getfval(x)); break;
+	case FATAN:
+		if (nextarg == 0) {
+			WARNING("atan2 requires two arguments; returning 1.0");
+			u = 1.0;
+		} else {
+			y = execute(a[1]->nnext);
+			u = atan2(getfval(x), getfval(y));
+			tempfree(y);
+			nextarg = nextarg->nnext;
+		}
+		break;
+	case FSYSTEM:
+		fflush(stdout);		/* in case something is buffered already */
+		u = (Awkfloat) system(getsval(x)) / 256;   /* 256 is unix-dep */
+		break;
+	case FRAND:
+		/* in principle, rand() returns something in 0..RAND_MAX */
+		u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX;
+		break;
+	case FSRAND:
+		if (isrec(x))	/* no argument provided */
+			u = time((time_t *)0);
+		else
+			u = getfval(x);
+		srand((unsigned int) u);
+		break;
+	case FTOUPPER:
+	case FTOLOWER:
+		buf = tostring(getsval(x));
+		if (t == FTOUPPER) {
+			for (p = buf; *p; p++)
+				if (islower(*p))
+					*p = toupper(*p);
+		} else {
+			for (p = buf; *p; p++)
+				if (isupper(*p))
+					*p = tolower(*p);
+		}
+		tempfree(x);
+		x = gettemp();
+		setsval(x, buf);
+		free(buf);
+		return x;
+	case FFLUSH:
+		if ((fp = openfile(FFLUSH, getsval(x))) == NULL)
+			u = EOF;
+		else
+			u = fflush(fp);
+		break;
+	case FUTF:
+		wc = (int)getfval(x);
+		mbc[wctomb(mbc, wc)] = 0;
+		tempfree(x);
+		x = gettemp();
+		setsval(x, mbc);
+		return x;
+	default:	/* can't happen */
+		FATAL("illegal function type %d", t);
+		break;
+	}
+	tempfree(x);
+	x = gettemp();
+	setfval(x, u);
+	if (nextarg != 0) {
+		WARNING("warning: function has too many arguments");
+		for ( ; nextarg; nextarg = nextarg->nnext)
+			execute(nextarg);
+	}
+	return(x);
+}
+
+Cell *printstat(Node **a, int n)	/* print a[0] */
+{
+	int r;
+	Node *x;
+	Cell *y;
+	FILE *fp;
+
+	if (a[1] == 0)	/* a[1] is redirection operator, a[2] is file */
+		fp = stdout;
+	else
+		fp = redirect(ptoi(a[1]), a[2]);
+	for (x = a[0]; x != NULL; x = x->nnext) {
+		y = execute(x);
+		fputs(getsval(y), fp);
+		tempfree(y);
+		if (x->nnext == NULL)
+			r = fputs(*ORS, fp);
+		else
+			r = fputs(*OFS, fp);
+		if (r == EOF)
+			FATAL("write error on %s", filename(fp));
+	}
+	if (a[1] != 0)
+		if (fflush(fp) == EOF)
+			FATAL("write error on %s", filename(fp));
+	return(True);
+}
+
+Cell *nullproc(Node **a, int n)
+{
+	n = n;
+	a = a;
+	return 0;
+}
+
+
+FILE *redirect(int a, Node *b)	/* set up all i/o redirections */
+{
+	FILE *fp;
+	Cell *x;
+	char *fname;
+
+	x = execute(b);
+	fname = getsval(x);
+	fp = openfile(a, fname);
+	if (fp == NULL)
+		FATAL("can't open file %s", fname);
+	tempfree(x);
+	return fp;
+}
+
+struct files {
+	FILE	*fp;
+	char	*fname;
+	int	mode;	/* '|', 'a', 'w' => LE/LT, GT */
+} files[FOPEN_MAX] ={
+	{ NULL,  "/dev/stdin",  LT },	/* watch out: don't free this! */
+	{ NULL, "/dev/stdout", GT },
+	{ NULL, "/dev/stderr", GT }
+};
+
+void stdinit(void)	/* in case stdin, etc., are not constants */
+{
+	files[0].fp = stdin;
+	files[1].fp = stdout;
+	files[2].fp = stderr;
+}
+
+FILE *openfile(int a, char *us)
+{
+	char *s = us;
+	int i, m;
+	FILE *fp = 0;
+
+	if (*s == '\0')
+		FATAL("null file name in print or getline");
+	for (i=0; i < FOPEN_MAX; i++)
+		if (files[i].fname && strcmp(s, files[i].fname) == 0) {
+			if (a == files[i].mode || (a==APPEND && files[i].mode==GT))
+				return files[i].fp;
+			if (a == FFLUSH)
+				return files[i].fp;
+		}
+	if (a == FFLUSH)	/* didn't find it, so don't create it! */
+		return NULL;
+
+	for (i=0; i < FOPEN_MAX; i++)
+		if (files[i].fp == 0)
+			break;
+	if (i >= FOPEN_MAX)
+		FATAL("%s makes too many open files", s);
+	fflush(stdout);	/* force a semblance of order */
+	m = a;
+	if (a == GT) {
+		fp = fopen(s, "w");
+	} else if (a == APPEND) {
+		fp = fopen(s, "a");
+		m = GT;	/* so can mix > and >> */
+	} else if (a == '|') {	/* output pipe */
+		fp = popen(s, "w");
+	} else if (a == LE) {	/* input pipe */
+		fp = popen(s, "r");
+	} else if (a == LT) {	/* getline <file */
+		fp = strcmp(s, "-") == 0 ? stdin : fopen(s, "r");	/* "-" is stdin */
+	} else	/* can't happen */
+		FATAL("illegal redirection %d", a);
+	if (fp != NULL) {
+		files[i].fname = tostring(s);
+		files[i].fp = fp;
+		files[i].mode = m;
+	}
+	return fp;
+}
+
+char *filename(FILE *fp)
+{
+	int i;
+
+	for (i = 0; i < FOPEN_MAX; i++)
+		if (fp == files[i].fp)
+			return files[i].fname;
+	return "???";
+}
+
+Cell *closefile(Node **a, int n)
+{
+	Cell *x;
+	int i, stat;
+
+	n = n;
+	x = execute(a[0]);
+	getsval(x);
+	for (i = 0; i < FOPEN_MAX; i++)
+		if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) {
+			if (ferror(files[i].fp))
+				WARNING( "i/o error occurred on %s", files[i].fname );
+			if (files[i].mode == '|' || files[i].mode == LE)
+				stat = pclose(files[i].fp);
+			else
+				stat = fclose(files[i].fp);
+			if (stat == EOF)
+				WARNING( "i/o error occurred closing %s", files[i].fname );
+			if (i > 2)	/* don't do /dev/std... */
+				xfree(files[i].fname);
+			files[i].fname = NULL;	/* watch out for ref thru this */
+			files[i].fp = NULL;
+		}
+	tempfree(x);
+	return(True);
+}
+
+void closeall(void)
+{
+	int i, stat;
+
+	for (i = 0; i < FOPEN_MAX; i++)
+		if (files[i].fp) {
+			if (ferror(files[i].fp))
+				WARNING( "i/o error occurred on %s", files[i].fname );
+			if (files[i].mode == '|' || files[i].mode == LE)
+				stat = pclose(files[i].fp);
+			else
+				stat = fclose(files[i].fp);
+			if (stat == EOF)
+				WARNING( "i/o error occurred while closing %s", files[i].fname );
+		}
+}
+
+void backsub(char **pb_ptr, char **sptr_ptr);
+
+Cell *sub(Node **a, int nnn)	/* substitute command */
+{
+	char *sptr, *pb, *q;
+	Cell *x, *y, *result;
+	char *t, *buf;
+	void *p;
+	int bufsz = recsize;
+
+	if ((buf = (char *) malloc(bufsz)) == NULL)
+		FATAL("out of memory in sub");
+	x = execute(a[3]);	/* target string */
+	t = getsval(x);
+	if (a[0] == 0)		/* 0 => a[1] is already-compiled regexpr */
+		p = (void *) a[1];	/* regular expression */
+	else {
+		y = execute(a[1]);
+		p = compre(getsval(y));
+		tempfree(y);
+	}
+	y = execute(a[2]);	/* replacement string */
+	result = False;
+	if (pmatch(p, t, t)) {
+		sptr = t;
+		adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub");
+		pb = buf;
+		while (sptr < patbeg)
+			*pb++ = *sptr++;
+		sptr = getsval(y);
+		while (*sptr != 0) {
+			adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "sub");
+			if (*sptr == '\\') {
+				backsub(&pb, &sptr);
+			} else if (*sptr == '&') {
+				sptr++;
+				adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "sub");
+				for (q = patbeg; q < patbeg+patlen; )
+					*pb++ = *q++;
+			} else
+				*pb++ = *sptr++;
+		}
+		*pb = '\0';
+		if (pb > buf + bufsz)
+			FATAL("sub result1 %.30s too big; can't happen", buf);
+		sptr = patbeg + patlen;
+		if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) {
+			adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "sub");
+			while ((*pb++ = *sptr++) != 0)
+				;
+		}
+		if (pb > buf + bufsz)
+			FATAL("sub result2 %.30s too big; can't happen", buf);
+		setsval(x, buf);	/* BUG: should be able to avoid copy */
+		result = True;;
+	}
+	tempfree(x);
+	tempfree(y);
+	free(buf);
+	return result;
+}
+
+Cell *gsub(Node **a, int nnn)	/* global substitute */
+{
+	Cell *x, *y;
+	char *rptr, *sptr, *t, *pb, *c;
+	char *buf;
+	void *p;
+	int mflag, num;
+	int bufsz = recsize;
+
+	if ((buf = (char *)malloc(bufsz)) == NULL)
+		FATAL("out of memory in gsub");
+	mflag = 0;	/* if mflag == 0, can replace empty string */
+	num = 0;
+	x = execute(a[3]);	/* target string */
+	c = t = getsval(x);
+	if (a[0] == 0)		/* 0 => a[1] is already-compiled regexpr */
+		p = (void *) a[1];	/* regular expression */
+	else {
+		y = execute(a[1]);
+		p = compre(getsval(y));
+		tempfree(y);
+	}
+	y = execute(a[2]);	/* replacement string */
+	if (pmatch(p, t, c)) {
+		pb = buf;
+		rptr = getsval(y);
+		do {
+			if (patlen == 0 && *patbeg != 0) {	/* matched empty string */
+				if (mflag == 0) {	/* can replace empty */
+					num++;
+					sptr = rptr;
+					while (*sptr != 0) {
+						adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub");
+						if (*sptr == '\\') {
+							backsub(&pb, &sptr);
+						} else if (*sptr == '&') {
+							char *q;
+							sptr++;
+							adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub");
+							for (q = patbeg; q < patbeg+patlen; )
+								*pb++ = *q++;
+						} else
+							*pb++ = *sptr++;
+					}
+				}
+				if (*c == 0)	/* at end */
+					goto done;
+				adjbuf(&buf, &bufsz, 2+pb-buf, recsize, &pb, "gsub");
+				*pb++ = *c++;
+				if (pb > buf + bufsz)	/* BUG: not sure of this test */
+					FATAL("gsub result0 %.30s too big; can't happen", buf);
+				mflag = 0;
+			}
+			else {	/* matched nonempty string */
+				num++;
+				sptr = c;
+				adjbuf(&buf, &bufsz, 1+(patbeg-sptr)+pb-buf, recsize, &pb, "gsub");
+				while (sptr < patbeg)
+					*pb++ = *sptr++;
+				sptr = rptr;
+				while (*sptr != 0) {
+					adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub");
+					if (*sptr == '\\') {
+						backsub(&pb, &sptr);
+					} else if (*sptr == '&') {
+						char *q;
+						sptr++;
+						adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub");
+						for (q = patbeg; q < patbeg+patlen; )
+							*pb++ = *q++;
+					} else
+						*pb++ = *sptr++;
+				}
+				c = patbeg + patlen;
+				if ((c[-1] == 0) || (*c == 0))
+					goto done;
+				if (pb > buf + bufsz)
+					FATAL("gsub result1 %.30s too big; can't happen", buf);
+				mflag = 1;
+			}
+		} while (pmatch(p, t, c));
+		sptr = c;
+		adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub");
+		while ((*pb++ = *sptr++) != 0)
+			;
+	done:	if (pb > buf + bufsz)
+			FATAL("gsub result2 %.30s too big; can't happen", buf);
+		*pb = '\0';
+		setsval(x, buf);	/* BUG: should be able to avoid copy + free */
+	}
+	tempfree(x);
+	tempfree(y);
+	x = gettemp();
+	x->tval = NUM;
+	x->fval = num;
+	free(buf);
+	return(x);
+}
+
+void backsub(char **pb_ptr, char **sptr_ptr)	/* handle \\& variations */
+{						/* sptr[0] == '\\' */
+	char *pb = *pb_ptr, *sptr = *sptr_ptr;
+
+	if (sptr[1] == '\\') {
+		if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */
+			*pb++ = '\\';
+			*pb++ = '&';
+			sptr += 4;
+		} else if (sptr[2] == '&') {	/* \\& -> \ + matched */
+			*pb++ = '\\';
+			sptr += 2;
+		} else {			/* \\x -> \\x */
+			*pb++ = *sptr++;
+			*pb++ = *sptr++;
+		}
+	} else if (sptr[1] == '&') {	/* literal & */
+		sptr++;
+		*pb++ = *sptr++;
+	} else				/* literal \ */
+		*pb++ = *sptr++;
+
+	*pb_ptr = pb;
+	*sptr_ptr = sptr;
+}
+
diff --git a/src/cmd/awk/tran.c b/src/cmd/awk/tran.c
new file mode 100644
index 0000000..272a7fd
--- /dev/null
+++ b/src/cmd/awk/tran.c
@@ -0,0 +1,435 @@
+/****************************************************************
+Copyright (C) Lucent Technologies 1997
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appear in all
+copies and that both that the copyright notice and this
+permission notice and warranty disclaimer appear in supporting
+documentation, and that the name Lucent Technologies or any of
+its entities not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+****************************************************************/
+
+#define	DEBUG
+#include <stdio.h>
+#include <math.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include "awk.h"
+#include "y.tab.h"
+
+#define	FULLTAB	2	/* rehash when table gets this x full */
+#define	GROWTAB 4	/* grow table by this factor */
+
+Array	*symtab;	/* main symbol table */
+
+char	**FS;		/* initial field sep */
+char	**RS;		/* initial record sep */
+char	**OFS;		/* output field sep */
+char	**ORS;		/* output record sep */
+char	**OFMT;		/* output format for numbers */
+char	**CONVFMT;	/* format for conversions in getsval */
+Awkfloat *NF;		/* number of fields in current record */
+Awkfloat *NR;		/* number of current record */
+Awkfloat *FNR;		/* number of current record in current file */
+char	**FILENAME;	/* current filename argument */
+Awkfloat *ARGC;		/* number of arguments from command line */
+char	**SUBSEP;	/* subscript separator for a[i,j,k]; default \034 */
+Awkfloat *RSTART;	/* start of re matched with ~; origin 1 (!) */
+Awkfloat *RLENGTH;	/* length of same */
+
+Cell	*nrloc;		/* NR */
+Cell	*nfloc;		/* NF */
+Cell	*fnrloc;	/* FNR */
+Array	*ARGVtab;	/* symbol table containing ARGV[...] */
+Array	*ENVtab;	/* symbol table containing ENVIRON[...] */
+Cell	*rstartloc;	/* RSTART */
+Cell	*rlengthloc;	/* RLENGTH */
+Cell	*symtabloc;	/* SYMTAB */
+
+Cell	*nullloc;	/* a guaranteed empty cell */
+Node	*nullnode;	/* zero&null, converted into a node for comparisons */
+Cell	*literal0;
+
+extern Cell **fldtab;
+
+void syminit(void)	/* initialize symbol table with builtin vars */
+{
+	literal0 = setsymtab("0", "0", 0.0, NUM|STR|CON|DONTFREE, symtab);
+	/* this is used for if(x)... tests: */
+	nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON|DONTFREE, symtab);
+	nullnode = celltonode(nullloc, CCON);
+
+	FS = &setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab)->sval;
+	RS = &setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
+	OFS = &setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab)->sval;
+	ORS = &setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
+	OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
+	CONVFMT = &setsymtab("CONVFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
+	FILENAME = &setsymtab("FILENAME", "", 0.0, STR|DONTFREE, symtab)->sval;
+	nfloc = setsymtab("NF", "", 0.0, NUM, symtab);
+	NF = &nfloc->fval;
+	nrloc = setsymtab("NR", "", 0.0, NUM, symtab);
+	NR = &nrloc->fval;
+	fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab);
+	FNR = &fnrloc->fval;
+	SUBSEP = &setsymtab("SUBSEP", "\034", 0.0, STR|DONTFREE, symtab)->sval;
+	rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab);
+	RSTART = &rstartloc->fval;
+	rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab);
+	RLENGTH = &rlengthloc->fval;
+	symtabloc = setsymtab("SYMTAB", "", 0.0, ARR, symtab);
+	symtabloc->sval = (char *) symtab;
+}
+
+void arginit(int ac, char **av)	/* set up ARGV and ARGC */
+{
+	Cell *cp;
+	int i;
+	char temp[50];
+
+	ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval;
+	cp = setsymtab("ARGV", "", 0.0, ARR, symtab);
+	ARGVtab = makesymtab(NSYMTAB);	/* could be (int) ARGC as well */
+	cp->sval = (char *) ARGVtab;
+	for (i = 0; i < ac; i++) {
+		sprintf(temp, "%d", i);
+		if (is_number(*av))
+			setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab);
+		else
+			setsymtab(temp, *av, 0.0, STR, ARGVtab);
+		av++;
+	}
+}
+
+void envinit(char **envp)	/* set up ENVIRON variable */
+{
+	Cell *cp;
+	char *p;
+
+	cp = setsymtab("ENVIRON", "", 0.0, ARR, symtab);
+	ENVtab = makesymtab(NSYMTAB);
+	cp->sval = (char *) ENVtab;
+	for ( ; *envp; envp++) {
+		if ((p = strchr(*envp, '=')) == NULL)
+			continue;
+		*p++ = 0;	/* split into two strings at = */
+		if (is_number(p))
+			setsymtab(*envp, p, atof(p), STR|NUM, ENVtab);
+		else
+			setsymtab(*envp, p, 0.0, STR, ENVtab);
+		p[-1] = '=';	/* restore in case env is passed down to a shell */
+	}
+}
+
+Array *makesymtab(int n)	/* make a new symbol table */
+{
+	Array *ap;
+	Cell **tp;
+
+	ap = (Array *) malloc(sizeof(Array));
+	tp = (Cell **) calloc(n, sizeof(Cell *));
+	if (ap == NULL || tp == NULL)
+		FATAL("out of space in makesymtab");
+	ap->nelem = 0;
+	ap->size = n;
+	ap->tab = tp;
+	return(ap);
+}
+
+void freesymtab(Cell *ap)	/* free a symbol table */
+{
+	Cell *cp, *temp;
+	Array *tp;
+	int i;
+
+	if (!isarr(ap))
+		return;
+	tp = (Array *) ap->sval;
+	if (tp == NULL)
+		return;
+	for (i = 0; i < tp->size; i++) {
+		for (cp = tp->tab[i]; cp != NULL; cp = temp) {
+			xfree(cp->nval);
+			if (freeable(cp))
+				xfree(cp->sval);
+			temp = cp->cnext;	/* avoids freeing then using */
+			free(cp); 
+		}
+		tp->tab[i] = 0;
+	}
+	free(tp->tab);
+	free(tp);
+}
+
+void freeelem(Cell *ap, char *s)	/* free elem s from ap (i.e., ap["s"] */
+{
+	Array *tp;
+	Cell *p, *prev = NULL;
+	int h;
+	
+	tp = (Array *) ap->sval;
+	h = hash(s, tp->size);
+	for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext)
+		if (strcmp(s, p->nval) == 0) {
+			if (prev == NULL)	/* 1st one */
+				tp->tab[h] = p->cnext;
+			else			/* middle somewhere */
+				prev->cnext = p->cnext;
+			if (freeable(p))
+				xfree(p->sval);
+			free(p->nval);
+			free(p);
+			tp->nelem--;
+			return;
+		}
+}
+
+Cell *setsymtab(char *n, char *s, Awkfloat f, unsigned t, Array *tp)
+{
+	int h;
+	Cell *p;
+
+	if (n != NULL && (p = lookup(n, tp)) != NULL) {
+		   dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",
+			p, p->nval, p->sval, p->fval, p->tval) );
+		return(p);
+	}
+	p = (Cell *) malloc(sizeof(Cell));
+	if (p == NULL)
+		FATAL("out of space for symbol table at %s", n);
+	p->nval = tostring(n);
+	p->sval = s ? tostring(s) : tostring("");
+	p->fval = f;
+	p->tval = t;
+	p->csub = CUNK;
+	p->ctype = OCELL;
+	tp->nelem++;
+	if (tp->nelem > FULLTAB * tp->size)
+		rehash(tp);
+	h = hash(n, tp->size);
+	p->cnext = tp->tab[h];
+	tp->tab[h] = p;
+	   dprintf( ("setsymtab set %p: n=%s s=\"%s\" f=%g t=%o\n",
+		p, p->nval, p->sval, p->fval, p->tval) );
+	return(p);
+}
+
+int hash(char *s, int n)	/* form hash value for string s */
+{
+	unsigned hashval;
+
+	for (hashval = 0; *s != '\0'; s++)
+		hashval = (*s + 31 * hashval);
+	return hashval % n;
+}
+
+void rehash(Array *tp)	/* rehash items in small table into big one */
+{
+	int i, nh, nsz;
+	Cell *cp, *op, **np;
+
+	nsz = GROWTAB * tp->size;
+	np = (Cell **) calloc(nsz, sizeof(Cell *));
+	if (np == NULL)		/* can't do it, but can keep running. */
+		return;		/* someone else will run out later. */
+	for (i = 0; i < tp->size; i++) {
+		for (cp = tp->tab[i]; cp; cp = op) {
+			op = cp->cnext;
+			nh = hash(cp->nval, nsz);
+			cp->cnext = np[nh];
+			np[nh] = cp;
+		}
+	}
+	free(tp->tab);
+	tp->tab = np;
+	tp->size = nsz;
+}
+
+Cell *lookup(char *s, Array *tp)	/* look for s in tp */
+{
+	Cell *p;
+	int h;
+
+	h = hash(s, tp->size);
+	for (p = tp->tab[h]; p != NULL; p = p->cnext)
+		if (strcmp(s, p->nval) == 0)
+			return(p);	/* found it */
+	return(NULL);			/* not found */
+}
+
+Awkfloat setfval(Cell *vp, Awkfloat f)	/* set float val of a Cell */
+{
+	int fldno;
+
+	if ((vp->tval & (NUM | STR)) == 0) 
+		funnyvar(vp, "assign to");
+	if (isfld(vp)) {
+		donerec = 0;	/* mark $0 invalid */
+		fldno = atoi(vp->nval);
+		if (fldno > *NF)
+			newfld(fldno);
+		   dprintf( ("setting field %d to %g\n", fldno, f) );
+	} else if (isrec(vp)) {
+		donefld = 0;	/* mark $1... invalid */
+		donerec = 1;
+	}
+	if (freeable(vp))
+		xfree(vp->sval); /* free any previous string */
+	vp->tval &= ~STR;	/* mark string invalid */
+	vp->tval |= NUM;	/* mark number ok */
+	   dprintf( ("setfval %p: %s = %g, t=%o\n", vp, vp->nval, f, vp->tval) );
+	return vp->fval = f;
+}
+
+void funnyvar(Cell *vp, char *rw)
+{
+	if (isarr(vp))
+		FATAL("can't %s %s; it's an array name.", rw, vp->nval);
+	if (vp->tval & FCN)
+		FATAL("can't %s %s; it's a function.", rw, vp->nval);
+	WARNING("funny variable %p: n=%s s=\"%s\" f=%g t=%o",
+		vp, vp->nval, vp->sval, vp->fval, vp->tval);
+}
+
+char *setsval(Cell *vp, char *s)	/* set string val of a Cell */
+{
+	char *t;
+	int fldno;
+
+	   dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval) );
+	if ((vp->tval & (NUM | STR)) == 0)
+		funnyvar(vp, "assign to");
+	if (isfld(vp)) {
+		donerec = 0;	/* mark $0 invalid */
+		fldno = atoi(vp->nval);
+		if (fldno > *NF)
+			newfld(fldno);
+		   dprintf( ("setting field %d to %s (%p)\n", fldno, s, s) );
+	} else if (isrec(vp)) {
+		donefld = 0;	/* mark $1... invalid */
+		donerec = 1;
+	}
+	t = tostring(s);	/* in case it's self-assign */
+	vp->tval &= ~NUM;
+	vp->tval |= STR;
+	if (freeable(vp))
+		xfree(vp->sval);
+	vp->tval &= ~DONTFREE;
+	   dprintf( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, t,t, vp->tval) );
+	return(vp->sval = t);
+}
+
+Awkfloat getfval(Cell *vp)	/* get float val of a Cell */
+{
+	if ((vp->tval & (NUM | STR)) == 0)
+		funnyvar(vp, "read value of");
+	if (isfld(vp) && donefld == 0)
+		fldbld();
+	else if (isrec(vp) && donerec == 0)
+		recbld();
+	if (!isnum(vp)) {	/* not a number */
+		vp->fval = atof(vp->sval);	/* best guess */
+		if (is_number(vp->sval) && !(vp->tval&CON))
+			vp->tval |= NUM;	/* make NUM only sparingly */
+	}
+	   dprintf( ("getfval %p: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval) );
+	return(vp->fval);
+}
+
+char *getsval(Cell *vp)	/* get string val of a Cell */
+{
+	char s[100];	/* BUG: unchecked */
+	double dtemp;
+
+	if ((vp->tval & (NUM | STR)) == 0)
+		funnyvar(vp, "read value of");
+	if (isfld(vp) && donefld == 0)
+		fldbld();
+	else if (isrec(vp) && donerec == 0)
+		recbld();
+	if (isstr(vp) == 0) {
+		if (freeable(vp))
+			xfree(vp->sval);
+		if (modf(vp->fval, &dtemp) == 0)	/* it's integral */
+			sprintf(s, "%.30g", vp->fval);
+		else
+			sprintf(s, *CONVFMT, vp->fval);
+		vp->sval = tostring(s);
+		vp->tval &= ~DONTFREE;
+		vp->tval |= STR;
+	}
+	   dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, vp->sval, vp->sval, vp->tval) );
+	return(vp->sval);
+}
+
+char *tostring(char *s)	/* make a copy of string s */
+{
+	char *p;
+
+	p = (char *) malloc(strlen(s)+1);
+	if (p == NULL)
+		FATAL("out of space in tostring on %s", s);
+	strcpy(p, s);
+	return(p);
+}
+
+char *qstring(char *s, int delim)	/* collect string up to next delim */
+{
+	char *os = s;
+	int c, n;
+	char *buf, *bp;
+
+	if ((buf = (char *) malloc(strlen(s)+3)) == NULL)
+		FATAL( "out of space in qstring(%s)", s);
+	for (bp = buf; (c = *s) != delim; s++) {
+		if (c == '\n')
+			SYNTAX( "newline in string %.20s...", os );
+		else if (c != '\\')
+			*bp++ = c;
+		else {	/* \something */
+			c = *++s;
+			if (c == 0) {	/* \ at end */
+				*bp++ = '\\';
+				break;	/* for loop */
+			}	
+			switch (c) {
+			case '\\':	*bp++ = '\\'; break;
+			case 'n':	*bp++ = '\n'; break;
+			case 't':	*bp++ = '\t'; break;
+			case 'b':	*bp++ = '\b'; break;
+			case 'f':	*bp++ = '\f'; break;
+			case 'r':	*bp++ = '\r'; break;
+			default:
+				if (!isdigit(c)) {
+					*bp++ = c;
+					break;
+				}
+				n = c - '0';
+				if (isdigit(s[1])) {
+					n = 8 * n + *++s - '0';
+					if (isdigit(s[1]))
+						n = 8 * n + *++s - '0';
+				}
+				*bp++ = n;
+				break;
+			}
+		}
+	}
+	*bp++ = 0;
+	return buf;
+}
+
diff --git a/src/cmd/awk/y.output b/src/cmd/awk/y.output
new file mode 100644
index 0000000..c7f0678
--- /dev/null
+++ b/src/cmd/awk/y.output
@@ -0,0 +1,9032 @@
+
+state 0
+	$accept: .program $end 
+	opt_pst: .    (28)
+
+	$end  reduce 28 (src line 156)
+	error  shift 3
+	XBEGIN  reduce 28 (src line 156)
+	XEND  reduce 28 (src line 156)
+	NL  shift 6
+	{  reduce 28 (src line 156)
+	(  reduce 28 (src line 156)
+	;  shift 7
+	/  reduce 28 (src line 156)
+	ARG  reduce 28 (src line 156)
+	BLTIN  reduce 28 (src line 156)
+	FUNC  reduce 28 (src line 156)
+	SUB  reduce 28 (src line 156)
+	GSUB  reduce 28 (src line 156)
+	INDEX  reduce 28 (src line 156)
+	MATCHFCN  reduce 28 (src line 156)
+	SPRINTF  reduce 28 (src line 156)
+	VAR  reduce 28 (src line 156)
+	IVAR  reduce 28 (src line 156)
+	VARNF  reduce 28 (src line 156)
+	CALL  reduce 28 (src line 156)
+	NUMBER  reduce 28 (src line 156)
+	STRING  reduce 28 (src line 156)
+	GETLINE  reduce 28 (src line 156)
+	SPLIT  reduce 28 (src line 156)
+	SUBSTR  reduce 28 (src line 156)
+	+  reduce 28 (src line 156)
+	-  reduce 28 (src line 156)
+	NOT  reduce 28 (src line 156)
+	DECR  reduce 28 (src line 156)
+	INCR  reduce 28 (src line 156)
+	INDIRECT  reduce 28 (src line 156)
+	.  error
+
+	pas  goto 2
+	pst  goto 5
+	opt_pst  goto 4
+	program  goto 1
+
+state 1
+	$accept:  program.$end 
+
+	$end  accept
+	.  error
+
+
+state 2
+	program:  pas.    (1)
+
+	.  reduce 1 (src line 99)
+
+
+state 3
+	program:  error.    (2)
+
+	.  reduce 2 (src line 102)
+
+
+state 4
+	pas:  opt_pst.    (32)
+	pas:  opt_pst.pa_stats opt_pst 
+
+	XBEGIN  shift 12
+	XEND  shift 13
+	{  shift 16
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	FUNC  shift 14
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 32 (src line 167)
+
+	pattern  goto 15
+	term  goto 20
+	re  goto 19
+	pa_pat  goto 10
+	pa_stat  goto 9
+	pa_stats  goto 8
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	lbrace  goto 11
+	subop  goto 39
+
+state 5
+	opt_pst:  pst.    (29)
+	pst:  pst.NL 
+	pst:  pst.; 
+
+	NL  shift 47
+	;  shift 48
+	.  reduce 29 (src line 158)
+
+
+state 6
+	pst:  NL.    (87)
+
+	.  reduce 87 (src line 274)
+
+
+state 7
+	pst:  ;.    (88)
+
+	.  reduce 88 (src line 275)
+
+
+state 8
+	pas:  opt_pst pa_stats.opt_pst 
+	pa_stats:  pa_stats.opt_pst pa_stat 
+	opt_pst: .    (28)
+
+	NL  shift 6
+	;  shift 7
+	.  reduce 28 (src line 156)
+
+	pst  goto 5
+	opt_pst  goto 49
+
+state 9
+	pa_stats:  pa_stat.    (44)
+
+	.  reduce 44 (src line 190)
+
+
+10: shift/reduce conflict (shift 16(0), red'n 35(0)) on {
+state 10
+	pa_stat:  pa_pat.    (35)
+	pa_stat:  pa_pat.lbrace stmtlist } 
+	pa_stat:  pa_pat., pa_pat 
+	pa_stat:  pa_pat., pa_pat lbrace stmtlist } 
+
+	,  shift 51
+	{  shift 16
+	.  reduce 35 (src line 176)
+
+	lbrace  goto 50
+
+state 11
+	lbrace:  lbrace.NL 
+	pa_stat:  lbrace.stmtlist } 
+
+	error  shift 75
+	NL  shift 52
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 54
+	stmtlist  goto 53
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 12
+	pa_stat:  XBEGIN.lbrace stmtlist } 
+
+	{  shift 16
+	.  error
+
+	lbrace  goto 79
+
+state 13
+	pa_stat:  XEND.lbrace stmtlist } 
+
+	{  shift 16
+	.  error
+
+	lbrace  goto 80
+
+state 14
+	pa_stat:  FUNC.funcname ( varlist rparen $$42 lbrace stmtlist } 
+
+	VAR  shift 82
+	CALL  shift 83
+	.  error
+
+	funcname  goto 81
+
+15: shift/reduce conflict (shift 101(11), red'n 34(0)) on (
+15: shift/reduce conflict (shift 42(8), red'n 34(0)) on ARG
+15: shift/reduce conflict (shift 28(8), red'n 34(0)) on BLTIN
+15: shift/reduce conflict (shift 45(10), red'n 34(0)) on SUB
+15: shift/reduce conflict (shift 46(9), red'n 34(0)) on GSUB
+15: shift/reduce conflict (shift 33(9), red'n 34(0)) on INDEX
+15: shift/reduce conflict (shift 34(9), red'n 34(0)) on MATCHFCN
+15: shift/reduce conflict (shift 37(10), red'n 34(0)) on SPRINTF
+15: shift/reduce conflict (shift 41(11), red'n 34(0)) on VAR
+15: shift/reduce conflict (shift 22(11), red'n 34(0)) on IVAR
+15: shift/reduce conflict (shift 43(11), red'n 34(0)) on VARNF
+15: shift/reduce conflict (shift 29(8), red'n 34(0)) on CALL
+15: shift/reduce conflict (shift 35(9), red'n 34(0)) on NUMBER
+15: shift/reduce conflict (shift 38(10), red'n 34(0)) on STRING
+15: shift/reduce conflict (shift 32(6), red'n 34(0)) on GETLINE
+15: shift/reduce conflict (shift 36(10), red'n 34(0)) on SPLIT
+15: shift/reduce conflict (shift 40(10), red'n 34(0)) on SUBSTR
+15: shift/reduce conflict (shift 27(13), red'n 34(0)) on +
+15: shift/reduce conflict (shift 26(13), red'n 34(0)) on -
+15: shift/reduce conflict (shift 99(15), red'n 34(0)) on NOT
+15: shift/reduce conflict (shift 30(17), red'n 34(0)) on DECR
+15: shift/reduce conflict (shift 31(17), red'n 34(0)) on INCR
+15: shift/reduce conflict (shift 23(18), red'n 34(0)) on INDIRECT
+state 15
+	pa_pat:  pattern.    (34)
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 34 (src line 172)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 16
+	lbrace:  {.    (22)
+
+	.  reduce 22 (src line 143)
+
+
+17: shift/reduce conflict (shift 103(17), red'n 173(0)) on DECR
+17: shift/reduce conflict (shift 104(17), red'n 173(0)) on INCR
+state 17
+	pattern:  var.ASGNOP pattern 
+	term:  var.DECR 
+	term:  var.INCR 
+	term:  var.    (173)
+
+	ASGNOP  shift 102
+	DECR  shift 103
+	INCR  shift 104
+	.  reduce 173 (src line 418)
+
+
+state 18
+	pattern:  (.plist ) IN varname 
+	term:  (.pattern ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 106
+	plist  goto 105
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 19
+	pattern:  re.    (76)
+
+	.  reduce 76 (src line 250)
+
+
+20: shift/reduce conflict (shift 107(14), red'n 77(0)) on /
+20: shift/reduce conflict (shift 108(13), red'n 77(0)) on +
+20: shift/reduce conflict (shift 109(13), red'n 77(0)) on -
+state 20
+	pattern:  term.    (77)
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 77 (src line 251)
+
+
+state 21
+	var:  varname.    (174)
+	var:  varname.[ patlist ] 
+
+	[  shift 113
+	.  reduce 174 (src line 421)
+
+
+state 22
+	var:  IVAR.    (176)
+
+	.  reduce 176 (src line 424)
+
+
+state 23
+	var:  INDIRECT.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 114
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 24
+	re:  reg_expr.    (93)
+
+	.  reduce 93 (src line 282)
+
+
+state 25
+	re:  NOT.re 
+	term:  NOT.term 
+
+	(  shift 101
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 116
+	re  goto 115
+	reg_expr  goto 24
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 26
+	term:  -.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 117
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 27
+	term:  +.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 118
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 28
+	term:  BLTIN.( ) 
+	term:  BLTIN.( patlist ) 
+	term:  BLTIN.    (145)
+
+	(  shift 119
+	.  reduce 145 (src line 367)
+
+
+state 29
+	term:  CALL.( ) 
+	term:  CALL.( patlist ) 
+
+	(  shift 120
+	.  error
+
+
+state 30
+	term:  DECR.var 
+
+	ARG  shift 42
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	INDIRECT  shift 23
+	.  error
+
+	var  goto 121
+	varname  goto 21
+
+state 31
+	term:  INCR.var 
+
+	ARG  shift 42
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	INDIRECT  shift 23
+	.  error
+
+	var  goto 122
+	varname  goto 21
+
+state 32
+	term:  GETLINE.var LT term 
+	term:  GETLINE.LT term 
+	term:  GETLINE.var 
+	term:  GETLINE.    (155)
+
+	LT  shift 124
+	ARG  shift 42
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	INDIRECT  shift 23
+	.  reduce 155 (src line 377)
+
+	var  goto 123
+	varname  goto 21
+
+state 33
+	term:  INDEX.( pattern comma pattern ) 
+	term:  INDEX.( pattern comma reg_expr ) 
+
+	(  shift 125
+	.  error
+
+
+state 34
+	term:  MATCHFCN.( pattern comma reg_expr ) 
+	term:  MATCHFCN.( pattern comma pattern ) 
+
+	(  shift 126
+	.  error
+
+
+state 35
+	term:  NUMBER.    (161)
+
+	.  reduce 161 (src line 391)
+
+
+state 36
+	term:  SPLIT.( pattern comma varname comma pattern ) 
+	term:  SPLIT.( pattern comma varname comma reg_expr ) 
+	term:  SPLIT.( pattern comma varname ) 
+
+	(  shift 127
+	.  error
+
+
+state 37
+	term:  SPRINTF.( patlist ) 
+
+	(  shift 128
+	.  error
+
+
+state 38
+	term:  STRING.    (166)
+
+	.  reduce 166 (src line 399)
+
+
+state 39
+	term:  subop.( reg_expr comma pattern ) 
+	term:  subop.( pattern comma pattern ) 
+	term:  subop.( reg_expr comma pattern comma var ) 
+	term:  subop.( pattern comma pattern comma var ) 
+
+	(  shift 129
+	.  error
+
+
+state 40
+	term:  SUBSTR.( pattern comma pattern comma pattern ) 
+	term:  SUBSTR.( pattern comma pattern ) 
+
+	(  shift 130
+	.  error
+
+
+state 41
+	varname:  VAR.    (181)
+
+	.  reduce 181 (src line 436)
+
+
+state 42
+	varname:  ARG.    (182)
+
+	.  reduce 182 (src line 438)
+
+
+state 43
+	varname:  VARNF.    (183)
+
+	.  reduce 183 (src line 439)
+
+
+state 44
+	reg_expr:  /.$$95 REGEXPR / 
+	$$95: .    (95)
+
+	.  reduce 95 (src line 288)
+
+	$$95  goto 131
+
+state 45
+	subop:  SUB.    (131)
+
+	.  reduce 131 (src line 350)
+
+
+state 46
+	subop:  GSUB.    (132)
+
+	.  reduce 132 (src line 351)
+
+
+state 47
+	pst:  pst NL.    (89)
+
+	.  reduce 89 (src line 275)
+
+
+state 48
+	pst:  pst ;.    (90)
+
+	.  reduce 90 (src line 275)
+
+
+state 49
+	pas:  opt_pst pa_stats opt_pst.    (33)
+	pa_stats:  pa_stats opt_pst.pa_stat 
+
+	XBEGIN  shift 12
+	XEND  shift 13
+	{  shift 16
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	FUNC  shift 14
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 33 (src line 169)
+
+	pattern  goto 15
+	term  goto 20
+	re  goto 19
+	pa_pat  goto 10
+	pa_stat  goto 132
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	lbrace  goto 11
+	subop  goto 39
+
+state 50
+	lbrace:  lbrace.NL 
+	pa_stat:  pa_pat lbrace.stmtlist } 
+
+	error  shift 75
+	NL  shift 52
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 54
+	stmtlist  goto 133
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 51
+	pa_stat:  pa_pat ,.pa_pat 
+	pa_stat:  pa_pat ,.pa_pat lbrace stmtlist } 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 15
+	term  goto 20
+	re  goto 19
+	pa_pat  goto 134
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 52
+	lbrace:  lbrace NL.    (23)
+
+	.  reduce 23 (src line 144)
+
+
+state 53
+	pa_stat:  lbrace stmtlist.} 
+	stmtlist:  stmtlist.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	}  shift 135
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 136
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 54
+	stmtlist:  stmt.    (129)
+
+	.  reduce 129 (src line 345)
+
+
+state 55
+	stmt:  BREAK.st 
+
+	NL  shift 140
+	;  shift 139
+	.  error
+
+	st  goto 137
+	nl  goto 138
+
+state 56
+	stmt:  CLOSE.pattern st 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 141
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 57
+	stmt:  CONTINUE.st 
+
+	NL  shift 140
+	;  shift 139
+	.  error
+
+	st  goto 142
+	nl  goto 138
+
+state 58
+	do:  do.NL 
+	stmt:  do.$$112 stmt $$113 WHILE ( pattern ) st 
+	$$112: .    (112)
+
+	NL  shift 143
+	.  reduce 112 (src line 324)
+
+	$$112  goto 144
+
+state 59
+	stmt:  EXIT.pattern st 
+	stmt:  EXIT.st 
+
+	NL  shift 140
+	(  shift 18
+	;  shift 139
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 145
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	st  goto 146
+	nl  goto 138
+	subop  goto 39
+
+state 60
+	stmt:  for.    (117)
+
+	.  reduce 117 (src line 328)
+
+
+state 61
+	stmt:  if.stmt else stmt 
+	stmt:  if.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 147
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 62
+	lbrace:  lbrace.NL 
+	stmt:  lbrace.stmtlist rbrace 
+
+	error  shift 75
+	NL  shift 52
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 54
+	stmtlist  goto 148
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 63
+	stmt:  NEXT.st 
+
+	NL  shift 140
+	;  shift 139
+	.  error
+
+	st  goto 149
+	nl  goto 138
+
+state 64
+	stmt:  NEXTFILE.st 
+
+	NL  shift 140
+	;  shift 139
+	.  error
+
+	st  goto 150
+	nl  goto 138
+
+state 65
+	stmt:  RETURN.pattern st 
+	stmt:  RETURN.st 
+
+	NL  shift 140
+	(  shift 18
+	;  shift 139
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 151
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	st  goto 152
+	nl  goto 138
+	subop  goto 39
+
+state 66
+	stmt:  simple_stmt.st 
+
+	NL  shift 140
+	;  shift 139
+	.  error
+
+	st  goto 153
+	nl  goto 138
+
+state 67
+	stmt:  while.$$126 stmt 
+	$$126: .    (126)
+
+	.  reduce 126 (src line 341)
+
+	$$126  goto 154
+
+state 68
+	stmt:  ;.opt_nl 
+	opt_nl: .    (26)
+
+	NL  shift 140
+	.  reduce 26 (src line 151)
+
+	nl  goto 156
+	opt_nl  goto 155
+
+state 69
+	do:  DO.    (9)
+
+	.  reduce 9 (src line 117)
+
+
+state 70
+	for:  FOR.( opt_simple_stmt ; opt_nl pattern ; opt_nl opt_simple_stmt rparen $$13 stmt 
+	for:  FOR.( opt_simple_stmt ; ; opt_nl opt_simple_stmt rparen $$15 stmt 
+	for:  FOR.( varname IN varname rparen $$17 stmt 
+
+	(  shift 157
+	.  error
+
+
+state 71
+	if:  IF.( pattern rparen 
+
+	(  shift 158
+	.  error
+
+
+state 72
+	simple_stmt:  print.prarg | term 
+	simple_stmt:  print.prarg APPEND term 
+	simple_stmt:  print.prarg GT term 
+	simple_stmt:  print.prarg 
+	prarg: .    (82)
+
+	(  shift 161
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 82 (src line 264)
+
+	ppattern  goto 162
+	pplist  goto 160
+	prarg  goto 159
+	term  goto 165
+	re  goto 164
+	reg_expr  goto 24
+	var  goto 163
+	varname  goto 21
+	subop  goto 39
+
+state 73
+	simple_stmt:  DELETE.varname [ patlist ] 
+	simple_stmt:  DELETE.varname 
+
+	ARG  shift 42
+	VAR  shift 41
+	VARNF  shift 43
+	.  error
+
+	varname  goto 166
+
+state 74
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	simple_stmt:  pattern.    (105)
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 105 (src line 309)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 75
+	simple_stmt:  error.    (106)
+
+	.  reduce 106 (src line 310)
+
+
+state 76
+	while:  WHILE.( pattern rparen 
+
+	(  shift 167
+	.  error
+
+
+state 77
+	print:  PRINT.    (85)
+
+	.  reduce 85 (src line 270)
+
+
+state 78
+	print:  PRINTF.    (86)
+
+	.  reduce 86 (src line 271)
+
+
+state 79
+	lbrace:  lbrace.NL 
+	pa_stat:  XBEGIN lbrace.stmtlist } 
+
+	error  shift 75
+	NL  shift 52
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 54
+	stmtlist  goto 168
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 80
+	lbrace:  lbrace.NL 
+	pa_stat:  XEND lbrace.stmtlist } 
+
+	error  shift 75
+	NL  shift 52
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 54
+	stmtlist  goto 169
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 81
+	pa_stat:  FUNC funcname.( varlist rparen $$42 lbrace stmtlist } 
+
+	(  shift 170
+	.  error
+
+
+state 82
+	funcname:  VAR.    (19)
+
+	.  reduce 19 (src line 134)
+
+
+state 83
+	funcname:  CALL.    (20)
+
+	.  reduce 20 (src line 136)
+
+
+state 84
+	pattern:  pattern ?.pattern : pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 171
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 85
+	bor:  bor.NL 
+	pattern:  pattern bor.pattern 
+
+	NL  shift 172
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 173
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 86
+	and:  and.NL 
+	pattern:  pattern and.pattern 
+
+	NL  shift 174
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 175
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 87
+	pattern:  pattern EQ.pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 176
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 88
+	pattern:  pattern GE.pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 177
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 89
+	pattern:  pattern GT.pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 178
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 90
+	pattern:  pattern LE.pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 179
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 91
+	pattern:  pattern LT.pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 180
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 92
+	pattern:  pattern NE.pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 181
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 93
+	pattern:  pattern MATCHOP.reg_expr 
+	pattern:  pattern MATCHOP.pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 183
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 182
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 94
+	pattern:  pattern IN.varname 
+
+	ARG  shift 42
+	VAR  shift 41
+	VARNF  shift 43
+	.  error
+
+	varname  goto 184
+
+state 95
+	pattern:  pattern |.GETLINE var 
+	pattern:  pattern |.GETLINE 
+
+	GETLINE  shift 185
+	.  error
+
+
+state 96
+	pattern:  pattern term.    (75)
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 75 (src line 249)
+
+
+state 97
+	bor:  BOR.    (5)
+
+	.  reduce 5 (src line 109)
+
+
+state 98
+	and:  AND.    (3)
+
+	.  reduce 3 (src line 105)
+
+
+state 99
+	term:  NOT.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 116
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+100: shift/reduce conflict (shift 103(17), red'n 173(0)) on DECR
+100: shift/reduce conflict (shift 104(17), red'n 173(0)) on INCR
+state 100
+	term:  var.DECR 
+	term:  var.INCR 
+	term:  var.    (173)
+
+	DECR  shift 103
+	INCR  shift 104
+	.  reduce 173 (src line 418)
+
+
+state 101
+	term:  (.pattern ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 186
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 102
+	pattern:  var ASGNOP.pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 187
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 103
+	term:  var DECR.    (150)
+
+	.  reduce 150 (src line 372)
+
+
+state 104
+	term:  var INCR.    (151)
+
+	.  reduce 151 (src line 373)
+
+
+state 105
+	pattern:  ( plist.) IN varname 
+	plist:  plist.comma pattern 
+
+	,  shift 190
+	)  shift 188
+	.  error
+
+	comma  goto 189
+
+state 106
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	plist:  pattern.comma pattern 
+	term:  ( pattern.) 
+
+	,  shift 190
+	(  shift 101
+	|  shift 95
+	)  shift 192
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	comma  goto 191
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 107
+	term:  term /.ASGNOP term 
+	term:  term /.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	ASGNOP  shift 193
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 194
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 108
+	term:  term +.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 195
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 109
+	term:  term -.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 196
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 110
+	term:  term *.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 197
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 111
+	term:  term %.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 198
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 112
+	term:  term POWER.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 199
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 113
+	var:  varname [.patlist ] 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 201
+	patlist  goto 200
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 114
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+	var:  INDIRECT term.    (177)
+
+	.  reduce 177 (src line 425)
+
+
+state 115
+	re:  NOT re.    (94)
+
+	.  reduce 94 (src line 285)
+
+
+state 116
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+	term:  NOT term.    (142)
+
+	POWER  shift 112
+	.  reduce 142 (src line 364)
+
+
+state 117
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+	term:  - term.    (140)
+
+	POWER  shift 112
+	.  reduce 140 (src line 362)
+
+
+state 118
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+	term:  + term.    (141)
+
+	POWER  shift 112
+	.  reduce 141 (src line 363)
+
+
+state 119
+	term:  BLTIN (.) 
+	term:  BLTIN (.patlist ) 
+
+	(  shift 18
+	/  shift 44
+	)  shift 202
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 201
+	patlist  goto 203
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 120
+	term:  CALL (.) 
+	term:  CALL (.patlist ) 
+
+	(  shift 18
+	/  shift 44
+	)  shift 204
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 201
+	patlist  goto 205
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 121
+	term:  DECR var.    (148)
+
+	.  reduce 148 (src line 370)
+
+
+state 122
+	term:  INCR var.    (149)
+
+	.  reduce 149 (src line 371)
+
+
+state 123
+	term:  GETLINE var.LT term 
+	term:  GETLINE var.    (154)
+
+	LT  shift 206
+	.  reduce 154 (src line 376)
+
+
+state 124
+	term:  GETLINE LT.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 207
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 125
+	term:  INDEX (.pattern comma pattern ) 
+	term:  INDEX (.pattern comma reg_expr ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 208
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 126
+	term:  MATCHFCN (.pattern comma reg_expr ) 
+	term:  MATCHFCN (.pattern comma pattern ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 209
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 127
+	term:  SPLIT (.pattern comma varname comma pattern ) 
+	term:  SPLIT (.pattern comma varname comma reg_expr ) 
+	term:  SPLIT (.pattern comma varname ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 210
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 128
+	term:  SPRINTF (.patlist ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 201
+	patlist  goto 211
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 129
+	term:  subop (.reg_expr comma pattern ) 
+	term:  subop (.pattern comma pattern ) 
+	term:  subop (.reg_expr comma pattern comma var ) 
+	term:  subop (.pattern comma pattern comma var ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 213
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 212
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 130
+	term:  SUBSTR (.pattern comma pattern comma pattern ) 
+	term:  SUBSTR (.pattern comma pattern ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 214
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 131
+	reg_expr:  / $$95.REGEXPR / 
+
+	REGEXPR  shift 215
+	.  error
+
+
+state 132
+	pa_stats:  pa_stats opt_pst pa_stat.    (45)
+
+	.  reduce 45 (src line 192)
+
+
+state 133
+	pa_stat:  pa_pat lbrace stmtlist.} 
+	stmtlist:  stmtlist.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	}  shift 216
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 136
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+134: shift/reduce conflict (shift 16(0), red'n 37(0)) on {
+state 134
+	pa_stat:  pa_pat , pa_pat.    (37)
+	pa_stat:  pa_pat , pa_pat.lbrace stmtlist } 
+
+	{  shift 16
+	.  reduce 37 (src line 179)
+
+	lbrace  goto 217
+
+state 135
+	pa_stat:  lbrace stmtlist }.    (39)
+
+	.  reduce 39 (src line 181)
+
+
+state 136
+	stmtlist:  stmtlist stmt.    (130)
+
+	.  reduce 130 (src line 347)
+
+
+state 137
+	stmt:  BREAK st.    (109)
+
+	.  reduce 109 (src line 318)
+
+
+state 138
+	nl:  nl.NL 
+	st:  nl.    (107)
+
+	NL  shift 218
+	.  reduce 107 (src line 313)
+
+
+state 139
+	st:  ;.opt_nl 
+	opt_nl: .    (26)
+
+	NL  shift 140
+	.  reduce 26 (src line 151)
+
+	nl  goto 156
+	opt_nl  goto 219
+
+state 140
+	nl:  NL.    (24)
+
+	.  reduce 24 (src line 147)
+
+
+state 141
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	stmt:  CLOSE pattern.st 
+
+	NL  shift 140
+	(  shift 101
+	|  shift 95
+	;  shift 139
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	st  goto 220
+	nl  goto 138
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 142
+	stmt:  CONTINUE st.    (111)
+
+	.  reduce 111 (src line 322)
+
+
+state 143
+	do:  do NL.    (10)
+
+	.  reduce 10 (src line 118)
+
+
+state 144
+	stmt:  do $$112.stmt $$113 WHILE ( pattern ) st 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 221
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 145
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	stmt:  EXIT pattern.st 
+
+	NL  shift 140
+	(  shift 101
+	|  shift 95
+	;  shift 139
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	st  goto 222
+	nl  goto 138
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 146
+	stmt:  EXIT st.    (116)
+
+	.  reduce 116 (src line 327)
+
+
+147: shift/reduce conflict (shift 224(0), red'n 119(0)) on ELSE
+state 147
+	stmt:  if stmt.else stmt 
+	stmt:  if stmt.    (119)
+
+	ELSE  shift 224
+	.  reduce 119 (src line 330)
+
+	else  goto 223
+
+state 148
+	stmt:  lbrace stmtlist.rbrace 
+	stmtlist:  stmtlist.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	}  shift 226
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 136
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	rbrace  goto 225
+	subop  goto 39
+	print  goto 72
+
+state 149
+	stmt:  NEXT st.    (121)
+
+	.  reduce 121 (src line 332)
+
+
+state 150
+	stmt:  NEXTFILE st.    (122)
+
+	.  reduce 122 (src line 335)
+
+
+state 151
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	stmt:  RETURN pattern.st 
+
+	NL  shift 140
+	(  shift 101
+	|  shift 95
+	;  shift 139
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	st  goto 227
+	nl  goto 138
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 152
+	stmt:  RETURN st.    (124)
+
+	.  reduce 124 (src line 339)
+
+
+state 153
+	stmt:  simple_stmt st.    (125)
+
+	.  reduce 125 (src line 340)
+
+
+state 154
+	stmt:  while $$126.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 228
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 155
+	stmt:  ; opt_nl.    (128)
+
+	.  reduce 128 (src line 342)
+
+
+state 156
+	nl:  nl.NL 
+	opt_nl:  nl.    (27)
+
+	NL  shift 218
+	.  reduce 27 (src line 153)
+
+
+state 157
+	for:  FOR (.opt_simple_stmt ; opt_nl pattern ; opt_nl opt_simple_stmt rparen $$13 stmt 
+	for:  FOR (.opt_simple_stmt ; ; opt_nl opt_simple_stmt rparen $$15 stmt 
+	for:  FOR (.varname IN varname rparen $$17 stmt 
+	opt_simple_stmt: .    (30)
+
+	error  shift 75
+	(  shift 18
+	;  reduce 30 (src line 162)
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	DELETE  shift 73
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 231
+	opt_simple_stmt  goto 229
+	var  goto 17
+	varname  goto 230
+	subop  goto 39
+	print  goto 72
+
+state 158
+	if:  IF (.pattern rparen 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 232
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 159
+	simple_stmt:  print prarg.| term 
+	simple_stmt:  print prarg.APPEND term 
+	simple_stmt:  print prarg.GT term 
+	simple_stmt:  print prarg.    (102)
+
+	|  shift 233
+	APPEND  shift 234
+	GT  shift 235
+	.  reduce 102 (src line 306)
+
+
+state 160
+	pplist:  pplist.comma ppattern 
+	prarg:  pplist.    (83)
+
+	,  shift 190
+	.  reduce 83 (src line 266)
+
+	comma  goto 236
+
+state 161
+	ppattern:  (.plist ) IN varname 
+	prarg:  (.plist ) 
+	term:  (.pattern ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 106
+	plist  goto 237
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 162
+	ppattern:  ppattern.? ppattern : ppattern 
+	ppattern:  ppattern.bor ppattern 
+	ppattern:  ppattern.and ppattern 
+	ppattern:  ppattern.MATCHOP reg_expr 
+	ppattern:  ppattern.MATCHOP ppattern 
+	ppattern:  ppattern.IN varname 
+	ppattern:  ppattern.term 
+	pplist:  ppattern.    (80)
+
+	(  shift 101
+	MATCHOP  shift 241
+	AND  shift 98
+	BOR  shift 97
+	IN  shift 242
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 238
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 80 (src line 259)
+
+	term  goto 243
+	var  goto 100
+	varname  goto 21
+	and  goto 240
+	bor  goto 239
+	subop  goto 39
+
+163: shift/reduce conflict (shift 103(17), red'n 173(0)) on DECR
+163: shift/reduce conflict (shift 104(17), red'n 173(0)) on INCR
+state 163
+	ppattern:  var.ASGNOP ppattern 
+	term:  var.DECR 
+	term:  var.INCR 
+	term:  var.    (173)
+
+	ASGNOP  shift 244
+	DECR  shift 103
+	INCR  shift 104
+	.  reduce 173 (src line 418)
+
+
+state 164
+	ppattern:  re.    (57)
+
+	.  reduce 57 (src line 217)
+
+
+165: shift/reduce conflict (shift 108(13), red'n 58(0)) on +
+165: shift/reduce conflict (shift 109(13), red'n 58(0)) on -
+state 165
+	ppattern:  term.    (58)
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 58 (src line 218)
+
+
+state 166
+	simple_stmt:  DELETE varname.[ patlist ] 
+	simple_stmt:  DELETE varname.    (104)
+
+	[  shift 245
+	.  reduce 104 (src line 308)
+
+
+state 167
+	while:  WHILE (.pattern rparen 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 246
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 168
+	pa_stat:  XBEGIN lbrace stmtlist.} 
+	stmtlist:  stmtlist.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	}  shift 247
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 136
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 169
+	pa_stat:  XEND lbrace stmtlist.} 
+	stmtlist:  stmtlist.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	}  shift 248
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 136
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 170
+	pa_stat:  FUNC funcname (.varlist rparen $$42 lbrace stmtlist } 
+	varlist: .    (178)
+
+	VAR  shift 250
+	.  reduce 178 (src line 428)
+
+	varlist  goto 249
+
+state 171
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern ? pattern.: pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	:  shift 251
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 172
+	bor:  bor NL.    (6)
+
+	.  reduce 6 (src line 110)
+
+
+state 173
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern bor pattern.    (61)
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 61 (src line 225)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 174
+	and:  and NL.    (4)
+
+	.  reduce 4 (src line 106)
+
+
+state 175
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern and pattern.    (62)
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 62 (src line 227)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 176
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern EQ pattern.    (63)
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  error
+	MATCHOP  error
+	EQ  error
+	GE  error
+	GT  error
+	LE  error
+	LT  error
+	NE  error
+	IN  error
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 63 (src line 229)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 177
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern GE pattern.    (64)
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  error
+	MATCHOP  error
+	EQ  error
+	GE  error
+	GT  error
+	LE  error
+	LT  error
+	NE  error
+	IN  error
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 64 (src line 230)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 178
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern GT pattern.    (65)
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  error
+	MATCHOP  error
+	EQ  error
+	GE  error
+	GT  error
+	LE  error
+	LT  error
+	NE  error
+	IN  error
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 65 (src line 231)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 179
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern LE pattern.    (66)
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  error
+	MATCHOP  error
+	EQ  error
+	GE  error
+	GT  error
+	LE  error
+	LT  error
+	NE  error
+	IN  error
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 66 (src line 232)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 180
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern LT pattern.    (67)
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  error
+	MATCHOP  error
+	EQ  error
+	GE  error
+	GT  error
+	LE  error
+	LT  error
+	NE  error
+	IN  error
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 67 (src line 233)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 181
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern NE pattern.    (68)
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  error
+	MATCHOP  error
+	EQ  error
+	GE  error
+	GT  error
+	LE  error
+	LT  error
+	NE  error
+	IN  error
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 68 (src line 234)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+182: reduce/reduce conflict (red'ns 69 and 93 ) on $end
+182: reduce/reduce conflict (red'ns 69 and 93 ) on XBEGIN
+182: reduce/reduce conflict (red'ns 69 and 93 ) on XEND
+182: reduce/reduce conflict (red'ns 69 and 93 ) on NL
+182: reduce/reduce conflict (red'ns 69 and 93 ) on ,
+182: reduce/reduce conflict (red'ns 69 and 93 ) on {
+182: reduce/reduce conflict (red'ns 69 and 93 ) on (
+182: reduce/reduce conflict (red'ns 69 and 93 ) on |
+182: reduce/reduce conflict (red'ns 69 and 93 ) on ;
+182: reduce/reduce conflict (red'ns 69 and 93 ) on /
+182: reduce/reduce conflict (red'ns 69 and 93 ) on )
+182: reduce/reduce conflict (red'ns 69 and 93 ) on ]
+182: reduce/reduce conflict (red'ns 69 and 93 ) on MATCHOP
+182: reduce/reduce conflict (red'ns 69 and 93 ) on AND
+182: reduce/reduce conflict (red'ns 69 and 93 ) on BOR
+182: reduce/reduce conflict (red'ns 69 and 93 ) on EQ
+182: reduce/reduce conflict (red'ns 69 and 93 ) on GE
+182: reduce/reduce conflict (red'ns 69 and 93 ) on GT
+182: reduce/reduce conflict (red'ns 69 and 93 ) on LE
+182: reduce/reduce conflict (red'ns 69 and 93 ) on LT
+182: reduce/reduce conflict (red'ns 69 and 93 ) on NE
+182: reduce/reduce conflict (red'ns 69 and 93 ) on IN
+182: reduce/reduce conflict (red'ns 69 and 93 ) on ARG
+182: reduce/reduce conflict (red'ns 69 and 93 ) on BLTIN
+182: reduce/reduce conflict (red'ns 69 and 93 ) on FUNC
+182: reduce/reduce conflict (red'ns 69 and 93 ) on SUB
+182: reduce/reduce conflict (red'ns 69 and 93 ) on GSUB
+182: reduce/reduce conflict (red'ns 69 and 93 ) on INDEX
+182: reduce/reduce conflict (red'ns 69 and 93 ) on MATCHFCN
+182: reduce/reduce conflict (red'ns 69 and 93 ) on SPRINTF
+182: reduce/reduce conflict (red'ns 69 and 93 ) on VAR
+182: reduce/reduce conflict (red'ns 69 and 93 ) on IVAR
+182: reduce/reduce conflict (red'ns 69 and 93 ) on VARNF
+182: reduce/reduce conflict (red'ns 69 and 93 ) on CALL
+182: reduce/reduce conflict (red'ns 69 and 93 ) on NUMBER
+182: reduce/reduce conflict (red'ns 69 and 93 ) on STRING
+182: reduce/reduce conflict (red'ns 69 and 93 ) on ?
+182: reduce/reduce conflict (red'ns 69 and 93 ) on :
+182: reduce/reduce conflict (red'ns 69 and 93 ) on GETLINE
+182: reduce/reduce conflict (red'ns 69 and 93 ) on SPLIT
+182: reduce/reduce conflict (red'ns 69 and 93 ) on SUBSTR
+182: reduce/reduce conflict (red'ns 69 and 93 ) on +
+182: reduce/reduce conflict (red'ns 69 and 93 ) on -
+182: reduce/reduce conflict (red'ns 69 and 93 ) on NOT
+182: reduce/reduce conflict (red'ns 69 and 93 ) on DECR
+182: reduce/reduce conflict (red'ns 69 and 93 ) on INCR
+182: reduce/reduce conflict (red'ns 69 and 93 ) on INDIRECT
+state 182
+	pattern:  pattern MATCHOP reg_expr.    (69)
+	re:  reg_expr.    (93)
+
+	.  reduce 69 (src line 235)
+
+
+state 183
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern MATCHOP pattern.    (70)
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  error
+	MATCHOP  error
+	EQ  error
+	GE  error
+	GT  error
+	LE  error
+	LT  error
+	NE  error
+	IN  error
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 70 (src line 236)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 184
+	pattern:  pattern IN varname.    (71)
+
+	.  reduce 71 (src line 241)
+
+
+state 185
+	pattern:  pattern | GETLINE.var 
+	pattern:  pattern | GETLINE.    (74)
+
+	ARG  shift 42
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	INDIRECT  shift 23
+	.  reduce 74 (src line 246)
+
+	var  goto 252
+	varname  goto 21
+
+state 186
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  ( pattern.) 
+
+	(  shift 101
+	|  shift 95
+	)  shift 192
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 187
+	pattern:  var ASGNOP pattern.    (59)
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 59 (src line 221)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 188
+	pattern:  ( plist ).IN varname 
+
+	IN  shift 253
+	.  error
+
+
+state 189
+	comma:  comma.NL 
+	plist:  plist comma.pattern 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 255
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 190
+	comma:  ,.    (7)
+
+	.  reduce 7 (src line 113)
+
+
+state 191
+	comma:  comma.NL 
+	plist:  pattern comma.pattern 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 256
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 192
+	term:  ( pattern ).    (158)
+
+	.  reduce 158 (src line 383)
+
+
+state 193
+	term:  term / ASGNOP.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 257
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 194
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term / term.    (137)
+	term:  term.% term 
+	term:  term.POWER term 
+
+	POWER  shift 112
+	.  reduce 137 (src line 359)
+
+
+state 195
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term + term.    (134)
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 134 (src line 356)
+
+
+state 196
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term - term.    (135)
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 135 (src line 357)
+
+
+state 197
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term * term.    (136)
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	POWER  shift 112
+	.  reduce 136 (src line 358)
+
+
+state 198
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term % term.    (138)
+	term:  term.POWER term 
+
+	POWER  shift 112
+	.  reduce 138 (src line 360)
+
+
+state 199
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+	term:  term POWER term.    (139)
+
+	POWER  shift 112
+	.  reduce 139 (src line 361)
+
+
+state 200
+	patlist:  patlist.comma pattern 
+	var:  varname [ patlist.] 
+
+	,  shift 190
+	]  shift 259
+	.  error
+
+	comma  goto 258
+
+state 201
+	patlist:  pattern.    (46)
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 46 (src line 195)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 202
+	term:  BLTIN ( ).    (143)
+
+	.  reduce 143 (src line 365)
+
+
+state 203
+	patlist:  patlist.comma pattern 
+	term:  BLTIN ( patlist.) 
+
+	,  shift 190
+	)  shift 260
+	.  error
+
+	comma  goto 258
+
+state 204
+	term:  CALL ( ).    (146)
+
+	.  reduce 146 (src line 368)
+
+
+state 205
+	patlist:  patlist.comma pattern 
+	term:  CALL ( patlist.) 
+
+	,  shift 190
+	)  shift 261
+	.  error
+
+	comma  goto 258
+
+state 206
+	term:  GETLINE var LT.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 262
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 207
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+	term:  GETLINE LT term.    (153)
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 153 (src line 375)
+
+
+state 208
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  INDEX ( pattern.comma pattern ) 
+	term:  INDEX ( pattern.comma reg_expr ) 
+
+	,  shift 190
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	comma  goto 263
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 209
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  MATCHFCN ( pattern.comma reg_expr ) 
+	term:  MATCHFCN ( pattern.comma pattern ) 
+
+	,  shift 190
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	comma  goto 264
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 210
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  SPLIT ( pattern.comma varname comma pattern ) 
+	term:  SPLIT ( pattern.comma varname comma reg_expr ) 
+	term:  SPLIT ( pattern.comma varname ) 
+
+	,  shift 190
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	comma  goto 265
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 211
+	patlist:  patlist.comma pattern 
+	term:  SPRINTF ( patlist.) 
+
+	,  shift 190
+	)  shift 266
+	.  error
+
+	comma  goto 258
+
+212: shift/reduce conflict (shift 190(0), red'n 93(0)) on ,
+state 212
+	re:  reg_expr.    (93)
+	term:  subop ( reg_expr.comma pattern ) 
+	term:  subop ( reg_expr.comma pattern comma var ) 
+
+	,  shift 190
+	.  reduce 93 (src line 282)
+
+	comma  goto 267
+
+state 213
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  subop ( pattern.comma pattern ) 
+	term:  subop ( pattern.comma pattern comma var ) 
+
+	,  shift 190
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	comma  goto 268
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 214
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  SUBSTR ( pattern.comma pattern comma pattern ) 
+	term:  SUBSTR ( pattern.comma pattern ) 
+
+	,  shift 190
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	comma  goto 269
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 215
+	reg_expr:  / $$95 REGEXPR./ 
+
+	/  shift 270
+	.  error
+
+
+state 216
+	pa_stat:  pa_pat lbrace stmtlist }.    (36)
+
+	.  reduce 36 (src line 178)
+
+
+state 217
+	lbrace:  lbrace.NL 
+	pa_stat:  pa_pat , pa_pat lbrace.stmtlist } 
+
+	error  shift 75
+	NL  shift 52
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 54
+	stmtlist  goto 271
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 218
+	nl:  nl NL.    (25)
+
+	.  reduce 25 (src line 148)
+
+
+state 219
+	st:  ; opt_nl.    (108)
+
+	.  reduce 108 (src line 315)
+
+
+state 220
+	stmt:  CLOSE pattern st.    (110)
+
+	.  reduce 110 (src line 321)
+
+
+state 221
+	stmt:  do $$112 stmt.$$113 WHILE ( pattern ) st 
+	$$113: .    (113)
+
+	.  reduce 113 (src line 0)
+
+	$$113  goto 272
+
+state 222
+	stmt:  EXIT pattern st.    (115)
+
+	.  reduce 115 (src line 326)
+
+
+state 223
+	else:  else.NL 
+	stmt:  if stmt else.stmt 
+
+	error  shift 75
+	NL  shift 273
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 274
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 224
+	else:  ELSE.    (11)
+
+	.  reduce 11 (src line 121)
+
+
+state 225
+	rbrace:  rbrace.NL 
+	stmt:  lbrace stmtlist rbrace.    (120)
+
+	NL  shift 275
+	.  reduce 120 (src line 331)
+
+
+state 226
+	rbrace:  }.    (91)
+
+	.  reduce 91 (src line 278)
+
+
+state 227
+	stmt:  RETURN pattern st.    (123)
+
+	.  reduce 123 (src line 338)
+
+
+state 228
+	stmt:  while $$126 stmt.    (127)
+
+	.  reduce 127 (src line 0)
+
+
+state 229
+	for:  FOR ( opt_simple_stmt.; opt_nl pattern ; opt_nl opt_simple_stmt rparen $$13 stmt 
+	for:  FOR ( opt_simple_stmt.; ; opt_nl opt_simple_stmt rparen $$15 stmt 
+
+	;  shift 276
+	.  error
+
+
+230: shift/reduce conflict (shift 277(7), red'n 174(0)) on IN
+state 230
+	for:  FOR ( varname.IN varname rparen $$17 stmt 
+	var:  varname.    (174)
+	var:  varname.[ patlist ] 
+
+	[  shift 113
+	IN  shift 277
+	.  reduce 174 (src line 421)
+
+
+state 231
+	opt_simple_stmt:  simple_stmt.    (31)
+
+	.  reduce 31 (src line 164)
+
+
+state 232
+	if:  IF ( pattern.rparen 
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	)  shift 279
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	rparen  goto 278
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 233
+	simple_stmt:  print prarg |.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 280
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 234
+	simple_stmt:  print prarg APPEND.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 281
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 235
+	simple_stmt:  print prarg GT.term 
+
+	(  shift 101
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 282
+	var  goto 100
+	varname  goto 21
+	subop  goto 39
+
+state 236
+	comma:  comma.NL 
+	pplist:  pplist comma.ppattern 
+
+	NL  shift 254
+	(  shift 284
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	ppattern  goto 283
+	term  goto 165
+	re  goto 164
+	reg_expr  goto 24
+	var  goto 163
+	varname  goto 21
+	subop  goto 39
+
+state 237
+	ppattern:  ( plist.) IN varname 
+	plist:  plist.comma pattern 
+	prarg:  ( plist.) 
+
+	,  shift 190
+	)  shift 285
+	.  error
+
+	comma  goto 189
+
+state 238
+	ppattern:  ppattern ?.ppattern : ppattern 
+
+	(  shift 284
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	ppattern  goto 286
+	term  goto 165
+	re  goto 164
+	reg_expr  goto 24
+	var  goto 163
+	varname  goto 21
+	subop  goto 39
+
+state 239
+	bor:  bor.NL 
+	ppattern:  ppattern bor.ppattern 
+
+	NL  shift 172
+	(  shift 284
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	ppattern  goto 287
+	term  goto 165
+	re  goto 164
+	reg_expr  goto 24
+	var  goto 163
+	varname  goto 21
+	subop  goto 39
+
+state 240
+	and:  and.NL 
+	ppattern:  ppattern and.ppattern 
+
+	NL  shift 174
+	(  shift 284
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	ppattern  goto 288
+	term  goto 165
+	re  goto 164
+	reg_expr  goto 24
+	var  goto 163
+	varname  goto 21
+	subop  goto 39
+
+state 241
+	ppattern:  ppattern MATCHOP.reg_expr 
+	ppattern:  ppattern MATCHOP.ppattern 
+
+	(  shift 284
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	ppattern  goto 290
+	term  goto 165
+	re  goto 164
+	reg_expr  goto 289
+	var  goto 163
+	varname  goto 21
+	subop  goto 39
+
+state 242
+	ppattern:  ppattern IN.varname 
+
+	ARG  shift 42
+	VAR  shift 41
+	VARNF  shift 43
+	.  error
+
+	varname  goto 291
+
+state 243
+	ppattern:  ppattern term.    (56)
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 56 (src line 216)
+
+
+state 244
+	ppattern:  var ASGNOP.ppattern 
+
+	(  shift 284
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	ppattern  goto 292
+	term  goto 165
+	re  goto 164
+	reg_expr  goto 24
+	var  goto 163
+	varname  goto 21
+	subop  goto 39
+
+state 245
+	simple_stmt:  DELETE varname [.patlist ] 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 201
+	patlist  goto 293
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 246
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	while:  WHILE ( pattern.rparen 
+
+	(  shift 101
+	|  shift 95
+	)  shift 279
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	rparen  goto 294
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 247
+	pa_stat:  XBEGIN lbrace stmtlist }.    (40)
+
+	.  reduce 40 (src line 182)
+
+
+state 248
+	pa_stat:  XEND lbrace stmtlist }.    (41)
+
+	.  reduce 41 (src line 184)
+
+
+state 249
+	pa_stat:  FUNC funcname ( varlist.rparen $$42 lbrace stmtlist } 
+	varlist:  varlist.comma VAR 
+
+	,  shift 190
+	)  shift 279
+	.  error
+
+	rparen  goto 295
+	comma  goto 296
+
+state 250
+	varlist:  VAR.    (179)
+
+	.  reduce 179 (src line 430)
+
+
+state 251
+	pattern:  pattern ? pattern :.pattern 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 297
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 252
+	pattern:  pattern | GETLINE var.    (73)
+
+	.  reduce 73 (src line 243)
+
+
+state 253
+	pattern:  ( plist ) IN.varname 
+
+	ARG  shift 42
+	VAR  shift 41
+	VARNF  shift 43
+	.  error
+
+	varname  goto 298
+
+state 254
+	comma:  comma NL.    (8)
+
+	.  reduce 8 (src line 114)
+
+
+state 255
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	plist:  plist comma pattern.    (79)
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 79 (src line 256)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 256
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	plist:  pattern comma pattern.    (78)
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 78 (src line 254)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 257
+	term:  term./ ASGNOP term 
+	term:  term / ASGNOP term.    (133)
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 133 (src line 354)
+
+
+state 258
+	comma:  comma.NL 
+	patlist:  patlist comma.pattern 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 299
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 259
+	var:  varname [ patlist ].    (175)
+
+	.  reduce 175 (src line 423)
+
+
+state 260
+	term:  BLTIN ( patlist ).    (144)
+
+	.  reduce 144 (src line 366)
+
+
+state 261
+	term:  CALL ( patlist ).    (147)
+
+	.  reduce 147 (src line 369)
+
+
+state 262
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+	term:  GETLINE var LT term.    (152)
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 152 (src line 374)
+
+
+state 263
+	comma:  comma.NL 
+	term:  INDEX ( pattern comma.pattern ) 
+	term:  INDEX ( pattern comma.reg_expr ) 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 300
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 301
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 264
+	comma:  comma.NL 
+	term:  MATCHFCN ( pattern comma.reg_expr ) 
+	term:  MATCHFCN ( pattern comma.pattern ) 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 303
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 302
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 265
+	comma:  comma.NL 
+	term:  SPLIT ( pattern comma.varname comma pattern ) 
+	term:  SPLIT ( pattern comma.varname comma reg_expr ) 
+	term:  SPLIT ( pattern comma.varname ) 
+
+	NL  shift 254
+	ARG  shift 42
+	VAR  shift 41
+	VARNF  shift 43
+	.  error
+
+	varname  goto 304
+
+state 266
+	term:  SPRINTF ( patlist ).    (165)
+
+	.  reduce 165 (src line 398)
+
+
+state 267
+	comma:  comma.NL 
+	term:  subop ( reg_expr comma.pattern ) 
+	term:  subop ( reg_expr comma.pattern comma var ) 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 305
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 268
+	comma:  comma.NL 
+	term:  subop ( pattern comma.pattern ) 
+	term:  subop ( pattern comma.pattern comma var ) 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 306
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 269
+	comma:  comma.NL 
+	term:  SUBSTR ( pattern comma.pattern comma pattern ) 
+	term:  SUBSTR ( pattern comma.pattern ) 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 307
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 270
+	reg_expr:  / $$95 REGEXPR /.    (96)
+
+	.  reduce 96 (src line 0)
+
+
+state 271
+	pa_stat:  pa_pat , pa_pat lbrace stmtlist.} 
+	stmtlist:  stmtlist.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	}  shift 308
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 136
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 272
+	stmt:  do $$112 stmt $$113.WHILE ( pattern ) st 
+
+	WHILE  shift 309
+	.  error
+
+
+state 273
+	else:  else NL.    (12)
+
+	.  reduce 12 (src line 122)
+
+
+state 274
+	stmt:  if stmt else stmt.    (118)
+
+	.  reduce 118 (src line 329)
+
+
+state 275
+	rbrace:  rbrace NL.    (92)
+
+	.  reduce 92 (src line 279)
+
+
+state 276
+	for:  FOR ( opt_simple_stmt ;.opt_nl pattern ; opt_nl opt_simple_stmt rparen $$13 stmt 
+	for:  FOR ( opt_simple_stmt ;.; opt_nl opt_simple_stmt rparen $$15 stmt 
+	opt_nl: .    (26)
+
+	NL  shift 140
+	;  shift 311
+	.  reduce 26 (src line 151)
+
+	nl  goto 156
+	opt_nl  goto 310
+
+state 277
+	for:  FOR ( varname IN.varname rparen $$17 stmt 
+
+	ARG  shift 42
+	VAR  shift 41
+	VARNF  shift 43
+	.  error
+
+	varname  goto 312
+
+state 278
+	if:  IF ( pattern rparen.    (21)
+	rparen:  rparen.NL 
+
+	NL  shift 313
+	.  reduce 21 (src line 139)
+
+
+state 279
+	rparen:  ).    (97)
+
+	.  reduce 97 (src line 292)
+
+
+state 280
+	simple_stmt:  print prarg | term.    (99)
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 99 (src line 296)
+
+
+state 281
+	simple_stmt:  print prarg APPEND term.    (100)
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 100 (src line 300)
+
+
+state 282
+	simple_stmt:  print prarg GT term.    (101)
+	term:  term./ ASGNOP term 
+	term:  term.+ term 
+	term:  term.- term 
+	term:  term.* term 
+	term:  term./ term 
+	term:  term.% term 
+	term:  term.POWER term 
+
+	/  shift 107
+	+  shift 108
+	-  shift 109
+	*  shift 110
+	%  shift 111
+	POWER  shift 112
+	.  reduce 101 (src line 303)
+
+
+state 283
+	ppattern:  ppattern.? ppattern : ppattern 
+	ppattern:  ppattern.bor ppattern 
+	ppattern:  ppattern.and ppattern 
+	ppattern:  ppattern.MATCHOP reg_expr 
+	ppattern:  ppattern.MATCHOP ppattern 
+	ppattern:  ppattern.IN varname 
+	ppattern:  ppattern.term 
+	pplist:  pplist comma ppattern.    (81)
+
+	(  shift 101
+	MATCHOP  shift 241
+	AND  shift 98
+	BOR  shift 97
+	IN  shift 242
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 238
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 81 (src line 261)
+
+	term  goto 243
+	var  goto 100
+	varname  goto 21
+	and  goto 240
+	bor  goto 239
+	subop  goto 39
+
+state 284
+	ppattern:  (.plist ) IN varname 
+	term:  (.pattern ) 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 106
+	plist  goto 314
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 285
+	ppattern:  ( plist ).IN varname 
+	prarg:  ( plist ).    (84)
+
+	IN  shift 315
+	.  reduce 84 (src line 267)
+
+
+state 286
+	ppattern:  ppattern.? ppattern : ppattern 
+	ppattern:  ppattern ? ppattern.: ppattern 
+	ppattern:  ppattern.bor ppattern 
+	ppattern:  ppattern.and ppattern 
+	ppattern:  ppattern.MATCHOP reg_expr 
+	ppattern:  ppattern.MATCHOP ppattern 
+	ppattern:  ppattern.IN varname 
+	ppattern:  ppattern.term 
+
+	(  shift 101
+	MATCHOP  shift 241
+	AND  shift 98
+	BOR  shift 97
+	IN  shift 242
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 238
+	:  shift 316
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 243
+	var  goto 100
+	varname  goto 21
+	and  goto 240
+	bor  goto 239
+	subop  goto 39
+
+state 287
+	ppattern:  ppattern.? ppattern : ppattern 
+	ppattern:  ppattern.bor ppattern 
+	ppattern:  ppattern bor ppattern.    (50)
+	ppattern:  ppattern.and ppattern 
+	ppattern:  ppattern.MATCHOP reg_expr 
+	ppattern:  ppattern.MATCHOP ppattern 
+	ppattern:  ppattern.IN varname 
+	ppattern:  ppattern.term 
+
+	(  shift 101
+	MATCHOP  shift 241
+	AND  shift 98
+	IN  shift 242
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 50 (src line 204)
+
+	term  goto 243
+	var  goto 100
+	varname  goto 21
+	and  goto 240
+	bor  goto 239
+	subop  goto 39
+
+state 288
+	ppattern:  ppattern.? ppattern : ppattern 
+	ppattern:  ppattern.bor ppattern 
+	ppattern:  ppattern.and ppattern 
+	ppattern:  ppattern and ppattern.    (51)
+	ppattern:  ppattern.MATCHOP reg_expr 
+	ppattern:  ppattern.MATCHOP ppattern 
+	ppattern:  ppattern.IN varname 
+	ppattern:  ppattern.term 
+
+	(  shift 101
+	MATCHOP  shift 241
+	IN  shift 242
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 51 (src line 206)
+
+	term  goto 243
+	var  goto 100
+	varname  goto 21
+	and  goto 240
+	bor  goto 239
+	subop  goto 39
+
+289: reduce/reduce conflict (red'ns 52 and 93 ) on NL
+289: reduce/reduce conflict (red'ns 52 and 93 ) on ,
+289: reduce/reduce conflict (red'ns 52 and 93 ) on (
+289: reduce/reduce conflict (red'ns 52 and 93 ) on |
+289: reduce/reduce conflict (red'ns 52 and 93 ) on ;
+289: reduce/reduce conflict (red'ns 52 and 93 ) on )
+289: reduce/reduce conflict (red'ns 52 and 93 ) on MATCHOP
+289: reduce/reduce conflict (red'ns 52 and 93 ) on AND
+289: reduce/reduce conflict (red'ns 52 and 93 ) on BOR
+289: reduce/reduce conflict (red'ns 52 and 93 ) on APPEND
+289: reduce/reduce conflict (red'ns 52 and 93 ) on GT
+289: reduce/reduce conflict (red'ns 52 and 93 ) on IN
+289: reduce/reduce conflict (red'ns 52 and 93 ) on ARG
+289: reduce/reduce conflict (red'ns 52 and 93 ) on BLTIN
+289: reduce/reduce conflict (red'ns 52 and 93 ) on SUB
+289: reduce/reduce conflict (red'ns 52 and 93 ) on GSUB
+289: reduce/reduce conflict (red'ns 52 and 93 ) on INDEX
+289: reduce/reduce conflict (red'ns 52 and 93 ) on MATCHFCN
+289: reduce/reduce conflict (red'ns 52 and 93 ) on SPRINTF
+289: reduce/reduce conflict (red'ns 52 and 93 ) on VAR
+289: reduce/reduce conflict (red'ns 52 and 93 ) on IVAR
+289: reduce/reduce conflict (red'ns 52 and 93 ) on VARNF
+289: reduce/reduce conflict (red'ns 52 and 93 ) on CALL
+289: reduce/reduce conflict (red'ns 52 and 93 ) on NUMBER
+289: reduce/reduce conflict (red'ns 52 and 93 ) on STRING
+289: reduce/reduce conflict (red'ns 52 and 93 ) on ?
+289: reduce/reduce conflict (red'ns 52 and 93 ) on :
+289: reduce/reduce conflict (red'ns 52 and 93 ) on GETLINE
+289: reduce/reduce conflict (red'ns 52 and 93 ) on SPLIT
+289: reduce/reduce conflict (red'ns 52 and 93 ) on SUBSTR
+289: reduce/reduce conflict (red'ns 52 and 93 ) on +
+289: reduce/reduce conflict (red'ns 52 and 93 ) on -
+289: reduce/reduce conflict (red'ns 52 and 93 ) on NOT
+289: reduce/reduce conflict (red'ns 52 and 93 ) on DECR
+289: reduce/reduce conflict (red'ns 52 and 93 ) on INCR
+289: reduce/reduce conflict (red'ns 52 and 93 ) on INDIRECT
+state 289
+	ppattern:  ppattern MATCHOP reg_expr.    (52)
+	re:  reg_expr.    (93)
+
+	.  reduce 52 (src line 208)
+
+
+state 290
+	ppattern:  ppattern.? ppattern : ppattern 
+	ppattern:  ppattern.bor ppattern 
+	ppattern:  ppattern.and ppattern 
+	ppattern:  ppattern.MATCHOP reg_expr 
+	ppattern:  ppattern.MATCHOP ppattern 
+	ppattern:  ppattern MATCHOP ppattern.    (53)
+	ppattern:  ppattern.IN varname 
+	ppattern:  ppattern.term 
+
+	(  shift 101
+	MATCHOP  error
+	IN  error
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 53 (src line 209)
+
+	term  goto 243
+	var  goto 100
+	varname  goto 21
+	and  goto 240
+	bor  goto 239
+	subop  goto 39
+
+state 291
+	ppattern:  ppattern IN varname.    (54)
+
+	.  reduce 54 (src line 214)
+
+
+state 292
+	ppattern:  var ASGNOP ppattern.    (48)
+	ppattern:  ppattern.? ppattern : ppattern 
+	ppattern:  ppattern.bor ppattern 
+	ppattern:  ppattern.and ppattern 
+	ppattern:  ppattern.MATCHOP reg_expr 
+	ppattern:  ppattern.MATCHOP ppattern 
+	ppattern:  ppattern.IN varname 
+	ppattern:  ppattern.term 
+
+	(  shift 101
+	MATCHOP  shift 241
+	AND  shift 98
+	BOR  shift 97
+	IN  shift 242
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 238
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 48 (src line 200)
+
+	term  goto 243
+	var  goto 100
+	varname  goto 21
+	and  goto 240
+	bor  goto 239
+	subop  goto 39
+
+state 293
+	patlist:  patlist.comma pattern 
+	simple_stmt:  DELETE varname [ patlist.] 
+
+	,  shift 190
+	]  shift 317
+	.  error
+
+	comma  goto 258
+
+state 294
+	rparen:  rparen.NL 
+	while:  WHILE ( pattern rparen.    (184)
+
+	NL  shift 313
+	.  reduce 184 (src line 443)
+
+
+state 295
+	pa_stat:  FUNC funcname ( varlist rparen.$$42 lbrace stmtlist } 
+	rparen:  rparen.NL 
+	$$42: .    (42)
+
+	NL  shift 313
+	.  reduce 42 (src line 186)
+
+	$$42  goto 318
+
+state 296
+	comma:  comma.NL 
+	varlist:  varlist comma.VAR 
+
+	NL  shift 254
+	VAR  shift 319
+	.  error
+
+
+state 297
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern ? pattern : pattern.    (60)
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 60 (src line 223)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 298
+	pattern:  ( plist ) IN varname.    (72)
+
+	.  reduce 72 (src line 242)
+
+
+state 299
+	patlist:  patlist comma pattern.    (47)
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 47 (src line 197)
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 300
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  INDEX ( pattern comma pattern.) 
+
+	(  shift 101
+	|  shift 95
+	)  shift 320
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+301: shift/reduce conflict (shift 321(0), red'n 93(0)) on )
+state 301
+	re:  reg_expr.    (93)
+	term:  INDEX ( pattern comma reg_expr.) 
+
+	)  shift 321
+	.  reduce 93 (src line 282)
+
+
+302: shift/reduce conflict (shift 322(0), red'n 93(0)) on )
+state 302
+	re:  reg_expr.    (93)
+	term:  MATCHFCN ( pattern comma reg_expr.) 
+
+	)  shift 322
+	.  reduce 93 (src line 282)
+
+
+state 303
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  MATCHFCN ( pattern comma pattern.) 
+
+	(  shift 101
+	|  shift 95
+	)  shift 323
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 304
+	term:  SPLIT ( pattern comma varname.comma pattern ) 
+	term:  SPLIT ( pattern comma varname.comma reg_expr ) 
+	term:  SPLIT ( pattern comma varname.) 
+
+	,  shift 190
+	)  shift 325
+	.  error
+
+	comma  goto 324
+
+state 305
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  subop ( reg_expr comma pattern.) 
+	term:  subop ( reg_expr comma pattern.comma var ) 
+
+	,  shift 190
+	(  shift 101
+	|  shift 95
+	)  shift 326
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	comma  goto 327
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 306
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  subop ( pattern comma pattern.) 
+	term:  subop ( pattern comma pattern.comma var ) 
+
+	,  shift 190
+	(  shift 101
+	|  shift 95
+	)  shift 328
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	comma  goto 329
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 307
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  SUBSTR ( pattern comma pattern.comma pattern ) 
+	term:  SUBSTR ( pattern comma pattern.) 
+
+	,  shift 190
+	(  shift 101
+	|  shift 95
+	)  shift 331
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	comma  goto 330
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 308
+	pa_stat:  pa_pat , pa_pat lbrace stmtlist }.    (38)
+
+	.  reduce 38 (src line 180)
+
+
+state 309
+	stmt:  do $$112 stmt $$113 WHILE.( pattern ) st 
+
+	(  shift 332
+	.  error
+
+
+state 310
+	for:  FOR ( opt_simple_stmt ; opt_nl.pattern ; opt_nl opt_simple_stmt rparen $$13 stmt 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 333
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 311
+	for:  FOR ( opt_simple_stmt ; ;.opt_nl opt_simple_stmt rparen $$15 stmt 
+	opt_nl: .    (26)
+
+	NL  shift 140
+	.  reduce 26 (src line 151)
+
+	nl  goto 156
+	opt_nl  goto 334
+
+state 312
+	for:  FOR ( varname IN varname.rparen $$17 stmt 
+
+	)  shift 279
+	.  error
+
+	rparen  goto 335
+
+state 313
+	rparen:  rparen NL.    (98)
+
+	.  reduce 98 (src line 293)
+
+
+state 314
+	ppattern:  ( plist.) IN varname 
+	plist:  plist.comma pattern 
+
+	,  shift 190
+	)  shift 336
+	.  error
+
+	comma  goto 189
+
+state 315
+	ppattern:  ( plist ) IN.varname 
+
+	ARG  shift 42
+	VAR  shift 41
+	VARNF  shift 43
+	.  error
+
+	varname  goto 337
+
+state 316
+	ppattern:  ppattern ? ppattern :.ppattern 
+
+	(  shift 284
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	ppattern  goto 338
+	term  goto 165
+	re  goto 164
+	reg_expr  goto 24
+	var  goto 163
+	varname  goto 21
+	subop  goto 39
+
+state 317
+	simple_stmt:  DELETE varname [ patlist ].    (103)
+
+	.  reduce 103 (src line 307)
+
+
+state 318
+	pa_stat:  FUNC funcname ( varlist rparen $$42.lbrace stmtlist } 
+
+	{  shift 16
+	.  error
+
+	lbrace  goto 339
+
+state 319
+	varlist:  varlist comma VAR.    (180)
+
+	.  reduce 180 (src line 431)
+
+
+state 320
+	term:  INDEX ( pattern comma pattern ).    (156)
+
+	.  reduce 156 (src line 378)
+
+
+state 321
+	term:  INDEX ( pattern comma reg_expr ).    (157)
+
+	.  reduce 157 (src line 380)
+
+
+state 322
+	term:  MATCHFCN ( pattern comma reg_expr ).    (159)
+
+	.  reduce 159 (src line 384)
+
+
+state 323
+	term:  MATCHFCN ( pattern comma pattern ).    (160)
+
+	.  reduce 160 (src line 386)
+
+
+state 324
+	comma:  comma.NL 
+	term:  SPLIT ( pattern comma varname comma.pattern ) 
+	term:  SPLIT ( pattern comma varname comma.reg_expr ) 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 340
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 341
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 325
+	term:  SPLIT ( pattern comma varname ).    (164)
+
+	.  reduce 164 (src line 396)
+
+
+state 326
+	term:  subop ( reg_expr comma pattern ).    (167)
+
+	.  reduce 167 (src line 400)
+
+
+state 327
+	comma:  comma.NL 
+	term:  subop ( reg_expr comma pattern comma.var ) 
+
+	NL  shift 254
+	ARG  shift 42
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	INDIRECT  shift 23
+	.  error
+
+	var  goto 342
+	varname  goto 21
+
+state 328
+	term:  subop ( pattern comma pattern ).    (168)
+
+	.  reduce 168 (src line 402)
+
+
+state 329
+	comma:  comma.NL 
+	term:  subop ( pattern comma pattern comma.var ) 
+
+	NL  shift 254
+	ARG  shift 42
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	INDIRECT  shift 23
+	.  error
+
+	var  goto 343
+	varname  goto 21
+
+state 330
+	comma:  comma.NL 
+	term:  SUBSTR ( pattern comma pattern comma.pattern ) 
+
+	NL  shift 254
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 344
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 331
+	term:  SUBSTR ( pattern comma pattern ).    (172)
+
+	.  reduce 172 (src line 416)
+
+
+state 332
+	stmt:  do $$112 stmt $$113 WHILE (.pattern ) st 
+
+	(  shift 18
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 345
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+
+state 333
+	for:  FOR ( opt_simple_stmt ; opt_nl pattern.; opt_nl opt_simple_stmt rparen $$13 stmt 
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+
+	(  shift 101
+	|  shift 95
+	;  shift 346
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 334
+	for:  FOR ( opt_simple_stmt ; ; opt_nl.opt_simple_stmt rparen $$15 stmt 
+	opt_simple_stmt: .    (30)
+
+	error  shift 75
+	(  shift 18
+	/  shift 44
+	)  reduce 30 (src line 162)
+	ARG  shift 42
+	BLTIN  shift 28
+	DELETE  shift 73
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 231
+	opt_simple_stmt  goto 347
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+	print  goto 72
+
+state 335
+	for:  FOR ( varname IN varname rparen.$$17 stmt 
+	rparen:  rparen.NL 
+	$$17: .    (17)
+
+	NL  shift 313
+	.  reduce 17 (src line 130)
+
+	$$17  goto 348
+
+state 336
+	ppattern:  ( plist ).IN varname 
+
+	IN  shift 315
+	.  error
+
+
+state 337
+	ppattern:  ( plist ) IN varname.    (55)
+
+	.  reduce 55 (src line 215)
+
+
+state 338
+	ppattern:  ppattern.? ppattern : ppattern 
+	ppattern:  ppattern ? ppattern : ppattern.    (49)
+	ppattern:  ppattern.bor ppattern 
+	ppattern:  ppattern.and ppattern 
+	ppattern:  ppattern.MATCHOP reg_expr 
+	ppattern:  ppattern.MATCHOP ppattern 
+	ppattern:  ppattern.IN varname 
+	ppattern:  ppattern.term 
+
+	(  shift 101
+	MATCHOP  shift 241
+	AND  shift 98
+	BOR  shift 97
+	IN  shift 242
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 238
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  reduce 49 (src line 202)
+
+	term  goto 243
+	var  goto 100
+	varname  goto 21
+	and  goto 240
+	bor  goto 239
+	subop  goto 39
+
+state 339
+	lbrace:  lbrace.NL 
+	pa_stat:  FUNC funcname ( varlist rparen $$42 lbrace.stmtlist } 
+
+	error  shift 75
+	NL  shift 52
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 54
+	stmtlist  goto 349
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 340
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  SPLIT ( pattern comma varname comma pattern.) 
+
+	(  shift 101
+	|  shift 95
+	)  shift 350
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+341: shift/reduce conflict (shift 351(0), red'n 93(0)) on )
+state 341
+	re:  reg_expr.    (93)
+	term:  SPLIT ( pattern comma varname comma reg_expr.) 
+
+	)  shift 351
+	.  reduce 93 (src line 282)
+
+
+state 342
+	term:  subop ( reg_expr comma pattern comma var.) 
+
+	)  shift 352
+	.  error
+
+
+state 343
+	term:  subop ( pattern comma pattern comma var.) 
+
+	)  shift 353
+	.  error
+
+
+state 344
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	term:  SUBSTR ( pattern comma pattern comma pattern.) 
+
+	(  shift 101
+	|  shift 95
+	)  shift 354
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 345
+	pattern:  pattern.? pattern : pattern 
+	pattern:  pattern.bor pattern 
+	pattern:  pattern.and pattern 
+	pattern:  pattern.EQ pattern 
+	pattern:  pattern.GE pattern 
+	pattern:  pattern.GT pattern 
+	pattern:  pattern.LE pattern 
+	pattern:  pattern.LT pattern 
+	pattern:  pattern.NE pattern 
+	pattern:  pattern.MATCHOP reg_expr 
+	pattern:  pattern.MATCHOP pattern 
+	pattern:  pattern.IN varname 
+	pattern:  pattern.| GETLINE var 
+	pattern:  pattern.| GETLINE 
+	pattern:  pattern.term 
+	stmt:  do $$112 stmt $$113 WHILE ( pattern.) st 
+
+	(  shift 101
+	|  shift 95
+	)  shift 355
+	MATCHOP  shift 93
+	AND  shift 98
+	BOR  shift 97
+	EQ  shift 87
+	GE  shift 88
+	GT  shift 89
+	LE  shift 90
+	LT  shift 91
+	NE  shift 92
+	IN  shift 94
+	ARG  shift 42
+	BLTIN  shift 28
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	?  shift 84
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 99
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	term  goto 96
+	var  goto 100
+	varname  goto 21
+	and  goto 86
+	bor  goto 85
+	subop  goto 39
+
+state 346
+	for:  FOR ( opt_simple_stmt ; opt_nl pattern ;.opt_nl opt_simple_stmt rparen $$13 stmt 
+	opt_nl: .    (26)
+
+	NL  shift 140
+	.  reduce 26 (src line 151)
+
+	nl  goto 156
+	opt_nl  goto 356
+
+state 347
+	for:  FOR ( opt_simple_stmt ; ; opt_nl opt_simple_stmt.rparen $$15 stmt 
+
+	)  shift 279
+	.  error
+
+	rparen  goto 357
+
+state 348
+	for:  FOR ( varname IN varname rparen $$17.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 358
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 349
+	pa_stat:  FUNC funcname ( varlist rparen $$42 lbrace stmtlist.} 
+	stmtlist:  stmtlist.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	}  shift 359
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 136
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 350
+	term:  SPLIT ( pattern comma varname comma pattern ).    (162)
+
+	.  reduce 162 (src line 392)
+
+
+state 351
+	term:  SPLIT ( pattern comma varname comma reg_expr ).    (163)
+
+	.  reduce 163 (src line 394)
+
+
+state 352
+	term:  subop ( reg_expr comma pattern comma var ).    (169)
+
+	.  reduce 169 (src line 407)
+
+
+state 353
+	term:  subop ( pattern comma pattern comma var ).    (170)
+
+	.  reduce 170 (src line 409)
+
+
+state 354
+	term:  SUBSTR ( pattern comma pattern comma pattern ).    (171)
+
+	.  reduce 171 (src line 414)
+
+
+state 355
+	stmt:  do $$112 stmt $$113 WHILE ( pattern ).st 
+
+	NL  shift 140
+	;  shift 139
+	.  error
+
+	st  goto 360
+	nl  goto 138
+
+state 356
+	for:  FOR ( opt_simple_stmt ; opt_nl pattern ; opt_nl.opt_simple_stmt rparen $$13 stmt 
+	opt_simple_stmt: .    (30)
+
+	error  shift 75
+	(  shift 18
+	/  shift 44
+	)  reduce 30 (src line 162)
+	ARG  shift 42
+	BLTIN  shift 28
+	DELETE  shift 73
+	SUB  shift 45
+	GSUB  shift 46
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 231
+	opt_simple_stmt  goto 361
+	var  goto 17
+	varname  goto 21
+	subop  goto 39
+	print  goto 72
+
+state 357
+	for:  FOR ( opt_simple_stmt ; ; opt_nl opt_simple_stmt rparen.$$15 stmt 
+	rparen:  rparen.NL 
+	$$15: .    (15)
+
+	NL  shift 313
+	.  reduce 15 (src line 128)
+
+	$$15  goto 362
+
+state 358
+	for:  FOR ( varname IN varname rparen $$17 stmt.    (18)
+
+	.  reduce 18 (src line 0)
+
+
+state 359
+	pa_stat:  FUNC funcname ( varlist rparen $$42 lbrace stmtlist }.    (43)
+
+	.  reduce 43 (src line 0)
+
+
+state 360
+	stmt:  do $$112 stmt $$113 WHILE ( pattern ) st.    (114)
+
+	.  reduce 114 (src line 0)
+
+
+state 361
+	for:  FOR ( opt_simple_stmt ; opt_nl pattern ; opt_nl opt_simple_stmt.rparen $$13 stmt 
+
+	)  shift 279
+	.  error
+
+	rparen  goto 363
+
+state 362
+	for:  FOR ( opt_simple_stmt ; ; opt_nl opt_simple_stmt rparen $$15.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 364
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 363
+	for:  FOR ( opt_simple_stmt ; opt_nl pattern ; opt_nl opt_simple_stmt rparen.$$13 stmt 
+	rparen:  rparen.NL 
+	$$13: .    (13)
+
+	NL  shift 313
+	.  reduce 13 (src line 125)
+
+	$$13  goto 365
+
+state 364
+	for:  FOR ( opt_simple_stmt ; ; opt_nl opt_simple_stmt rparen $$15 stmt.    (16)
+
+	.  reduce 16 (src line 0)
+
+
+state 365
+	for:  FOR ( opt_simple_stmt ; opt_nl pattern ; opt_nl opt_simple_stmt rparen $$13.stmt 
+
+	error  shift 75
+	{  shift 16
+	(  shift 18
+	;  shift 68
+	/  shift 44
+	ARG  shift 42
+	BLTIN  shift 28
+	BREAK  shift 55
+	CLOSE  shift 56
+	CONTINUE  shift 57
+	DELETE  shift 73
+	DO  shift 69
+	EXIT  shift 59
+	FOR  shift 70
+	SUB  shift 45
+	GSUB  shift 46
+	IF  shift 71
+	INDEX  shift 33
+	MATCHFCN  shift 34
+	NEXT  shift 63
+	NEXTFILE  shift 64
+	PRINT  shift 77
+	PRINTF  shift 78
+	SPRINTF  shift 37
+	VAR  shift 41
+	IVAR  shift 22
+	VARNF  shift 43
+	CALL  shift 29
+	NUMBER  shift 35
+	STRING  shift 38
+	GETLINE  shift 32
+	RETURN  shift 65
+	SPLIT  shift 36
+	SUBSTR  shift 40
+	WHILE  shift 76
+	+  shift 27
+	-  shift 26
+	NOT  shift 25
+	DECR  shift 30
+	INCR  shift 31
+	INDIRECT  shift 23
+	.  error
+
+	pattern  goto 74
+	term  goto 20
+	re  goto 19
+	reg_expr  goto 24
+	simple_stmt  goto 66
+	stmt  goto 366
+	var  goto 17
+	varname  goto 21
+	for  goto 60
+	if  goto 61
+	while  goto 67
+	do  goto 58
+	lbrace  goto 62
+	subop  goto 39
+	print  goto 72
+
+state 366
+	for:  FOR ( opt_simple_stmt ; opt_nl pattern ; opt_nl opt_simple_stmt rparen $$13 stmt.    (14)
+
+	.  reduce 14 (src line 0)
+
+
+111/511 terminals, 48/600 nonterminals
+185/1600 grammar rules, 367/2000 states
+42 shift/reduce, 83 reduce/reduce conflicts reported
+112/350 working sets used
+memory: states,etc. 3507/40000, parser 1243/40000
+174/2400 distinct lookahead sets
+238 extra closures
+4434 shift entries, 98 exceptions
+371 goto entries
+830 entries saved by goto default
+Optimizer space used: input 9564/40000, output 4170/40000
+4170 table entries, 2057 zero
+maximum spread: 110, maximum offset: 365