aboutsummaryrefslogtreecommitdiff
path: root/unix/boot/xyacc
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /unix/boot/xyacc
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'unix/boot/xyacc')
-rw-r--r--unix/boot/xyacc/Makefile21
-rw-r--r--unix/boot/xyacc/README117
-rw-r--r--unix/boot/xyacc/debug/dc.y306
-rw-r--r--unix/boot/xyacc/debug/y.output331
-rw-r--r--unix/boot/xyacc/debug/ytab.x645
-rw-r--r--unix/boot/xyacc/dextern.h382
-rw-r--r--unix/boot/xyacc/mkpkg.sh7
-rw-r--r--unix/boot/xyacc/y1.c1307
-rw-r--r--unix/boot/xyacc/y2.c1952
-rw-r--r--unix/boot/xyacc/y3.c606
-rw-r--r--unix/boot/xyacc/y4.c528
-rw-r--r--unix/boot/xyacc/yaccpar.x238
12 files changed, 6440 insertions, 0 deletions
diff --git a/unix/boot/xyacc/Makefile b/unix/boot/xyacc/Makefile
new file mode 100644
index 00000000..1afcdfdd
--- /dev/null
+++ b/unix/boot/xyacc/Makefile
@@ -0,0 +1,21 @@
+HLIB = ../../hlib/
+IRAFLIB = ../../../lib/
+VGRIND = csh /usr/ucb/vgrind -W
+
+head: xyacc
+xyacc: y1.o y2.o y3.o y4.o
+ cc -o xyacc.e y?.o
+
+y1.o y2.o y3.o y4.o: dextern files
+
+install:
+ mv -f xyacc.e $(HLIB)
+ cp yaccpar.x $(IRAFLIB)
+
+clean :
+ rm -f *.o
+
+vgrind:
+ cp /dev/null index
+ $(VGRIND) -h 'Yacc' dextern files y1.c y2.c y3.c y4.c
+ $(VGRIND) -h 'Yacc' -x index
diff --git a/unix/boot/xyacc/README b/unix/boot/xyacc/README
new file mode 100644
index 00000000..2da6b992
--- /dev/null
+++ b/unix/boot/xyacc/README
@@ -0,0 +1,117 @@
+.help xyacc
+.nf
+This directory contains the source for the Yacc compiler compiler as modified
+to produce SPP language parsers. This version of XYACC is based on code
+obtained from the OpenSolaris project and distributed under the Common
+Development and Distribution License (CDDL), considered to be a 'free'
+license. All parsers in the system will be regenerated using this new
+version of XYACC, all vestiges of the original XYACC code have been
+removed.
+
+Notes regarding the changes required for SPP from the original README
+file are included below.
+
+Mike Fitzpatrick
+1/25/2011
+
+
+------------------------------------------------------------------------------
+
+ For the most part, the operation of SPP/Yacc is as described in the
+Yacc reference manual, with the important differences noted below. A
+complete working example of a desk calculator program may be found in
+the subdirectory debug, file dc.y.
+
+Notes on SPP Yacc
+
+ (1) The Yacc input syntax is unmodified, except that the comment convention
+ is now as in SPP, rather than C (i.e., use #, rather than /*..*/).
+ All defines, actions, etc. are of course given in the SPP language.
+
+ (2) The Yacc output file is "ytab.x", rather than "y.tab.c". The token
+ defs file "y.tab.h" now contains SPP defines, rather than C #defines.
+ The states file "y.output" is completely unmodified.
+
+ (3) The global declarations section %{ .. %} had to be changed somewhat
+ because SPP does not have global variables. The section is now
+ divided into two subsections. The first is for global defines,
+ includes, etc. which go into the header area of the ytab.x file.
+ Then follows a %L, telling Yacc that the local declarations for
+ the parser procedure follow. This second section should contain
+ variable and function declarations required for the user supplied
+ actions (code fragments to be executed when a rule of the grammar
+ is recognized) in the yyparse procedure.
+
+ (4) The global declarations section MUST contain the following two
+ defines:
+
+ YYMAXDEPTH Depth of the parser stacks; determines
+ the maximum complexity of a language
+ construct which can be parsed. A typical
+ value is 150.
+
+ YYOPLEN The length, in struct units, of a token
+ operand value structure. You define the
+ operand structure to be whatever you wish;
+ all the parser needs to know is how big an
+ element is. The lexical analyzer and the
+ actions, both of which are supplied by the
+ user, use the operand structure for
+ communications. Operand structures are
+ always referred to by a Mem pointer.
+
+ (5) The calling sequence for the parser is as follows
+
+ status = yyparse (fd, debug, yylex)
+
+ where
+ status is OK, EOF, or ERR (syntax error)
+ fd is the text stream to be parsed
+ debug is a boolean, true to print debugging info
+ yylex is the user supplied lexical analysis procedure.
+
+ The calling sequence for the lexical analysis procedure is as
+ follows (the name "yylex" may be anything):
+
+ token = yylex (fd, yylval)
+
+ where
+ Token is the integer code for the token. The tokens are
+ named in the Yacc grammar, and are defined either by
+ the user or by Yacc in the header area of ytab.x.
+ If Yacc is permitted to assign codes to tokens, the
+ token defininitions file ytab.h is written out.
+ fd is the file to be read
+ yylval is a POINTER to the token value structure to be
+ returned by yylex.
+
+ (6) The SPP version of Yacc, unlike the C version, does not use any
+ external or global variables for communication between routines,
+ and hence it is possible for several distinct parsers to coexist
+ in the same image. If this is done, the user supplied yylex
+ procedures should be named something else, and the name of the
+ parser procedure (yyparse) should be changed. This can be done
+ by putting a "define yyparse" in the global definitions area.
+
+ (7) Token values (i.e., $$, $1, $2, yyval, yylval, etc.) are always
+ pointers to structures in the SPP version, as opposed to structures
+ in the C version. Thus actions like
+
+ { $$ = $1; }
+
+ which are common in the C version, are programmed like this in SPP:
+
+ { YYMOVE ($1, $$) }
+
+ where YYMOVE is a Yacc supplied macro which copies an operand
+ structure.
+
+ (8) The source for the language independent part of the parser is given
+ in "lib$yaccpar.x".
+
+Doug Tody, 21 Feb 84.
+20Jan85:
+ y.tab.x -> ytab.x (etc), added EOF token
+20Apr85:
+ lib$yaccpar.x, deleted entry points for examining parser stack and
+ other context state variables.
diff --git a/unix/boot/xyacc/debug/dc.y b/unix/boot/xyacc/debug/dc.y
new file mode 100644
index 00000000..0d6fe655
--- /dev/null
+++ b/unix/boot/xyacc/debug/dc.y
@@ -0,0 +1,306 @@
+# SPP/Yacc specification for a simple desk calculator. Input consists
+# of simple arithmetic expressions; output is the value of the expression.
+# Operands are restricted to integer and real numeric constants.
+
+%{
+include <ctype.h>
+include <lexnum.h>
+
+define YYMAXDEPTH 150 # length of parser stack
+
+task dc = t_dc
+
+# Operand Structure (parser stack)
+define YYOPLEN 2 # size of operand structure
+define OPTYPE Memi[$1] # operand datatype
+define OPVALI Memi[$1+1] # integer value of operand
+define OPVALR Memr[$1+1] # real value of operand
+
+%}
+
+%token CONST LETTER YYEOF
+
+%left '+' '-'
+%left '*' '/'
+%left UMINUS
+
+%%
+
+prog : # Empty
+ | prog stmt eost {
+ return (OK)
+ }
+ | YYEOF {
+ return (EOF)
+ }
+ | prog error '\n' {
+ yyerrok
+ }
+ ;
+
+stmt : expr {
+ # Print the value of an expression.
+ if (OPTYPE($1) == TY_INT) {
+ call printf ("%d\n")
+ call pargi (OPVALI($1))
+ } else {
+ call printf ("%g\n")
+ call pargr (OPVALR($1))
+ }
+ }
+ | LETTER '=' expr {
+ # Set the value of a register (from a-z).
+ call putreg (OPVALI($1), $3)
+ }
+ ;
+
+expr : '(' expr ')' {
+ YYMOVE ($2, $$)
+ }
+ | expr '+' opnl expr {
+ call binop ($1, $4, $$, '+')
+ }
+ | expr '-' opnl expr {
+ call binop ($1, $4, $$, '-')
+ }
+ | expr '*' opnl expr {
+ call binop ($1, $4, $$, '*')
+ }
+ | expr '/' opnl expr {
+ call binop ($1, $4, $$, '/')
+ }
+ | '-' expr %prec UMINUS {
+ call unop ($2, $$, '-')
+ }
+ | LETTER {
+ call getreg (OPVALI($1), $$)
+ }
+ | CONST
+ ;
+
+eost : ';'
+ | '\n'
+ ;
+
+opnl : # Empty
+ | opnl '\n'
+ ;
+
+%%
+
+
+# DC -- Main routine for the desk calculator.
+
+procedure t_dc()
+
+bool debug
+int status
+bool clgetb()
+int yyparse()
+extern yylex()
+
+begin
+ debug = clgetb ("debug")
+
+ repeat {
+ status = yyparse (STDIN, debug, yylex)
+ if (status == ERR)
+ call eprintf ("syntax error")
+ } until (status == EOF)
+end
+
+
+# BINOP -- Perform an arithmetic binary operation on two operands (passed
+# by pointer), returning the result in a third.
+
+procedure binop (a, b, c, operation)
+
+pointer a, b, c # c = a op b
+int operation # i.e., '+', '-', etc.
+int i, j, k
+real x, y, z
+
+begin
+ if (OPTYPE(a) == TY_INT && OPTYPE(b) == TY_INT) {
+ # Both operands are of type int, so return an integer result.
+
+ i = OPVALI(a)
+ j = OPVALI(b)
+
+ switch (operation) {
+ case '+':
+ k = i + j
+ case '-':
+ k = i - j
+ case '*':
+ k = i * j
+ case '/':
+ k = i / j
+ default:
+ call error (1, "unknown binary operator")
+ }
+ OPVALI(c) = k
+ OPTYPE(c) = TY_INT
+
+ } else {
+ # At least one of the two operands is a real. Perform the
+ # calculation in type real, producing a real result.
+
+ if (OPTYPE(a) == TY_INT)
+ x = OPVALI(a)
+ else
+ x = OPVALR(a)
+ if (OPTYPE(b) == TY_INT)
+ y = OPVALI(b)
+ else
+ y = OPVALR(b)
+
+ switch (operation) {
+ case '+':
+ z = x + y
+ case '-':
+ z = x - y
+ case '*':
+ z = x * y
+ case '/':
+ z = x / y
+ default:
+ call error (1, "unknown binary operator")
+ }
+
+ OPVALR(c) = z
+ OPTYPE(c) = TY_REAL
+ }
+end
+
+
+# UNOP -- Perform a unary operation. Since there is only one operand, the
+# datatype does not change.
+
+procedure unop (a, b, operation)
+
+pointer a, b
+int operation
+
+begin
+ OPTYPE(b) = OPTYPE(a)
+
+ switch (operation) {
+ case '-':
+ switch (OPTYPE(a)) {
+ case TY_INT:
+ OPVALI(b) = -OPVALI(a)
+ case TY_REAL:
+ OPVALR(b) = -OPVALR(a)
+ }
+ default:
+ call error (2, "unknown unary operator")
+ }
+end
+
+
+# GETREG, PUTREG -- Fetch or store the contents of a register variable.
+# Registers are referred to by letter, A-Z or a-z.
+
+define MAXREG ('z'-'a'+1)
+
+
+procedure getreg (regchar, op)
+
+int regchar
+pointer op
+
+bool store
+int regbuf[MAXREG*YYOPLEN]
+int reg, offset
+
+begin
+ store = false
+ goto 10
+
+entry putreg (regchar, op)
+ store = true
+
+ # Compute offset into storage. Structures are stored in buffer
+ # by a binary copy, knowing only the length of the structure.
+10 if (IS_UPPER(regchar))
+ reg = regchar - 'A' + 1
+ else
+ reg = regchar - 'a' + 1
+ reg = max(1, min(MAXREG, reg))
+ offset = (reg-1) * YYOPLEN + 1
+
+ # Copy the operand structure either in or out.
+ if (store)
+ call amovi (Memi[op], regbuf[offset], YYOPLEN)
+ else
+ call amovi (regbuf[offset], Memi[op], YYOPLEN)
+end
+
+
+# YYLEX -- Lexical input routine. Return next token from the input
+# stream. Recognized tokens are CONST (numeric constants), LETTER,
+# and the operator characters.
+
+int procedure yylex (fd, yylval)
+
+int fd
+pointer yylval
+char ch, lbuf[SZ_LINE]
+int ip, nchars, token, junk
+double dval
+int lexnum(), getline(), gctod()
+data ip /0/
+
+begin
+ # Fetch a nonempty input line, or advance to start of next token
+ # if within a line. Newline is a token.
+ repeat {
+ if (ip <= 0 || lbuf[ip] == EOS) {
+ if (getline (fd, lbuf) == EOF) {
+ ip = 0
+ return (YYEOF)
+ } else
+ ip = 1
+ }
+ while (IS_WHITE (lbuf[ip]))
+ ip = ip + 1
+ } until (lbuf[ip] != EOS)
+
+ # Determine type of token. If numeric constant, convert to binary
+ # and return value in op structure (yylval). If letter (register
+ # variable) return value and advance input one char. If any other
+ # character, return char itself as the token, and advance input one
+ # character.
+
+ if (IS_DIGIT (lbuf[ip]))
+ token = lexnum (lbuf, ip, nchars)
+ else
+ token = LEX_NONNUM
+
+ switch (token) {
+ case LEX_OCTAL, LEX_DECIMAL, LEX_HEX:
+ junk = gctod (lbuf, ip, dval)
+ OPTYPE(yylval) = TY_INT
+ OPVALI(yylval) = int (dval)
+ return (CONST)
+
+ case LEX_REAL:
+ junk = gctod (lbuf, ip, dval)
+ OPTYPE(yylval) = TY_REAL
+ OPVALR(yylval) = dval
+ return (CONST)
+
+ default:
+ ch = lbuf[ip]
+ ip = ip + 1
+ if (IS_ALPHA (ch)) {
+ OPTYPE(yylval) = LETTER
+ OPVALI(yylval) = ch
+ return (LETTER)
+ } else {
+ OPTYPE(yylval) = ch
+ return (OPTYPE(yylval))
+ }
+ }
+end
diff --git a/unix/boot/xyacc/debug/y.output b/unix/boot/xyacc/debug/y.output
new file mode 100644
index 00000000..5640244f
--- /dev/null
+++ b/unix/boot/xyacc/debug/y.output
@@ -0,0 +1,331 @@
+
+state 0
+ $accept : _prog $end
+ prog : _ (1)
+
+ YYEOF shift 2
+ . reduce 1
+
+ prog goto 1
+
+state 1
+ $accept : prog_$end
+ prog : prog_stmt eost
+ prog : prog_error \n
+
+ $end accept
+ error shift 4
+ CONST shift 9
+ LETTER shift 6
+ - shift 8
+ ( shift 7
+ . error
+
+ stmt goto 3
+ expr goto 5
+
+state 2
+ prog : YYEOF_ (3)
+
+ . reduce 3
+
+
+state 3
+ prog : prog stmt_eost
+
+ \n shift 12
+ ; shift 11
+ . error
+
+ eost goto 10
+
+state 4
+ prog : prog error_\n
+
+ \n shift 13
+ . error
+
+
+state 5
+ stmt : expr_ (5)
+ expr : expr_+ opnl expr
+ expr : expr_- opnl expr
+ expr : expr_* opnl expr
+ expr : expr_/ opnl expr
+
+ + shift 14
+ - shift 15
+ * shift 16
+ / shift 17
+ . reduce 5
+
+
+state 6
+ stmt : LETTER_= expr
+ expr : LETTER_ (13)
+
+ = shift 18
+ . reduce 13
+
+
+state 7
+ expr : (_expr )
+
+ CONST shift 9
+ LETTER shift 20
+ - shift 8
+ ( shift 7
+ . error
+
+ expr goto 19
+
+state 8
+ expr : -_expr
+
+ CONST shift 9
+ LETTER shift 20
+ - shift 8
+ ( shift 7
+ . error
+
+ expr goto 21
+
+state 9
+ expr : CONST_ (14)
+
+ . reduce 14
+
+
+state 10
+ prog : prog stmt eost_ (2)
+
+ . reduce 2
+
+
+state 11
+ eost : ;_ (15)
+
+ . reduce 15
+
+
+state 12
+ eost : \n_ (16)
+
+ . reduce 16
+
+
+state 13
+ prog : prog error \n_ (4)
+
+ . reduce 4
+
+
+state 14
+ expr : expr +_opnl expr
+ opnl : _ (17)
+
+ . reduce 17
+
+ opnl goto 22
+
+state 15
+ expr : expr -_opnl expr
+ opnl : _ (17)
+
+ . reduce 17
+
+ opnl goto 23
+
+state 16
+ expr : expr *_opnl expr
+ opnl : _ (17)
+
+ . reduce 17
+
+ opnl goto 24
+
+state 17
+ expr : expr /_opnl expr
+ opnl : _ (17)
+
+ . reduce 17
+
+ opnl goto 25
+
+state 18
+ stmt : LETTER =_expr
+
+ CONST shift 9
+ LETTER shift 20
+ - shift 8
+ ( shift 7
+ . error
+
+ expr goto 26
+
+state 19
+ expr : ( expr_)
+ expr : expr_+ opnl expr
+ expr : expr_- opnl expr
+ expr : expr_* opnl expr
+ expr : expr_/ opnl expr
+
+ + shift 14
+ - shift 15
+ * shift 16
+ / shift 17
+ ) shift 27
+ . error
+
+
+state 20
+ expr : LETTER_ (13)
+
+ . reduce 13
+
+
+state 21
+ expr : expr_+ opnl expr
+ expr : expr_- opnl expr
+ expr : expr_* opnl expr
+ expr : expr_/ opnl expr
+ expr : - expr_ (12)
+
+ . reduce 12
+
+
+state 22
+ expr : expr + opnl_expr
+ opnl : opnl_\n
+
+ CONST shift 9
+ LETTER shift 20
+ - shift 8
+ \n shift 29
+ ( shift 7
+ . error
+
+ expr goto 28
+
+state 23
+ expr : expr - opnl_expr
+ opnl : opnl_\n
+
+ CONST shift 9
+ LETTER shift 20
+ - shift 8
+ \n shift 29
+ ( shift 7
+ . error
+
+ expr goto 30
+
+state 24
+ expr : expr * opnl_expr
+ opnl : opnl_\n
+
+ CONST shift 9
+ LETTER shift 20
+ - shift 8
+ \n shift 29
+ ( shift 7
+ . error
+
+ expr goto 31
+
+state 25
+ expr : expr / opnl_expr
+ opnl : opnl_\n
+
+ CONST shift 9
+ LETTER shift 20
+ - shift 8
+ \n shift 29
+ ( shift 7
+ . error
+
+ expr goto 32
+
+state 26
+ stmt : LETTER = expr_ (6)
+ expr : expr_+ opnl expr
+ expr : expr_- opnl expr
+ expr : expr_* opnl expr
+ expr : expr_/ opnl expr
+
+ + shift 14
+ - shift 15
+ * shift 16
+ / shift 17
+ . reduce 6
+
+
+state 27
+ expr : ( expr )_ (7)
+
+ . reduce 7
+
+
+state 28
+ expr : expr_+ opnl expr
+ expr : expr + opnl expr_ (8)
+ expr : expr_- opnl expr
+ expr : expr_* opnl expr
+ expr : expr_/ opnl expr
+
+ * shift 16
+ / shift 17
+ . reduce 8
+
+
+state 29
+ opnl : opnl \n_ (18)
+
+ . reduce 18
+
+
+state 30
+ expr : expr_+ opnl expr
+ expr : expr_- opnl expr
+ expr : expr - opnl expr_ (9)
+ expr : expr_* opnl expr
+ expr : expr_/ opnl expr
+
+ * shift 16
+ / shift 17
+ . reduce 9
+
+
+state 31
+ expr : expr_+ opnl expr
+ expr : expr_- opnl expr
+ expr : expr_* opnl expr
+ expr : expr * opnl expr_ (10)
+ expr : expr_/ opnl expr
+
+ . reduce 10
+
+
+state 32
+ expr : expr_+ opnl expr
+ expr : expr_- opnl expr
+ expr : expr_* opnl expr
+ expr : expr_/ opnl expr
+ expr : expr / opnl expr_ (11)
+
+ . reduce 11
+
+
+15/127 terminals, 5/300 nonterminals
+19/600 grammar rules, 33/750 states
+0 shift/reduce, 0 reduce/reduce conflicts reported
+13/350 working sets used
+memory: states,etc. 226/12000, parser 14/12000
+11/600 distinct lookahead sets
+5 extra closures
+59 shift entries, 1 exceptions
+15 goto entries
+0 entries saved by goto default
+Optimizer space used: input 145/12000, output 249/12000
+249 table entries, 204 zero
+maximum spread: 259, maximum offset: 259
diff --git a/unix/boot/xyacc/debug/ytab.x b/unix/boot/xyacc/debug/ytab.x
new file mode 100644
index 00000000..5a453b52
--- /dev/null
+++ b/unix/boot/xyacc/debug/ytab.x
@@ -0,0 +1,645 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <ctype.h>
+include <lexnum.h>
+
+define YYMAXDEPTH 150 # length of parser stack
+
+task dc = t_dc
+
+# Operand Structure (parser stack)
+define YYOPLEN 2 # size of operand structure
+define OPTYPE Memi[$1] # operand datatype
+define OPVALI Memi[$1+1] # integer value of operand
+define OPVALR Memr[$1+1] # real value of operand
+
+define CONST 257
+define LETTER 258
+define YYEOF 259
+define UMINUS 260
+define yyclearin yychar = -1
+define yyerrok yyerrflag = 0
+define YYMOVE call amovi (Memi[$1], Memi[$2], YYOPLEN)
+define YYERRCODE 256
+
+# line 89 "dc.y"
+
+
+
+# DC -- Main routine for the desk calculator.
+
+procedure t_dc()
+
+bool debug
+int status
+bool clgetb()
+int yyparse()
+extern yylex()
+
+begin
+ debug = clgetb ("debug")
+
+ repeat {
+ status = yyparse (STDIN, debug, yylex)
+ if (status == ERR)
+ call eprintf ("syntax error")
+ } until (status == EOF)
+end
+
+
+# BINOP -- Perform an arithmetic binary operation on two operands (passed
+# by pointer), returning the result in a third.
+
+procedure binop (a, b, c, opchar)
+
+pointer a, b, c # c = a op b
+char opchar # i.e., '+', '-', etc.
+int i, j, k
+real x, y, z
+
+begin
+ if (OPTYPE(a) == TY_INT && OPTYPE(b) == TY_INT) {
+ # Both operands are of type int, so return an integer result.
+
+ i = OPVALI(a)
+ j = OPVALI(b)
+
+ switch (opchar) {
+ case '+':
+ k = i + j
+ case '-':
+ k = i - j
+ case '*':
+ k = i * j
+ case '/':
+ k = i / j
+ default:
+ call error (1, "unknown binary operator")
+ }
+ OPVALI(c) = k
+ OPTYPE(c) = TY_INT
+
+ } else {
+ # At least one of the two operands is a real. Perform the
+ # calculation in type real, producing a real result.
+
+ if (OPTYPE(a) == TY_INT)
+ x = OPVALI(a)
+ else
+ x = OPVALR(a)
+ if (OPTYPE(b) == TY_INT)
+ y = OPVALI(b)
+ else
+ y = OPVALR(b)
+
+ switch (opchar) {
+ case '+':
+ z = x + y
+ case '-':
+ z = x - y
+ case '*':
+ z = x * y
+ case '/':
+ z = x / y
+ default:
+ call error (1, "unknown binary operator")
+ }
+
+ OPVALR(c) = z
+ OPTYPE(c) = TY_REAL
+ }
+end
+
+
+# UNOP -- Perform a unary operation. Since there is only one operand, the
+# datatype does not change.
+
+procedure unop (a, b, opchar)
+
+pointer a, b
+char opchar
+
+begin
+ OPTYPE(b) = OPTYPE(a)
+
+ switch (opchar) {
+ case '-':
+ switch (OPTYPE(a)) {
+ case TY_INT:
+ OPVALI(b) = -OPVALI(a)
+ case TY_REAL:
+ OPVALR(b) = -OPVALR(a)
+ }
+ default:
+ call error (2, "unknown unary operator")
+ }
+end
+
+
+# GETREG, PUTREG -- Fetch or store the contents of a register variable.
+# Registers are referred to by letter, A-Z or a-z.
+
+define MAXREG ('z'-'a'+1)
+
+
+procedure getreg (regchar, op)
+
+char regchar
+pointer op
+
+bool store
+int regbuf[MAXREG*YYOPLEN]
+int reg, offset
+
+begin
+ store = false
+ goto 10
+
+entry putreg (regchar, op)
+ store = true
+
+ # Compute offset into storage. Structures are stored in buffer
+ # by a binary copy, knowing only the length of the structure.
+10 if (IS_UPPER(regchar))
+ reg = regchar - 'A' + 1
+ else
+ reg = regchar - 'a' + 1
+ reg = max(1, min(MAXREG, reg))
+ offset = (reg-1) * YYOPLEN + 1
+
+ # Copy the operand structure either in or out.
+ if (store)
+ call amovi (Memi[op], regbuf[offset], YYOPLEN)
+ else
+ call amovi (regbuf[offset], Memi[op], YYOPLEN)
+end
+
+
+# YYLEX -- Lexical input routine. Return next token from the input
+# stream. Recognized tokens are CONST (numeric constants), LETTER,
+# and the operator characters.
+
+int procedure yylex (fd, yylval)
+
+int fd
+pointer yylval
+char ch, lbuf[SZ_LINE]
+int ip, nchars, token, junk
+double dval
+int lexnum(), getline(), gctod()
+data ip /0/
+
+begin
+ # Fetch a nonempty input line, or advance to start of next token
+ # if within a line. Newline is a token.
+ repeat {
+ if (ip <= 0 || lbuf[ip] == EOS) {
+ if (getline (fd, lbuf) == EOF) {
+ ip = 0
+ return (YYEOF)
+ } else
+ ip = 1
+ }
+ while (IS_WHITE (lbuf[ip]))
+ ip = ip + 1
+ } until (lbuf[ip] != EOS)
+
+ # Determine type of token. If numeric constant, convert to binary
+ # and return value in op structure (yylval). If letter (register
+ # variable) return value and advance input one char. If any other
+ # character, return char itself as the token, and advance input one
+ # character.
+
+ if (IS_DIGIT (lbuf[ip]))
+ token = lexnum (lbuf, ip, nchars)
+ else
+ token = LEX_NONNUM
+
+ switch (token) {
+ case LEX_OCTAL, LEX_DECIMAL, LEX_HEX:
+ junk = gctod (lbuf, ip, dval)
+ OPTYPE(yylval) = TY_INT
+ OPVALI(yylval) = int (dval)
+ return (CONST)
+
+ case LEX_REAL:
+ junk = gctod (lbuf, ip, dval)
+ OPTYPE(yylval) = TY_REAL
+ OPVALR(yylval) = dval
+ return (CONST)
+
+ default:
+ ch = lbuf[ip]
+ ip = ip + 1
+ if (IS_ALPHA (ch)) {
+ OPTYPE(yylval) = LETTER
+ OPVALI(yylval) = ch
+ return (LETTER)
+ } else {
+ OPTYPE(yylval) = ch
+ return (OPTYPE(yylval))
+ }
+ }
+end
+define YYNPROD 19
+define YYLAST 249
+
+# Parser for yacc output, translated to the IRAF SPP language. The contents
+# of this file form the bulk of the source of the parser produced by Yacc.
+# Yacc recognizes several macros in the yaccpar input source and replaces
+# them as follows:
+# A user suppled "global" definitions and declarations
+# B parser tables
+# C user supplied actions (reductions)
+# The remainder of the yaccpar code is not changed.
+
+define yystack_ 10 # statement labels for gotos
+define yynewstate_ 20
+define yydefault_ 30
+define yyerrlab_ 40
+define yyabort_ 50
+
+define YYFLAG (-1000) # defs used in user actions
+define YYERROR goto yyerrlab_
+define YYACCEPT return (OK)
+define YYABORT return (ERR)
+
+
+# YYPARSE -- Parse the input stream, returning OK if the source is
+# syntactically acceptable (i.e., if compilation is successful),
+# otherwise ERR. The parameters YYMAXDEPTH and YYOPLEN must be
+# supplied by the caller in the %{ ... %} section of the Yacc source.
+# The token value stack is a dynamically allocated array of operand
+# structures, with the length and makeup of the operand structure being
+# application dependent.
+
+int procedure yyparse (fd, yydebug, yylex)
+
+int fd # stream to be parsed
+bool yydebug # print debugging information?
+int yylex() # user-supplied lexical input function
+extern yylex()
+
+short yys[YYMAXDEPTH] # parser stack -- stacks tokens
+pointer yyv # pointer to token value stack
+pointer yyval # value returned by action
+pointer yylval # value of token
+int yyps # token stack pointer
+pointer yypv # value stack pointer
+int yychar # current input token number
+int yyerrflag # error recovery flag
+int yynerrs # number of errors
+
+short yyj, yym # internal variables
+pointer sp, yypvt
+short yystate, yyn
+int yyxi
+
+int toksp # declarations for status entry points
+int uups, uuchar
+pointer valsp, uuop, uupv, uuval, uulval
+int yygtok(), yygval(), yystat()
+errchk salloc, yylex
+
+short yyexca[6]
+data (yyexca(i),i= 1, 6) / -1, 1, 0, -1, -2, 0/
+short yyact[249]
+data (yyact(i),i= 1, 8) / 29, 7, 2, 7, 18, 12, 8, 16/
+data (yyact(i),i= 9, 16) / 8, 27, 16, 14, 17, 15, 5, 17/
+data (yyact(i),i= 17, 24) / 16, 14, 13, 15, 10, 17, 19, 21/
+data (yyact(i),i= 25, 32) / 3, 22, 1, 0, 0, 0, 7, 0/
+data (yyact(i),i= 33, 40) / 0, 26, 0, 8, 0, 28, 30, 31/
+data (yyact(i),i= 41, 48) / 32, 23, 24, 25, 0, 0, 0, 0/
+data (yyact(i),i= 49, 56) / 0, 0, 0, 0, 0, 0, 11, 0/
+data (yyact(i),i= 57, 64) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i= 65, 72) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i= 73, 80) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i= 81, 88) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i= 89, 96) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i= 97,104) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=105,112) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=113,120) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=121,128) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=129,136) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=137,144) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=145,152) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=153,160) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=161,168) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=169,176) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=177,184) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=185,192) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=193,200) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=201,208) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=209,216) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=217,224) / 0, 4, 9, 6, 9, 20, 0, 0/
+data (yyact(i),i=225,232) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=233,240) / 0, 0, 0, 0, 0, 0, 0, 0/
+data (yyact(i),i=241,248) / 0, 0, 0, 0, 0, 0, 0, 9/
+data (yyact(i),i=249,249) / 20/
+short yypact[33]
+data (yypact(i),i= 1, 8) /-257, -39,-1000, -5, 8, -26, -57, -37/
+data (yypact(i),i= 9, 16) / -37,-1000,-1000,-1000,-1000,-1000,-1000,-1000/
+data (yypact(i),i= 17, 24) /-1000,-1000, -37, -32,-1000,-1000, -10, -10/
+data (yypact(i),i= 25, 32) / -10, -10, -26,-1000, -35,-1000, -35,-1000/
+data (yypact(i),i= 33, 33) /-1000/
+short yypgo[6]
+data (yypgo(i),i= 1, 6) / 0, 26, 24, 20, 14, 25/
+short yyr1[19]
+data (yyr1(i),i= 1, 8) / 0, 1, 1, 1, 1, 2, 2, 4/
+data (yyr1(i),i= 9, 16) / 4, 4, 4, 4, 4, 4, 4, 3/
+data (yyr1(i),i= 17, 19) / 3, 5, 5/
+short yyr2[19]
+data (yyr2(i),i= 1, 8) / 0, 0, 3, 1, 3, 1, 3, 3/
+data (yyr2(i),i= 9, 16) / 4, 4, 4, 4, 2, 1, 1, 1/
+data (yyr2(i),i= 17, 19) / 1, 0, 2/
+short yychk[33]
+data (yychk(i),i= 1, 8) /-1000, -1, 259, -2, 256, -4, 258, 40/
+data (yychk(i),i= 9, 16) / 45, 257, -3, 59, 10, 10, 43, 45/
+data (yychk(i),i= 17, 24) / 42, 47, 61, -4, 258, -4, -5, -5/
+data (yychk(i),i= 25, 32) / -5, -5, -4, 41, -4, 10, -4, -4/
+data (yychk(i),i= 33, 33) / -4/
+short yydef[33]
+data (yydef(i),i= 1, 8) / 1, -2, 3, 0, 0, 5, 13, 0/
+data (yydef(i),i= 9, 16) / 0, 14, 2, 15, 16, 4, 17, 17/
+data (yydef(i),i= 17, 24) / 17, 17, 0, 0, 13, 12, 0, 0/
+data (yydef(i),i= 25, 32) / 0, 0, 6, 7, 8, 18, 9, 10/
+data (yydef(i),i= 33, 33) / 11/
+
+begin
+ call smark (sp)
+ call salloc (yyv, (YYMAXDEPTH+2) * YYOPLEN, TY_STRUCT)
+
+ # Initialization. The first element of the dynamically allocated
+ # token value stack (yyv) is used for yyval, the second for yylval,
+ # and the actual stack starts with the third element.
+
+ yystate = 0
+ yychar = -1
+ yynerrs = 0
+ yyerrflag = 0
+ yyps = 0
+ yyval = yyv
+ yylval = yyv + YYOPLEN
+ yypv = yylval
+
+yystack_
+ # SHIFT -- Put a state and value onto the stack. The token and
+ # value stacks are logically the same stack, implemented as two
+ # separate arrays.
+
+ if (yydebug) {
+ call printf ("state %d, char 0%o\n")
+ call pargs (yystate)
+ call pargi (yychar)
+ }
+ yyps = yyps + 1
+ yypv = yypv + YYOPLEN
+ if (yyps > YYMAXDEPTH) {
+ call sfree (sp)
+ call eprintf ("yacc stack overflow\n")
+ return (ERR)
+ }
+ yys[yyps] = yystate
+ YYMOVE (yyval, yypv)
+
+yynewstate_
+ # Process the new state.
+ yyn = yypact[yystate+1]
+
+ if (yyn <= YYFLAG)
+ goto yydefault_ # simple state
+
+ # The variable "yychar" is the lookahead token.
+ if (yychar < 0) {
+ yychar = yylex (fd, yylval)
+ if (yychar < 0)
+ yychar = 0
+ }
+ yyn = yyn + yychar
+ if (yyn < 0 || yyn >= YYLAST)
+ goto yydefault_
+
+ yyn = yyact[yyn+1]
+ if (yychk[yyn+1] == yychar) { # valid shift
+ yychar = -1
+ YYMOVE (yylval, yyval)
+ yystate = yyn
+ if (yyerrflag > 0)
+ yyerrflag = yyerrflag - 1
+ goto yystack_
+ }
+
+yydefault_
+ # Default state action.
+
+ yyn = yydef[yystate+1]
+ if (yyn == -2) {
+ if (yychar < 0) {
+ yychar = yylex (fd, yylval)
+ if (yychar < 0)
+ yychar = 0
+ }
+
+ # Look through exception table.
+ yyxi = 1
+ while ((yyexca[yyxi] != (-1)) || (yyexca[yyxi+1] != yystate))
+ yyxi = yyxi + 2
+ for (yyxi=yyxi+2; yyexca[yyxi] >= 0; yyxi=yyxi+2) {
+ if (yyexca[yyxi] == yychar)
+ break
+ }
+
+ yyn = yyexca[yyxi+1]
+ if (yyn < 0) {
+ call sfree (sp)
+ return (OK) # ACCEPT -- all done
+ }
+ }
+
+
+ # SYNTAX ERROR -- resume parsing if possible.
+
+ if (yyn == 0) {
+ switch (yyerrflag) {
+ case 0, 1, 2:
+ if (yyerrflag == 0) { # brand new error
+ call eprintf ("syntax error\n")
+yyerrlab_
+ yynerrs = yynerrs + 1
+ # fall through...
+ }
+
+ # case 1:
+ # case 2: incompletely recovered error ... try again
+ yyerrflag = 3
+
+ # Find a state where "error" is a legal shift action.
+ while (yyps >= 1) {
+ yyn = yypact[yys[yyps]+1] + YYERRCODE
+ if ((yyn >= 0) && (yyn < YYLAST) &&
+ (yychk[yyact[yyn+1]+1] == YYERRCODE)) {
+ # Simulate a shift of "error".
+ yystate = yyact[yyn+1]
+ goto yystack_
+ }
+ yyn = yypact[yys[yyps]+1]
+
+ # The current yyps has no shift on "error", pop stack.
+ if (yydebug) {
+ call printf ("error recovery pops state %d, ")
+ call pargs (yys[yyps])
+ call printf ("uncovers %d\n")
+ call pargs (yys[yyps-1])
+ }
+ yyps = yyps - 1
+ yypv = yypv - YYOPLEN
+ }
+
+ # ABORT -- There is no state on the stack with an error shift.
+yyabort_
+ call sfree (sp)
+ return (ERR)
+
+
+ case 3: # No shift yet; clobber input char.
+
+ if (yydebug) {
+ call printf ("error recovery discards char %d\n")
+ call pargi (yychar)
+ }
+
+ if (yychar == 0)
+ goto yyabort_ # don't discard EOF, quit
+ yychar = -1
+ goto yynewstate_ # try again in the same state
+ }
+ }
+
+
+ # REDUCE -- Reduction by production yyn.
+
+ if (yydebug) {
+ call printf ("reduce %d\n")
+ call pargs (yyn)
+ }
+ yyps = yyps - yyr2[yyn+1]
+ yypvt = yypv
+ yypv = yypv - yyr2[yyn+1] * YYOPLEN
+ YYMOVE (yypv + YYOPLEN, yyval)
+ yym = yyn
+
+ # Consult goto table to find next state.
+ yyn = yyr1[yyn+1]
+ yyj = yypgo[yyn+1] + yys[yyps] + 1
+ if (yyj >= YYLAST)
+ yystate = yyact[yypgo[yyn+1]+1]
+ else {
+ yystate = yyact[yyj+1]
+ if (yychk[yystate+1] != -yyn)
+ yystate = yyact[yypgo[yyn+1]+1]
+ }
+
+ # Perform action associated with the grammar rule, if any.
+ switch (yym) {
+
+case 2:
+# line 30 "dc.y"
+{
+ return (OK)
+ }
+case 3:
+# line 33 "dc.y"
+{
+ return (EOF)
+ }
+case 4:
+# line 36 "dc.y"
+{
+ yyerrok
+ }
+case 5:
+# line 41 "dc.y"
+{
+ # Print the value of an expression.
+ if (OPTYPE(yypvt) == TY_INT) {
+ call printf ("%d\n")
+ call pargi (OPVALI(yypvt))
+ } else {
+ call printf ("%g\n")
+ call pargr (OPVALR(yypvt))
+ }
+ }
+case 6:
+# line 51 "dc.y"
+{
+ # Set the value of a register (from a-z).
+ call putreg (char(OPVALI(yypvt-2*YYOPLEN)), yypvt)
+ }
+case 7:
+# line 57 "dc.y"
+{
+ YYMOVE (yypvt-YYOPLEN, yyval)
+ }
+case 8:
+# line 60 "dc.y"
+{
+ call binop (yypvt-3*YYOPLEN, yypvt, yyval, '+')
+ }
+case 9:
+# line 63 "dc.y"
+{
+ call binop (yypvt-3*YYOPLEN, yypvt, yyval, '-')
+ }
+case 10:
+# line 66 "dc.y"
+{
+ call binop (yypvt-3*YYOPLEN, yypvt, yyval, '*')
+ }
+case 11:
+# line 69 "dc.y"
+{
+ call binop (yypvt-3*YYOPLEN, yypvt, yyval, '/')
+ }
+case 12:
+# line 72 "dc.y"
+{
+ call unop (yypvt, yyval, '-')
+ }
+case 13:
+# line 75 "dc.y"
+{
+ call getreg (char(OPVALI(yypvt)), yyval)
+ } }
+
+ goto yystack_ # stack new state and value
+
+
+# The following entry points are provided so that lexical routines
+# and actions may get information of the parser status, i.e., how
+# deep is the stack, what tokens are currently stacked, and so on.
+# Conceivably there could be reentrancy problems here...
+
+ # YYGTOK -- Read an element from the token stack.
+entry yygtok (toksp)
+ return (yys[toksp])
+
+ # YYGVAL -- Read an element from the value stack.
+entry yygval (valsp, uuop)
+ YYMOVE (valsp, uuop)
+ return (OPTYPE(uuop))
+
+ # YYSTAT -- Return parser state variables. The code for the token
+ # currently on top of the stack is returned as the function value.
+
+entry yystat (uups, uupv, uuchar, uuval, uulval)
+ uups = yyps
+ uupv = yypv
+ uuchar = yychar
+ YYMOVE (yyval, uuval)
+ YYMOVE (yylval, uulval)
+
+ if (yyps <= 0)
+ return (0)
+ else
+ return (yys[yyps])
+end
diff --git a/unix/boot/xyacc/dextern.h b/unix/boot/xyacc/dextern.h
new file mode 100644
index 00000000..e735003d
--- /dev/null
+++ b/unix/boot/xyacc/dextern.h
@@ -0,0 +1,382 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+#ifndef _DEXTERN_H
+#define _DEXTERN_H
+
+//#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <memory.h>
+#include <string.h>
+#ifdef LINUX
+#include <malloc.h>
+#include <values.h>
+#else
+#include <malloc/malloc.h>
+#endif
+#include <unistd.h>
+#include <stdlib.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* MANIFEST CONSTANT DEFINITIONS */
+#if u3b || u3b15 || u3b2 || vax || uts || sparc
+#define WORD32
+#endif
+#ifdef LINUX
+#include <libintl.h>
+#endif
+
+ /* base of nonterminal internal numbers */
+
+#define NTBASE 010000
+
+ /* internal codes for error and accept actions */
+
+#define ERRCODE 8190
+#define ACCEPTCODE 8191
+
+ /* sizes and limits */
+
+#define ACTSIZE 12000
+#define MEMSIZE 12000
+#define NSTATES 750
+#define PSTSIZE 1024
+#define NTERMS 127
+#define NPROD 600
+#define NNONTERM 300
+#define TEMPSIZE 1200
+#define CNAMSZ 5000
+#define LSETSIZE 600
+#define WSETSIZE 350
+
+#define NAMESIZE 50
+#define NTYPES 63
+
+#define NMBCHARSZ 100
+#define LKFACTOR 16
+
+#define WORD32
+#ifdef WORD32
+
+ /* bit packing macros (may be machine dependent) */
+#define BIT(a, i) ((a)[(i)>>5] & (1<<((i)&037)))
+#define SETBIT(a, i) ((a)[(i)>>5] |= (1<<((i)&037)))
+
+ /* number of words needed to hold n+1 bits */
+#define NWORDS(n) (((n)+32)/32)
+
+#else
+
+ /* bit packing macros (may be machine dependent) */
+#define BIT(a, i) ((a)[(i)>>4] & (1<<((i)&017)))
+#define SETBIT(a, i) ((a)[(i)>>4] |= (1<<((i)&017)))
+
+ /* number of words needed to hold n+1 bits */
+#define NWORDS(n) (((n)+16)/16)
+#endif
+
+ /*
+ * relationships which must hold:
+ * TBITSET ints must hold NTERMS+1 bits...
+ * WSETSIZE >= NNONTERM
+ * LSETSIZE >= NNONTERM
+ * TEMPSIZE >= NTERMS + NNONTERMs + 1
+ * TEMPSIZE >= NSTATES
+ */
+
+ /* associativities */
+
+#define NOASC 0 /* no assoc. */
+#define LASC 1 /* left assoc. */
+#define RASC 2 /* right assoc. */
+#define BASC 3 /* binary assoc. */
+
+ /* flags for state generation */
+
+#define DONE 0
+#define MUSTDO 1
+#define MUSTLOOKAHEAD 2
+
+ /* flags for a rule having an action, and being reduced */
+
+#define ACTFLAG 04
+#define REDFLAG 010
+
+ /* output parser flags */
+#define YYFLAG1 (-1000)
+
+ /* macros for getting associativity and precedence levels */
+
+#define ASSOC(i) ((i)&07)
+#define PLEVEL(i) (((i)>>4)&077)
+#define TYPE(i) ((i>>10)&077)
+
+ /* macros for setting associativity and precedence levels */
+
+#define SETASC(i, j) i |= j
+#define SETPLEV(i, j) i |= (j<<4)
+#define SETTYPE(i, j) i |= (j<<10)
+
+ /* looping macros */
+
+#define TLOOP(i) for (i = 1; i <= ntokens; ++i)
+#define NTLOOP(i) for (i = 0; i <= nnonter; ++i)
+#define PLOOP(s, i) for (i = s; i < nprod; ++i)
+#define SLOOP(i) for (i = 0; i < nstate; ++i)
+#define WSBUMP(x) ++x
+#define WSLOOP(s, j) for (j = s; j < &wsets[cwp]; ++j)
+#define ITMLOOP(i, p, q) q = pstate[i+1]; for (p = pstate[i]; p < q; ++p)
+#define SETLOOP(i) for (i = 0; i < tbitset; ++i)
+
+ /* I/O descriptors */
+
+extern FILE *finput; /* input file */
+extern FILE *faction; /* file for saving actions */
+extern FILE *fdefine; /* file for #defines */
+extern FILE *ftable; /* y.tab.c file */
+extern FILE *ftemp; /* tempfile to pass 2 */
+extern FILE *fdebug; /* tempfile for two debugging info arrays */
+extern FILE *foutput; /* y.output file */
+extern FILE *fsppout; /* ytab.x file */
+
+ /* structure declarations */
+
+typedef struct looksets {
+ int *lset;
+} LOOKSETS;
+
+typedef struct item {
+ int *pitem;
+ LOOKSETS *look;
+} ITEM;
+
+typedef struct toksymb {
+ char *name;
+ int value;
+} TOKSYMB;
+
+typedef struct mbclit {
+ char character;
+ int tvalue; /* token issued for the character */
+} MBCLIT;
+
+typedef struct ntsymb {
+ char *name;
+ int tvalue;
+} NTSYMB;
+
+typedef struct wset {
+ int *pitem;
+ int flag;
+ LOOKSETS ws;
+} WSET;
+
+ /* token information */
+
+extern int ntokens; /* number of tokens */
+extern TOKSYMB *tokset;
+extern int ntoksz;
+
+ /*
+ * multibyte (c > 255) character literals are
+ * handled as though they were tokens except
+ * that it generates a separate mapping table.
+ */
+extern int nmbchars; /* number of mb literals */
+extern MBCLIT *mbchars;
+extern int nmbcharsz;
+
+ /* nonterminal information */
+
+extern int nnonter; /* the number of nonterminals */
+extern NTSYMB *nontrst;
+extern int nnontersz;
+
+ /* grammar rule information */
+
+extern int nprod; /* number of productions */
+extern int **prdptr; /* pointers to descriptions of productions */
+extern int *levprd; /* contains production levels to break conflicts */
+extern char *had_act; /* set if reduction has associated action code */
+
+ /* state information */
+
+extern int nstate; /* number of states */
+extern ITEM **pstate; /* pointers to the descriptions of the states */
+extern int *tystate; /* contains type information about the states */
+extern int *defact; /* the default action of the state */
+
+extern int size;
+
+ /* lookahead set information */
+
+extern int TBITSET;
+extern LOOKSETS *lkst;
+extern int nolook; /* flag to turn off lookahead computations */
+
+ /* working set information */
+
+extern WSET *wsets;
+
+ /* storage for productions */
+
+extern int *mem0;
+extern int *mem;
+extern int *tracemem;
+extern int new_memsize;
+
+ /* storage for action table */
+
+extern int *amem;
+extern int *memp; /* next free action table position */
+extern int *indgo; /* index to the stored goto table */
+extern int new_actsize;
+
+ /* temporary vector, indexable by states, terms, or ntokens */
+
+extern int *temp1;
+extern int lineno; /* current line number */
+
+ /* statistics collection variables */
+
+extern int zzgoent;
+extern int zzgobest;
+extern int zzacent;
+extern int zzexcp;
+extern int zzrrconf;
+extern int zzsrconf;
+
+ /* define external functions */
+
+extern void setup(int, char *[]);
+extern void closure(int);
+extern void output(void);
+extern void aryfil(int *, int, int);
+extern void error(char *, ...);
+extern void warning(int, char *, ...);
+extern void putitem(int *, LOOKSETS *);
+extern void go2out(void);
+extern void hideprod(void);
+extern void callopt(void);
+extern void warray(char *, int *, int);
+extern char *symnam(int);
+extern char *writem(int *);
+extern void exp_mem(int);
+extern void exp_act(int **);
+extern int apack(int *, int);
+extern int state(int);
+extern void fprintf3(FILE *, const char *, const char *, const char *, ...);
+extern void error3(const char *, const char *, const char *, ...);
+
+extern char *wscpy(char *, const char *);
+extern size_t wslen(const char *);
+extern int wscmp(const char *, const char *);
+
+
+ /* yaccpar location */
+
+extern char *parser;
+
+ /* default settings for a number of macros */
+
+ /* name of yacc tempfiles */
+
+#ifndef TEMPNAME
+#define TEMPNAME "yacc.tmp"
+#endif
+
+#ifndef ACTNAME
+#define ACTNAME "yacc.acts"
+#endif
+
+#ifndef DEBUGNAME
+#define DEBUGNAME "yacc.debug"
+#endif
+
+#ifndef OFILE /* output file name */
+#define OFILE "ytab.x"
+#endif
+
+#ifndef TABFILE /* parser tables file name */
+#define TABFILE "yacc.tab"
+#endif
+
+#ifndef UDFILE /* user global declarations file name */
+#define UDFILE "yacc.udecl"
+#endif
+
+#ifndef FILEU /* user output file name */
+#define FILEU "y.output"
+#endif
+
+#ifndef FILED /* output file for # defines */
+#define FILED "ytab.h"
+#endif
+
+ /* command to clobber tempfiles after use */
+
+#ifndef ZAPFILE
+#define ZAPFILE(x) (void)unlink(x)
+#endif
+
+#ifndef PARSER
+#define PARSER "/iraf/iraf/lib/yaccpar.x"
+#endif
+
+
+
+/*
+ * Lint is unable to properly handle formats with wide strings
+ * (e.g. %ws) and misdiagnoses them as being malformed.
+ * This macro is used to work around that, by substituting
+ * a pointer to a null string when compiled by lint. This
+ * trick works because lint is not able to evaluate the
+ * variable.
+ *
+ * When lint is able to handle %ws, it would be appropriate
+ * to come back through and remove the use of this macro.
+ */
+#if defined(__lint)
+static const char *lint_ws_fmt = "";
+#define WSFMT(_fmt) lint_ws_fmt
+#else
+#define WSFMT(_fmt) _fmt
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DEXTERN_H */
diff --git a/unix/boot/xyacc/mkpkg.sh b/unix/boot/xyacc/mkpkg.sh
new file mode 100644
index 00000000..205d8f5d
--- /dev/null
+++ b/unix/boot/xyacc/mkpkg.sh
@@ -0,0 +1,7 @@
+# XYACC -- Yacc parser generator for SPP.
+
+$CC -c $HSI_CF y[1-4].c
+$CC $HSI_LF y[1-4].o -o xyacc.e
+mv -f xyacc.e ../../hlib
+cp yaccpar.x ../../../lib
+rm -f *.o
diff --git a/unix/boot/xyacc/y1.c b/unix/boot/xyacc/y1.c
new file mode 100644
index 00000000..58f2f945
--- /dev/null
+++ b/unix/boot/xyacc/y1.c
@@ -0,0 +1,1307 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+//#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "dextern.h"
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <unistd.h>
+#include <locale.h>
+#include <stdarg.h> /* For error() */
+
+static void mktbls (void);
+static void others (void);
+static void summary (void);
+static char *chcopy (char *, char *);
+static int setunion (int *, int *);
+static void prlook (LOOKSETS *);
+static void cpres (void);
+static void cpfir (void);
+static void cempty (void);
+static void stagen (void);
+static LOOKSETS *flset (LOOKSETS *);
+static void exp_lkst (void);
+static void exp_wsets (void);
+static void exp_states (void);
+static void exp_psmem (void);
+
+ /* lookahead computations */
+
+int TBITSET;
+static int tbitset; /* size of lookahead sets */
+LOOKSETS *lkst;
+static int lsetsize;
+
+static int nlset = 0; /* next lookahead set index */
+int nolook = 0; /* flag to suppress lookahead computations */
+static LOOKSETS clset; /* temporary storage for lookahead computations */
+
+static ITEM *psmem, *zzmemsz;
+static int new_pstsize = PSTSIZE;
+
+ /* I/O descriptors */
+
+extern FILE *finput; /* input file */
+extern FILE *faction; /* file for saving actions */
+extern FILE *fdefine; /* file for #defines */
+extern FILE *fudecl; /* file for user declarations */
+extern FILE *ftable; /* parser tables file */
+extern FILE *fsppout; /* SPP output file */
+extern FILE *ftemp; /* tempfile to pass 2 */
+extern FILE *foutput; /* y.output file */
+
+ /* working set computations */
+
+WSET *wsets;
+int cwp;
+static int wsetsz = 0; /* number of WSET items in wsets block */
+
+ /* state information */
+
+int nstate = 0; /* number of states */
+static int nstatesz = NSTATES; /* number of state space allocated */
+ITEM **pstate; /* ptr to descriptions of the states */
+int *tystate; /* contains type info about the states */
+int *indgo; /* index to the stored goto table */
+static int *tmp_lset;
+static int *tstates; /* states generated by terminal gotos */
+static int *ntstates; /* states generated by non-term gotos */
+static int *mstates; /* chain of overflows of term/nonterm */
+ /* generation lists */
+
+ /* storage for the actions in the parser */
+
+int *amem, *memp; /* next free action table position */
+int new_actsize = ACTSIZE;
+
+ /* other storage areas */
+
+int *temp1; /* temp storate, indexed by terms+ntokens or states */
+int lineno = 0; /* current input line number */
+int size;
+static int fatfl = 1; /* if on, error is fatal */
+static int nerrors = 0; /* number of errors */
+
+ /* storage for information about the nonterminals */
+
+static int ***pres; /* vector of pointers to productions */
+ /* yielding each nonterminal */
+static LOOKSETS **pfirst; /* vector of pointers to first sets for */
+ /* each nonterminal */
+static int *pempty; /* vector of nonterminals nontrivially */
+ /* deriving e */
+extern int nprodsz;
+
+int
+main (int argc, char *argv[])
+{
+ (void) setlocale (LC_ALL, "");
+#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
+#endif
+ /*
+ (void) textdomain (TEXT_DOMAIN);
+ */
+
+ setup (argc, argv); /* initialize and read productions */
+ TBITSET = NWORDS (ntoksz * LKFACTOR);
+ tbitset = NWORDS (ntokens * LKFACTOR);
+ mktbls ();
+ cpres (); /* make table of which productions yield a */
+ /* given nonterminal */
+ cempty (); /* make a table of which nonterminals can match */
+ /* the empty string */
+ cpfir (); /* make a table of firsts of nonterminals */
+ stagen (); /* generate the states */
+ output (); /* write the states and the tables */
+ go2out ();
+ hideprod ();
+ summary ();
+ callopt ();
+ others ();
+ return (0);
+}
+
+
+static void
+mktbls ()
+{
+ int i;
+
+ size = ntoksz + nnontersz + 1;
+ if (size < nstatesz)
+ size = nstatesz;
+ if (size < new_memsize)
+ size = new_memsize;
+
+ amem = (int *) malloc (sizeof (int) * new_actsize);
+ psmem = (ITEM *) malloc (sizeof (ITEM) * new_pstsize);
+ if ((psmem == NULL) || (amem == NULL))
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This error happens when yacc could not allocate
+ * initial memory to be used for internal tables.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("couldn't allocate initial table");
+ zzmemsz = psmem;
+ memp = amem;
+
+ /*
+ * For lkst
+ */
+#define INIT_LSIZE nnontersz*LKFACTOR
+ tmp_lset = (int *)
+ calloc ((size_t) (TBITSET * (INIT_LSIZE + 1)), sizeof (int));
+ if (tmp_lset == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Yacc could not allocate memory for table named lookset.
+ * Do not translate 'lookset'.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("could not allocate lookset array");
+ lkst = (LOOKSETS *) malloc (sizeof (LOOKSETS) * (INIT_LSIZE + 1));
+ for (i = 0; i <= INIT_LSIZE; ++i)
+ lkst[i].lset = tmp_lset + TBITSET * i;
+ tmp_lset = NULL;
+
+ /*
+ * For wsets
+ */
+ tmp_lset = (int *)
+ calloc ((size_t) (TBITSET * (nnontersz + 1)), sizeof (int));
+ if (tmp_lset == NULL)
+ error ("could not allocate lookset array");
+ wsets = (WSET *) malloc (sizeof (WSET) * (nnontersz + 1));
+ for (i = 0; i <= nnontersz; ++i)
+ wsets[i].ws.lset = tmp_lset + TBITSET * i;
+ tmp_lset = NULL;
+
+ clset.lset = (int *) malloc (sizeof (int) * TBITSET);
+ tstates = (int *) malloc (sizeof (int) * (ntoksz + 1));
+ ntstates = (int *) malloc (sizeof (int) * (nnontersz + 1));
+ temp1 = (int *) malloc (sizeof (int) * size);
+ pres = (int ***) malloc (sizeof (int **) * (nnontersz + 2));
+ pfirst = (LOOKSETS **) malloc (sizeof (LOOKSETS *) * (nnontersz + 2));
+ pempty = (int *) malloc (sizeof (int) * (nnontersz + 1));
+
+ pstate = (ITEM **) malloc (sizeof (ITEM *) * (nstatesz + 2));
+ tystate = (int *) malloc (sizeof (int) * nstatesz);
+ indgo = (int *) malloc (sizeof (int) * nstatesz);
+ mstates = (int *) malloc (sizeof (int) * nstatesz);
+ defact = (int *) malloc (sizeof (int) * nstatesz);
+
+ if ((lkst == NULL) || (wsets == NULL) || (tstates == NULL) ||
+ (ntstates == NULL) || (temp1 == NULL) || (pres == NULL) ||
+ (pfirst == NULL) || (pempty == NULL) || (pstate == NULL) ||
+ (tystate == NULL) || (indgo == NULL) || (mstates == NULL) ||
+ (defact == NULL) || (clset.lset == NULL))
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate mktbls(). It is a function name.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("cannot allocate tables in mktbls()");
+
+ aryfil (ntstates, nnontersz + 1, 0);
+ aryfil (tstates, ntoksz + 1, 0);
+ wsetsz = nnontersz + 1;
+ lsetsize = INIT_LSIZE + 1;
+}
+
+/* put out other arrays, copy the parsers */
+static void
+others ()
+{
+ extern int gen_lines;
+ int c, i, j;
+ int tmpline;
+
+ finput = fopen (parser, "r");
+ if (finput == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This error message is issued when yacc can not find
+ * the parser to be copied.
+ */
+ error ("cannot find parser %s", parser);
+
+ warray ("yyr1", levprd, nprod);
+
+ aryfil (temp1, nprod, 0);
+ /* had_act[i] is either 1 or 0 */
+/* original
+ PLOOP(1, i)
+ temp1[i] = ((prdptr[i+1] - prdptr[i]-2) << 1) | had_act[i];
+*/
+ PLOOP (1, i) temp1[i] = prdptr[i + 1] - prdptr[i] - 2;
+
+ warray ("yyr2", temp1, nprod);
+
+ aryfil (temp1, nstate, -1000);
+ TLOOP (i) for (j = tstates[i]; j != 0; j = mstates[j])
+ temp1[j] = tokset[i].value;
+ NTLOOP (i) for (j = ntstates[i]; j != 0; j = mstates[j])
+ temp1[j] = -i;
+ warray ("yychk", temp1, nstate);
+ warray ("yydef", defact, nstate);
+
+ fclose (ftable);
+ fclose (fudecl);
+
+ if ((fdebug = fopen (DEBUGNAME, "r")) == NULL)
+ error ("cannot open yacc.debug");
+ while ((c = getc (fdebug)) != EOF)
+ (void) putc (c, fsppout);
+ (void) fclose (fdebug);
+ ZAPFILE (DEBUGNAME);
+
+ if (gen_lines)
+ (void) fprintf (fsppout, "# line\t1 \"%s\"\n", parser);
+ tmpline = 1;
+ /* copy parser text */
+ while ((c = getc (finput)) != EOF) {
+ if (c == '\n')
+ tmpline++;
+ if (c == '$') {
+ if ((c = getc (finput)) == 'A') {
+ /* Replace $A macro by the user declarations.
+ */
+ fudecl = fopen (UDFILE, "r");
+ if (fudecl == NULL)
+ error ("cannot reopen user declarations tempfile");
+ while ((c = getc (fudecl)) != EOF)
+ putc (c, fsppout);
+ fclose (fudecl);
+ ZAPFILE (UDFILE);
+ /* Skip remainder of line following macro.
+ */
+ while ((c = getc (finput)) != '\n' && c != EOF);
+
+ } else if (c == 'B') {
+ /* Replace $B macro by the parser tables.
+ */
+ ftable = fopen (TABFILE, "r");
+ if (ftable == NULL)
+ error ("cannot reopen parser tables tempfile");
+ while ((c = getc (ftable)) != EOF)
+ putc (c, fsppout);
+ fclose (ftable);
+ ZAPFILE (TABFILE);
+ /* Skip remainder of line following macro.
+ */
+ while ((c = getc (finput)) != '\n' && c != EOF);
+
+ } else if (c == 'C') {
+ /* Replace $C macro by user-supplied actions.
+ */
+ faction = fopen (ACTNAME, "r");
+ if (faction == NULL)
+ error ("cannot reopen action tempfile");
+ while ((c = getc (faction)) != EOF)
+ putc (c, fsppout);
+ fclose (faction);
+ ZAPFILE (ACTNAME);
+ /* Skip remainder of line following macro.
+ */
+ while ((c = getc (finput)) != '\n' && c != EOF);
+
+ } else {
+ putc ('$', fsppout);
+ putc (c, fsppout);
+ }
+
+ } else
+ putc (c, fsppout);
+ }
+
+ fclose (fsppout);
+}
+
+
+/* copies string q into p, returning next free char ptr */
+static char *
+chcopy (p, q)
+ char *p, *q;
+{
+ while ((*p = *q++))
+ ++p;
+ return (p);
+}
+
+#define ISIZE 400
+/* creates output string for item pointed to by pp */
+char *
+writem (pp)
+ int *pp;
+{
+ int i, *p;
+ static int isize = ISIZE;
+ static char *sarr = NULL;
+ char *q;
+
+ if (sarr == NULL) {
+ sarr = (char *) malloc (sizeof (char) * isize);
+ if (sarr == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This error is issued when yacc could not allocate
+ * memory for internally used array.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("could not allocate output string array");
+ for (i = 0; i < isize; ++i)
+ sarr[i] = ' ';
+ }
+ for (p = pp; *p > 0; ++p) /* NULL */
+ ;
+ p = prdptr[-*p];
+ q = chcopy (sarr, nontrst[*p - NTBASE].name);
+ q = chcopy (q, " : ");
+
+ for (;;) {
+ *q++ = ++p == pp ? '_' : ' ';
+ *q = 0;
+ if ((i = *p) <= 0)
+ break;
+ q = chcopy (q, symnam (i));
+ while (q > &sarr[isize - 30]) {
+ static char *sarrbase;
+
+ sarrbase = sarr;
+ isize += ISIZE;
+ sarr = (char *)
+ realloc ((char *) sarr, sizeof (*sarr) * isize);
+ if (sarr == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This error is issued when yacc could not allocate
+ * memory for internally used array.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("cannot expand sarr arrays");
+ q = q - sarrbase + sarr;
+ }
+ }
+
+ /* an item calling for a reduction */
+ if ((i = *pp) < 0) {
+ q = chcopy (q, " (");
+ (void) sprintf (q, "%d)", -i);
+ }
+ return (sarr);
+}
+
+/* return a pointer to the name of symbol i */
+char *
+symnam (int i)
+{
+ char *cp;
+
+ cp = (i >= NTBASE) ? nontrst[i - NTBASE].name : tokset[i].name;
+ if (*cp == ' ')
+ ++cp;
+ return (cp);
+}
+
+static int zzcwp = 0;
+static int zzclose = 0;
+int zzgoent = 0;
+int zzgobest = 0;
+int zzacent = 0;
+int zzexcp = 0;
+int zzsrconf = 0;
+int zzrrconf = 0;
+
+/* output the summary on the tty */
+static void
+summary ()
+{
+ if (foutput != NULL) {
+ (void) fprintf (foutput,
+ "\n%d/%d terminals, %d/%d nonterminals\n",
+ ntokens, ntoksz, nnonter, nnontersz);
+ (void) fprintf (foutput,
+ "%d/%d grammar rules, %d/%d states\n",
+ nprod, nprodsz, nstate, nstatesz);
+ (void) fprintf (foutput,
+ "%d shift/reduce, %d reduce/reduce conflicts reported\n",
+ zzsrconf, zzrrconf);
+ (void) fprintf (foutput, "%d/%d working sets used\n", zzcwp, wsetsz);
+ (void) fprintf (foutput,
+ "memory: states,etc. %" PRIdPTR
+ "/%d, parser %" PRIdPTR "/%d\n",
+ mem - tracemem, new_memsize,
+ memp - amem, new_actsize);
+ (void) fprintf (foutput,
+ "%d/%d distinct lookahead sets\n", nlset, lsetsize);
+ (void) fprintf (foutput, "%d extra closures\n", zzclose - 2 * nstate);
+ (void) fprintf (foutput,
+ "%d shift entries, %d exceptions\n", zzacent, zzexcp);
+ (void) fprintf (foutput, "%d goto entries\n", zzgoent);
+ (void) fprintf (foutput,
+ "%d entries saved by goto default\n", zzgobest);
+ }
+ if (zzsrconf != 0 || zzrrconf != 0) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * You may just leave this message un-translated.
+ * This message only makes sense to those who knows
+ * how yacc works, and the person should know what
+ * this message means in English.
+ */
+ (void) fprintf (stderr, "\nconflicts: ");
+ if (zzsrconf)
+ (void) fprintf (stderr, "%d shift/reduce", zzsrconf);
+ if (zzsrconf && zzrrconf)
+ (void) fprintf (stderr, ", ");
+ if (zzrrconf)
+ (void) fprintf (stderr, "%d reduce/reduce", zzrrconf);
+ (void) fprintf (stderr, "\n");
+ }
+
+ if (ftemp != NULL)
+ (void) fclose (ftemp);
+ if (fdefine != NULL)
+ (void) fclose (fdefine);
+}
+
+/* write out error comment */
+/*PRINTFLIKE1*/
+void
+error (char *s, ...)
+{
+ extern char *infile;
+ va_list ap;
+
+ va_start (ap, s);
+
+ ++nerrors;
+ if (!lineno)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is a prefix to the error messages
+ * passed to error() function.
+ */
+ (void) fprintf (stderr, "command line: fatal: ");
+ else {
+ (void) fprintf (stderr, "\"%s\", ", infile);
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is a prefix to the error messages
+ * passed to error() function.
+ */
+ (void) fprintf (stderr, "line %d: fatal: ", lineno);
+ }
+ (void) vfprintf (stderr, s, ap);
+ (void) fprintf (stderr, "\n");
+ va_end (ap);
+ if (!fatfl)
+ return;
+ summary ();
+ exit (1);
+}
+
+/*
+ * Print out a warning message.
+ */
+/*PRINTFLIKE2*/
+void
+warning (int flag, char *s, ...)
+{
+ extern char *infile;
+ va_list ap;
+ va_start (ap, s);
+
+ (void) fprintf (stderr, "\"%s\", ", infile);
+ /*
+ * If flag, print lineno as well.
+ */
+ if (flag == 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is a prefix to the warning messages
+ * passed to warning() function.
+ */
+ (void) fprintf (stderr, "warning: ");
+ else
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is a prefix to the warning messages
+ * passed to warning() function.
+ */
+ (void) fprintf (stderr, "line %d: warning: ", lineno);
+ (void) vfprintf (stderr, s, ap);
+ (void) fprintf (stderr, "\n");
+ va_end (ap);
+}
+
+/* set elements 0 through n-1 to c */
+void
+aryfil (v, n, c)
+ int *v, n, c;
+{
+ int i;
+ for (i = 0; i < n; ++i)
+ v[i] = c;
+}
+
+/* set a to the union of a and b */
+/* return 1 if b is not a subset of a, 0 otherwise */
+static int
+setunion (a, b)
+ int *a, *b;
+{
+ int i, x, sub;
+
+ sub = 0;
+ SETLOOP (i) {
+ *a = (x = *a) | *b++;
+ if (*a++ != x)
+ sub = 1;
+ }
+ return (sub);
+}
+
+static void
+prlook (p)
+ LOOKSETS *p;
+{
+ int j, *pp;
+ pp = p->lset;
+ if (pp == 0)
+ (void) fprintf (foutput, "\tNULL");
+ else {
+ (void) fprintf (foutput, " { ");
+ TLOOP (j) {
+ if (BIT (pp, j))
+ (void) fprintf (foutput, WSFMT ("%s "), symnam (j));
+ }
+ (void) fprintf (foutput, "}");
+ }
+}
+
+/*
+ * compute an array with the beginnings of productions yielding
+ * given nonterminals
+ * The array pres points to these lists
+ * the array pyield has the lists: the total size is only NPROD+1
+ */
+static void
+cpres ()
+{
+ int **ptrpy;
+ int **pyield;
+ int c, j, i;
+
+ /*
+ * 2/29/88 -
+ * nprodsz is the size of the tables describing the productions.
+ * Normally this will be NPROD unless the production tables have
+ * been expanded, in which case the tables will be NPROD * N(where
+ * N is the number of times the tables had to be expanded.)
+ */
+ if ((pyield = (int **) malloc (sizeof (int *) * nprodsz)) == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This error is issued when yacc could not allocate
+ * memory for internally used array.
+ *
+ * pyield is name of an array. You should not try to translate
+ * this word.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("cannot allocate space for pyield array");
+
+ ptrpy = pyield;
+
+ NTLOOP (i) {
+ c = i + NTBASE;
+ pres[i] = ptrpy;
+ fatfl = 0; /* make undefined symbols nonfatal */
+ PLOOP (0, j) {
+ if (*prdptr[j] == c) /* linear search for all c's */
+ *ptrpy++ = prdptr[j] + 1;
+ }
+ if (pres[i] == ptrpy) { /* c not found */
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Ask somebody who knows yacc how to translate nonterminal or
+ * look at translated yacc document.
+ */
+ error ("undefined nonterminal: %s", nontrst[i].name);
+ }
+ }
+ pres[i] = ptrpy;
+ fatfl = 1;
+ if (nerrors) {
+ summary ();
+ exit (1);
+ }
+ if (ptrpy != &pyield[nprod])
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This is an internal error message.
+ * Very little use to user. You may leave it
+ * un-translated.
+ *
+ * pyied is name of an array. Do not translate it.
+ */
+ error ("internal Yacc error: pyield %d", ptrpy - &pyield[nprod]);
+}
+
+static int indebug = 0;
+/* compute an array with the first of nonterminals */
+static void
+cpfir ()
+{
+ int *p, **s, i, **t, ch, changes;
+
+ zzcwp = nnonter;
+ NTLOOP (i) {
+ aryfil (wsets[i].ws.lset, tbitset, 0);
+ t = pres[i + 1];
+ /* initially fill the sets */
+ for (s = pres[i]; s < t; ++s) {
+ /* check if ch is non-terminal */
+ for (p = *s; (ch = *p) > 0; ++p) {
+ if (ch < NTBASE) { /* should be token */
+ SETBIT (wsets[i].ws.lset, ch);
+ break;
+ } else if (!pempty[ch - NTBASE])
+ break;
+ }
+ }
+ }
+
+ /* now, reflect transitivity */
+
+ changes = 1;
+ while (changes) {
+ changes = 0;
+ NTLOOP (i) {
+ t = pres[i + 1];
+ for (s = pres[i]; s < t; ++s) {
+ for (p = *s; (ch = (*p - NTBASE)) >= 0; ++p) {
+ changes |= setunion (wsets[i].ws.lset, wsets[ch].ws.lset);
+ if (!pempty[ch])
+ break;
+ }
+ }
+ }
+ }
+
+ NTLOOP (i) pfirst[i] = flset (&wsets[i].ws);
+ if (!indebug)
+ return;
+ if ((foutput != NULL)) {
+ NTLOOP (i) {
+ (void) fprintf (foutput, WSFMT ("\n%s: "), nontrst[i].name);
+ prlook (pfirst[i]);
+ (void) fprintf (foutput, " %d\n", pempty[i]);
+ }
+ }
+}
+
+/* sorts last state,and sees if it equals earlier ones. returns state number */
+int
+state (int c)
+{
+ int size1, size2;
+ int i;
+ ITEM *p1, *p2, *k, *l, *q1, *q2;
+ p1 = pstate[nstate];
+ p2 = pstate[nstate + 1];
+ if (p1 == p2)
+ return (0); /* null state */
+ /* sort the items */
+ for (k = p2 - 1; k > p1; k--) { /* make k the biggest */
+ for (l = k - 1; l >= p1; --l)
+ if (l->pitem > k->pitem) {
+ int *s;
+ LOOKSETS *ss;
+ s = k->pitem;
+ k->pitem = l->pitem;
+ l->pitem = s;
+ ss = k->look;
+ k->look = l->look;
+ l->look = ss;
+ }
+ }
+ size1 = p2 - p1; /* size of state */
+
+ for (i = (c >= NTBASE) ? ntstates[c - NTBASE] : tstates[c];
+ i != 0; i = mstates[i]) {
+ /* get ith state */
+ q1 = pstate[i];
+ q2 = pstate[i + 1];
+ size2 = q2 - q1;
+ if (size1 != size2)
+ continue;
+ k = p1;
+ for (l = q1; l < q2; l++) {
+ if (l->pitem != k->pitem)
+ break;
+ ++k;
+ }
+ if (l != q2)
+ continue;
+ /* found it */
+ pstate[nstate + 1] = pstate[nstate]; /* delete last state */
+ /* fix up lookaheads */
+ if (nolook)
+ return (i);
+ for (l = q1, k = p1; l < q2; ++l, ++k) {
+ int s;
+ SETLOOP (s) clset.lset[s] = l->look->lset[s];
+ if (setunion (clset.lset, k->look->lset)) {
+ tystate[i] = MUSTDO;
+ /* register the new set */
+ l->look = flset (&clset);
+ }
+ }
+ return (i);
+ }
+ /* state is new */
+ if (nolook)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * You may leave this untranslated. Leave
+ * state/nolook un-translated.
+ */
+ error ("yacc state/nolook error");
+ pstate[nstate + 2] = p2;
+ if (nstate + 1 >= nstatesz)
+ exp_states ();
+ if (c >= NTBASE) {
+ mstates[nstate] = ntstates[c - NTBASE];
+ ntstates[c - NTBASE] = nstate;
+ } else {
+ mstates[nstate] = tstates[c];
+ tstates[c] = nstate;
+ }
+ tystate[nstate] = MUSTDO;
+ return (nstate++);
+}
+
+static int pidebug = 0;
+
+void
+putitem (ptr, lptr)
+ int *ptr;
+ LOOKSETS *lptr;
+{
+ register ITEM *j;
+
+ if (pidebug && (foutput != NULL))
+ (void) fprintf (foutput,
+ WSFMT ("putitem(%s), state %d\n"), writem (ptr),
+ nstate);
+ j = pstate[nstate + 1];
+ j->pitem = ptr;
+ if (!nolook)
+ j->look = flset (lptr);
+ pstate[nstate + 1] = ++j;
+ if (j > zzmemsz) {
+ zzmemsz = j;
+ if (zzmemsz >= &psmem[new_pstsize])
+ exp_psmem ();
+ /* error("out of state space"); */
+ }
+}
+
+/*
+ * mark nonterminals which derive the empty string
+ * also, look for nonterminals which don't derive any token strings
+ */
+static void
+cempty ()
+{
+#define EMPTY 1
+#define WHOKNOWS 0
+#define OK 1
+ int i, *p;
+
+ /*
+ * first, use the array pempty to detect productions
+ * that can never be reduced
+ */
+
+ /* set pempty to WHONOWS */
+ aryfil (pempty, nnonter + 1, WHOKNOWS);
+
+ /*
+ * now, look at productions, marking nonterminals which
+ * derive something
+ */
+ more:
+ PLOOP (0, i) {
+ if (pempty[*prdptr[i] - NTBASE])
+ continue;
+ for (p = prdptr[i] + 1; *p >= 0; ++p)
+ if (*p >= NTBASE && pempty[*p - NTBASE] == WHOKNOWS)
+ break;
+ if (*p < 0) { /* production can be derived */
+ pempty[*prdptr[i] - NTBASE] = OK;
+ goto more;
+ }
+ }
+
+ /* now, look at the nonterminals, to see if they are all OK */
+
+ NTLOOP (i) {
+ /*
+ * the added production rises or falls as the
+ * start symbol ...
+ */
+ if (i == 0)
+ continue;
+ if (pempty[i] != OK) {
+ fatfl = 0;
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Ask somebody who knows yacc how to translate nonterminal or
+ * look at translated yacc document. Check how 'derive' is
+ * translated in these documents also.
+ */
+ error ("nonterminal %s never derives any token string",
+ nontrst[i].name);
+ }
+ }
+
+ if (nerrors) {
+ summary ();
+ exit (1);
+ }
+
+ /*
+ * now, compute the pempty array, to see which nonterminals
+ * derive the empty string
+ */
+
+ /* set pempty to WHOKNOWS */
+
+ aryfil (pempty, nnonter + 1, WHOKNOWS);
+
+ /* loop as long as we keep finding empty nonterminals */
+
+ again:
+ PLOOP (1, i) {
+ /* not known to be empty */
+ if (pempty[*prdptr[i] - NTBASE] == WHOKNOWS) {
+ for (p = prdptr[i] + 1;
+ *p >= NTBASE && pempty[*p - NTBASE] == EMPTY; ++p);
+ /* we have a nontrivially empty nonterminal */
+ if (*p < 0) {
+ pempty[*prdptr[i] - NTBASE] = EMPTY;
+ goto again; /* got one ... try for another */
+ }
+ }
+ }
+}
+
+/* generate the states */
+static int gsdebug = 0;
+static void
+stagen ()
+{
+ int i, j;
+ int c;
+ register WSET *p, *q;
+
+ /* initialize */
+
+ nstate = 0;
+
+ pstate[0] = pstate[1] = psmem;
+ aryfil (clset.lset, tbitset, 0);
+ putitem (prdptr[0] + 1, &clset);
+ tystate[0] = MUSTDO;
+ nstate = 1;
+ pstate[2] = pstate[1];
+
+ aryfil (amem, new_actsize, 0);
+
+ /* now, the main state generation loop */
+
+ more:
+ SLOOP (i) {
+ if (tystate[i] != MUSTDO)
+ continue;
+ tystate[i] = DONE;
+ aryfil (temp1, nnonter + 1, 0);
+ /* take state i, close it, and do gotos */
+ closure (i);
+ WSLOOP (wsets, p) { /* generate goto's */
+ if (p->flag)
+ continue;
+ p->flag = 1;
+ c = *(p->pitem);
+ if (c <= 1) {
+ if (pstate[i + 1] - pstate[i] <= p - wsets)
+ tystate[i] = MUSTLOOKAHEAD;
+ continue;
+ }
+ /* do a goto on c */
+ WSLOOP (p, q) {
+ /* this item contributes to the goto */
+ if (c == *(q->pitem)) {
+ putitem (q->pitem + 1, &q->ws);
+ q->flag = 1;
+ }
+ }
+ if (c < NTBASE)
+ (void) state (c); /* register new state */
+ else
+ temp1[c - NTBASE] = state (c);
+ }
+ if (gsdebug && (foutput != NULL)) {
+ (void) fprintf (foutput, "%d: ", i);
+ NTLOOP (j) {
+ if (temp1[j])
+ (void) fprintf (foutput,
+ WSFMT ("%s %d, "), nontrst[j].name,
+ temp1[j]);
+ }
+ (void) fprintf (foutput, "\n");
+ }
+ indgo[i] = apack (&temp1[1], nnonter - 1) - 1;
+ goto more; /* we have done one goto; do some more */
+ }
+ /* no more to do... stop */
+}
+
+/* generate the closure of state i */
+static int cldebug = 0; /* debugging flag for closure */
+
+void
+closure (int i)
+{
+ int c, ch, work, k;
+ register WSET *u, *v;
+ int *pi;
+ int **s, **t;
+ ITEM *q;
+ register ITEM *p;
+ int idx1 = 0;
+
+ ++zzclose;
+
+ /* first, copy kernel of state i to wsets */
+ cwp = 0;
+ ITMLOOP (i, p, q) {
+ wsets[cwp].pitem = p->pitem;
+ wsets[cwp].flag = 1; /* this item must get closed */
+ SETLOOP (k) wsets[cwp].ws.lset[k] = p->look->lset[k];
+ WSBUMP (cwp);
+ }
+
+ /* now, go through the loop, closing each item */
+
+ work = 1;
+ while (work) {
+ work = 0;
+ /*
+ * WSLOOP(wsets, u) {
+ */
+ for (idx1 = 0; idx1 < cwp; idx1++) {
+ u = &wsets[idx1];
+ if (u->flag == 0)
+ continue;
+ c = *(u->pitem); /* dot is before c */
+ if (c < NTBASE) {
+ u->flag = 0;
+ /*
+ * only interesting case is where . is
+ * before nonterminal
+ */
+ continue;
+ }
+
+ /* compute the lookahead */
+ aryfil (clset.lset, tbitset, 0);
+
+ /* find items involving c */
+
+ WSLOOP (u, v) {
+ if (v->flag == 1 && *(pi = v->pitem) == c) {
+ v->flag = 0;
+ if (nolook)
+ continue;
+ while ((ch = *++pi) > 0) {
+ /* terminal symbol */
+ if (ch < NTBASE) {
+ SETBIT (clset.lset, ch);
+ break;
+ }
+ /* nonterminal symbol */
+ (void) setunion (clset.lset,
+ pfirst[ch - NTBASE]->lset);
+ if (!pempty[ch - NTBASE])
+ break;
+ }
+ if (ch <= 0)
+ (void) setunion (clset.lset, v->ws.lset);
+ }
+ }
+
+ /* now loop over productions derived from c */
+
+ c -= NTBASE; /* c is now nonterminal number */
+
+ t = pres[c + 1];
+ for (s = pres[c]; s < t; ++s) {
+ /* put these items into the closure */
+ WSLOOP (wsets, v) { /* is the item there */
+ /* yes, it is there */
+ if (v->pitem == *s) {
+ if (nolook)
+ goto nexts;
+ if (setunion (v->ws.lset, clset.lset))
+ v->flag = work = 1;
+ goto nexts;
+ }
+ }
+
+ /* not there; make a new entry */
+ if (cwp + 1 >= wsetsz)
+ exp_wsets ();
+
+ wsets[cwp].pitem = *s;
+ wsets[cwp].flag = 1;
+ if (!nolook) {
+ work = 1;
+ SETLOOP (k) wsets[cwp].ws.lset[k] = clset.lset[k];
+ }
+ WSBUMP (cwp);
+ nexts:;
+ }
+ }
+ }
+
+ /* have computed closure; flags are reset; return */
+
+ if (&wsets[cwp] > &wsets[zzcwp])
+ zzcwp = cwp;
+ if (cldebug && (foutput != NULL)) {
+ (void) fprintf (foutput, "\nState %d, nolook = %d\n", i, nolook);
+ WSLOOP (wsets, u) {
+ if (u->flag)
+ (void) fprintf (foutput, "flag set!\n");
+ u->flag = 0;
+ (void) fprintf (foutput, WSFMT ("\t%s"), writem (u->pitem));
+ prlook (&u->ws);
+ (void) fprintf (foutput, "\n");
+ }
+ }
+}
+
+static LOOKSETS *
+flset (p)
+ LOOKSETS *p;
+{
+ /* decide if the lookahead set pointed to by p is known */
+ /* return pointer to a perminent location for the set */
+
+ int j, *w;
+ int *u, *v;
+ register LOOKSETS *q;
+
+ for (q = &lkst[nlset]; q-- > lkst;) {
+ u = p->lset;
+ v = q->lset;
+ w = &v[tbitset];
+ while (v < w)
+ if (*u++ != *v++)
+ goto more;
+ /* we have matched */
+ return (q);
+ more:;
+ }
+ /* add a new one */
+ q = &lkst[nlset++];
+ if (nlset >= lsetsize) {
+ exp_lkst ();
+ q = &lkst[nlset++];
+ }
+ SETLOOP (j) q->lset[j] = p->lset[j];
+ return (q);
+}
+
+static void
+exp_lkst ()
+{
+ int i, j;
+ static LOOKSETS *lookbase;
+
+ lookbase = lkst;
+ lsetsize += LSETSIZE;
+ tmp_lset = (int *)
+ calloc ((size_t) (TBITSET * (lsetsize - LSETSIZE)), sizeof (int));
+ if (tmp_lset == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Memory allocation error. Do not translate lookset.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("could not expand lookset array");
+ lkst = (LOOKSETS *) realloc ((char *) lkst, sizeof (LOOKSETS) * lsetsize);
+ for (i = lsetsize - LSETSIZE, j = 0; i < lsetsize; ++i, ++j)
+ lkst[i].lset = tmp_lset + TBITSET * j;
+ tmp_lset = NULL;
+ if (lkst == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Memory allocation error. Do not translate lookset.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("could not expand lookahead sets");
+ for (i = 0; i <= nnonter; ++i)
+ pfirst[i] = pfirst[i] - lookbase + lkst;
+ for (i = 0; i <= nstate + 1; ++i) {
+ if (psmem[i].look)
+ psmem[i].look = psmem[i].look - lookbase + lkst;
+ if (pstate[i]->look)
+ pstate[i]->look = pstate[i]->look - lookbase + lkst;
+ }
+}
+
+static void
+exp_wsets ()
+{
+ int i, j;
+
+ wsetsz += WSETSIZE;
+ tmp_lset = (int *)
+ calloc ((size_t) (TBITSET * (wsetsz - WSETSIZE)), sizeof (int));
+ if (tmp_lset == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Memory allocation error. Do not translate lookset.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("could not expand lookset array");
+ wsets = (WSET *) realloc ((char *) wsets, sizeof (WSET) * wsetsz);
+ for (i = wsetsz - WSETSIZE, j = 0; i < wsetsz; ++i, ++j)
+ wsets[i].ws.lset = tmp_lset + TBITSET * j;
+ tmp_lset = NULL;
+ if (wsets == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Memory allocation error. You may just transltate
+ * this as 'Could not allocate internally used memory.'
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("could not expand working sets");
+}
+
+static void
+exp_states ()
+{
+ nstatesz += NSTATES;
+
+ pstate = (ITEM **)
+ realloc ((char *) pstate, sizeof (ITEM *) * (nstatesz + 2));
+ mstates = (int *) realloc ((char *) mstates, sizeof (int) * nstatesz);
+ defact = (int *) realloc ((char *) defact, sizeof (int) * nstatesz);
+ tystate = (int *) realloc ((char *) tystate, sizeof (int) * nstatesz);
+ indgo = (int *) realloc ((char *) indgo, sizeof (int) * nstatesz);
+
+ if ((*pstate == NULL) || (tystate == NULL) || (defact == NULL) ||
+ (indgo == NULL) || (mstates == NULL))
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Memory allocation error.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("cannot expand table of states");
+}
+
+static void
+exp_psmem ()
+{
+ int i;
+
+ new_pstsize += PSTSIZE;
+ psmem = (ITEM *) realloc ((char *) psmem, sizeof (ITEM) * new_pstsize);
+ if (psmem == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Memory allocation error.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("cannot expand pstate memory");
+
+ zzmemsz = zzmemsz - pstate[0] + psmem;
+ for (i = 1; i <= nstate + 1; ++i)
+ pstate[i] = pstate[i] - pstate[0] + psmem;
+ pstate[0] = psmem;
+}
diff --git a/unix/boot/xyacc/y2.c b/unix/boot/xyacc/y2.c
new file mode 100644
index 00000000..072b6c8c
--- /dev/null
+++ b/unix/boot/xyacc/y2.c
@@ -0,0 +1,1952 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+//#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "dextern.h"
+#include <stdio.h>
+
+
+#define IDENTIFIER 257
+
+#define MARK 258
+#define TERM 259
+#define LEFT 260
+#define RIGHT 261
+#define BINARY 262
+#define PREC 263
+#define LCURLY 264
+#define C_IDENTIFIER 265 /* name followed by colon */
+#define NUMBER 266
+#define START 267
+#define TYPEDEF 268
+#define TYPENAME 269
+#define UNION 270
+#define ENDFILE 0
+#define LHS_TEXT_LEN 80 /* length of lhstext */
+#define RHS_TEXT_LEN 640 /* length of rhstext */
+ /* communication variables between various I/O routines */
+
+#define v_FLAG 0x01
+#define d_FLAG 0x02
+#define DEFAULT_PREFIX "y"
+
+char *infile; /* input file name */
+static int numbval; /* value of an input number */
+static int toksize = NAMESIZE;
+static char *tokname; /* input token name */
+char *parser = PARSER; /* location of common parser */
+
+static void finact (void);
+static char *cstash (char *);
+static void defout (void);
+static void cpyunion (void);
+static void cpycode (void);
+static void cpyact (int);
+static void lhsfill (char *);
+static void rhsfill (char *);
+static void lrprnt (void);
+#ifdef XYACC_DEBUG
+static void beg_debug (void);
+static void end_toks (void);
+static void end_debug (void);
+#endif
+static void exp_tokname (void);
+static void exp_prod (void);
+static void exp_ntok (void);
+static void exp_nonterm (void);
+static int defin (int, char *);
+static int gettok (void);
+static int chfind (int, char *);
+static int skipcom (void);
+static int findchtok (int);
+#ifdef PREFIX_DEFINE
+static void put_prefix_define (char *);
+#endif
+
+
+/* storage of names */
+
+/*
+ * initial block to place token and
+ * nonterminal names are stored
+ * points to initial block - more space
+ * is allocated as needed.
+ */
+static char cnamesblk0[CNAMSZ];
+static char *cnames = cnamesblk0;
+
+/* place where next name is to be put in */
+static char *cnamp = cnamesblk0;
+
+/* number of defined symbols output */
+static int ndefout = 3;
+
+ /* storage of types */
+static int defunion = 0; /* union of types defined? */
+static int ntypes = 0; /* number of types defined */
+static char *typeset[NTYPES]; /* pointers to type tags */
+
+ /* symbol tables for tokens and nonterminals */
+
+int ntokens = 0;
+int ntoksz = NTERMS;
+TOKSYMB *tokset;
+int *toklev;
+
+int nnonter = -1;
+NTSYMB *nontrst;
+int nnontersz = NNONTERM;
+
+static int start; /* start symbol */
+
+ /* assigned token type values */
+static int extval = 0;
+
+ /* input and output file descriptors */
+
+FILE *finput; /* yacc input file */
+FILE *faction; /* file for saving actions */
+FILE *fdefine; /* file for # defines */
+FILE *ftable; /* y.tab.x file */
+FILE *ftemp; /* tempfile to pass 2 */
+FILE *fudecl; /* file for user declarations */
+FILE *fsppout; /* SPP y.tab.x output file */
+FILE *fdebug; /* where the strings for debugging are stored */
+FILE *foutput; /* y.output file */
+
+ /* output string */
+
+static char *lhstext;
+static char *rhstext;
+
+ /* storage for grammar rules */
+
+int *mem0; /* production storage */
+int *mem;
+int *tracemem;
+extern int *optimmem;
+int new_memsize = MEMSIZE;
+int nprod = 1; /* number of productions */
+int nprodsz = NPROD;
+
+int **prdptr;
+int *levprd;
+char *had_act;
+
+/* flag for generating the # line's default is yes */
+int gen_lines = 1;
+int act_lines = 0;
+
+/* flag for whether to include runtime debugging */
+static int gen_testing = 0;
+
+/* flag for version stamping--default turned off */
+static char *v_stmp = "n";
+
+int nmbchars = 0; /* number of mb literals in mbchars */
+MBCLIT *mbchars = (MBCLIT *) 0; /* array of mb literals */
+int nmbcharsz = 0; /* allocated space for mbchars */
+
+void
+setup (argc, argv)
+ int argc;
+ char *argv[];
+{
+ int ii, i, j, lev, t, ty;
+ /* ty is the sequencial number of token name in tokset */
+ int c;
+ int *p;
+ char *cp;
+ char actname[8];
+ unsigned int options = 0;
+ char *file_prefix = DEFAULT_PREFIX;
+ char *sym_prefix = "";
+#define F_NAME_LENGTH 128
+ char fname[F_NAME_LENGTH + 1];
+
+ foutput = NULL;
+ fdefine = NULL;
+ i = 1;
+
+ tokname = (char *) malloc (sizeof (char) * toksize);
+ tokset = (TOKSYMB *) malloc (sizeof (TOKSYMB) * ntoksz);
+ toklev = (int *) malloc (sizeof (int) * ntoksz);
+ nontrst = (NTSYMB *) malloc (sizeof (NTSYMB) * nnontersz);
+ mem0 = (int *) malloc (sizeof (int) * new_memsize);
+ prdptr = (int **) malloc (sizeof (int *) * (nprodsz + 2));
+ levprd = (int *) malloc (sizeof (int) * (nprodsz + 2));
+ had_act = (char *) calloc ((nprodsz + 2), sizeof (char));
+ lhstext = (char *) calloc (1, sizeof (char) * LHS_TEXT_LEN);
+ rhstext = (char *) calloc (1, sizeof (char) * RHS_TEXT_LEN);
+ aryfil (toklev, ntoksz, 0);
+ aryfil (levprd, nprodsz, 0);
+ for (ii = 0; ii < ntoksz; ++ii)
+ tokset[ii].value = 0;
+ for (ii = 0; ii < nnontersz; ++ii)
+ nontrst[ii].tvalue = 0;
+ aryfil (mem0, new_memsize, 0);
+ mem = mem0;
+ tracemem = mem0;
+
+ while ((c = getopt (argc, argv, "vVdltp:Q:Y:P:b:")) != EOF)
+ switch (c) {
+ case 'v':
+ options |= v_FLAG;
+ break;
+ case 'V':
+ (void) fprintf (stderr, "yacc: NOAO/IRAF v1.0\n");
+ break;
+ case 'Q':
+ v_stmp = optarg;
+ if (*v_stmp != 'y' && *v_stmp != 'n')
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate -Q and [y/n].
+ */
+ error ("yacc: -Q should be followed by [y/n]");
+ break;
+ case 'd':
+ options |= d_FLAG;
+ break;
+ case 'l':
+ gen_lines = 0; /* don't gen #lines */
+ break;
+ case 't':
+ gen_testing = 1; /* set YYDEBUG on */
+ break;
+ case 'Y':
+ cp = (char *) malloc (strlen (optarg) + sizeof ("/yaccpar") + 1);
+ cp = strcpy (cp, optarg);
+ parser = strcat (cp, "/yaccpar");
+ break;
+ case 'P':
+ parser = optarg;
+ break;
+ case 'p':
+ if (strcmp (optarg, "yy") != 0)
+ sym_prefix = optarg;
+ else
+ sym_prefix = "";
+ break;
+ case 'b':
+ file_prefix = optarg;
+ break;
+ case '?':
+ default:
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This is a usage message. The translate should be
+ * consistent with man page translation.
+ */
+ (void) fprintf (stderr,
+ "Usage: yacc [-vVdltY] [-Q(y/n)] [-b file_prefix] [-p sym_prefix]"
+ " [-P parser] file\n");
+ exit (1);
+ }
+ /*
+ * Open y.output if -v is specified
+ */
+ if (options & v_FLAG) {
+ (void) strncpy (fname,
+ file_prefix, F_NAME_LENGTH - strlen (".output"));
+ (void) strcat (fname, ".output");
+ foutput = fopen (fname, "w");
+ if (foutput == NULL)
+ error ("cannot open y.output");
+ }
+
+ /*
+ * Open y.tab.h if -d is specified
+ */
+ if (options & d_FLAG) {
+ (void) strncpy (fname,
+ file_prefix, F_NAME_LENGTH - strlen (".tab.h"));
+ (void) strcat (fname, ".tab.h");
+ fdefine = fopen (fname, "w");
+ if (fdefine == NULL)
+ error ("cannot open y.tab.h");
+ }
+
+ fdebug = fopen (DEBUGNAME, "w");
+ if (fdebug == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate yacc.debug.
+ */
+ error ("cannot open yacc.debug");
+ /*
+ * Open ytab.x
+ (void) strncpy(fname, file_prefix, F_NAME_LENGTH-strlen(".tab.x"));
+ (void) strcat(fname, ".tab.x");
+ ftable = fopen(fname, "w");
+ if (ftable == NULL)
+ error("cannot open %s", fname);
+ */
+
+
+ fsppout = fopen (OFILE, "w");
+ if (fsppout == NULL)
+ error ("cannot create output file");
+ ftable = fopen (TABFILE, "w");
+ if (ftable == NULL)
+ error ("cannot create table file");
+ fudecl = fopen (UDFILE, "w");
+ if (fudecl == NULL)
+ error ("cannot create user declarations file");
+
+
+ ftemp = fopen (TEMPNAME, "w");
+ faction = fopen (ACTNAME, "w");
+ if (ftemp == NULL || faction == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * The message means: "Could not open a temporary file."
+ */
+ error ("cannot open temp file");
+
+ if ((finput = fopen (infile = argv[optind], "r")) == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error ("cannot open input file");
+
+ lineno = 1;
+ cnamp = cnames;
+ (void) defin (0, "$end");
+ extval = 0400;
+ (void) defin (0, "error");
+ (void) defin (1, "$accept");
+ mem = mem0;
+ lev = 0;
+ ty = 0;
+ i = 0;
+#ifdef XYACC_DEBUG
+ beg_debug(); /* initialize fdebug file */
+#endif
+
+ /*
+ * sorry -- no yacc parser here.....
+ * we must bootstrap somehow...
+ */
+
+ t = gettok ();
+ if (*v_stmp == 'y')
+ (void) fprintf (ftable, "#ident\t\"yacc: NOAO/IRAF v1.0\"\n");
+ for (; t != MARK && t != ENDFILE;) {
+ int tok_in_line;
+ switch (t) {
+
+ case ';':
+ t = gettok ();
+ break;
+
+ case START:
+ if ((t = gettok ()) != IDENTIFIER) {
+ error ("bad %%start construction");
+ }
+ start = chfind (1, tokname);
+ t = gettok ();
+ continue;
+
+ case TYPEDEF:
+ tok_in_line = 0;
+ if ((t = gettok ()) != TYPENAME)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate %%type.
+ */
+ error ("bad syntax in %%type");
+ ty = numbval;
+ for (;;) {
+ t = gettok ();
+ switch (t) {
+
+ case IDENTIFIER:
+ /*
+ * The following lines are idented to left.
+ */
+ tok_in_line = 1;
+ if ((t = chfind (1, tokname)) < NTBASE) {
+ j = TYPE (toklev[t]);
+ if (j != 0 && j != ty) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error
+ ("type redeclaration of token %s",
+ tokset[t].name);
+ } else
+ SETTYPE (toklev[t], ty);
+ } else {
+ j = nontrst[t - NTBASE].tvalue;
+ if (j != 0 && j != ty) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how nonterminal is translated in translated
+ * yacc man page or yacc user's document.
+ */
+ error
+ ("type redeclaration of nonterminal %s",
+ nontrst[t - NTBASE].name);
+ } else
+ nontrst[t - NTBASE].tvalue = ty;
+ }
+ /* FALLTHRU */
+ /*
+ * End Indentation
+ */
+ case ',':
+ continue;
+
+ case ';':
+ t = gettok ();
+ break;
+ default:
+ break;
+ }
+ if (!tok_in_line)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error ("missing tokens or illegal tokens");
+ break;
+ }
+ continue;
+
+ case UNION:
+ /* copy the union declaration to the output */
+ cpyunion ();
+ defunion = 1;
+ t = gettok ();
+ continue;
+
+ case LEFT:
+ case BINARY:
+ case RIGHT:
+ i++;
+ /* FALLTHRU */
+ case TERM:
+ tok_in_line = 0;
+
+ /* nonzero means new prec. and assoc. */
+ lev = (t - TERM) | 04;
+ ty = 0;
+
+ /* get identifiers so defined */
+
+ t = gettok ();
+ if (t == TYPENAME) { /* there is a type defined */
+ ty = numbval;
+ t = gettok ();
+ }
+
+ for (;;) {
+ switch (t) {
+
+ case ',':
+ t = gettok ();
+ continue;
+
+ case ';':
+ break;
+
+ case IDENTIFIER:
+ tok_in_line = 1;
+ j = chfind (0, tokname);
+ if (j > NTBASE) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error ("%s is not a token.", tokname);
+ }
+ if (lev & ~04) {
+ if (ASSOC (toklev[j]) & ~04)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error
+ ("redeclaration of precedence of %s",
+ tokname);
+ SETASC (toklev[j], lev);
+ SETPLEV (toklev[j], i);
+ } else {
+ if (ASSOC (toklev[j]))
+ (void) warning (1,
+ "redeclaration of precedence of %s.",
+ tokname);
+ SETASC (toklev[j], lev);
+ }
+ if (ty) {
+ if (TYPE (toklev[j]))
+ error (
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ "redeclaration of type of %s", tokname);
+ SETTYPE (toklev[j], ty);
+ }
+ if ((t = gettok ()) == NUMBER) {
+ tokset[j].value = numbval;
+ if (j < ndefout && j > 2) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error
+ ("type number of %s should be defined earlier",
+ tokset[j].name);
+ }
+ if (numbval >= -YYFLAG1) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error
+ ("token numbers must be less than %d",
+ -YYFLAG1);
+ }
+ t = gettok ();
+ }
+ continue;
+
+ }
+ if (!tok_in_line)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error ("missing tokens or illegal tokens");
+ break;
+ }
+ continue;
+
+ case LCURLY:
+ defout ();
+ cpycode ();
+ t = gettok ();
+ continue;
+
+ default:
+ error ("syntax error");
+
+ }
+
+ }
+
+ if (t == ENDFILE) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate %%%%.
+ */
+ error ("unexpected EOF before %%%%");
+ }
+
+ /* t is MARK */
+
+ defout ();
+#ifdef XYACC_DEBUG
+ end_toks(); /* all tokens dumped - get ready for reductions */
+#endif
+
+ fprintf (fsppout, "define\tyyclearin\tyychar = -1\n");
+ fprintf (fsppout, "define\tyyerrok\t\tyyerrflag = 0\n");
+ fprintf (fsppout,
+ "define\tYYMOVE\t\tcall amovi (Memi[$1], Memi[$2], YYOPLEN)\n");
+
+ prdptr[0] = mem;
+ /* added production */
+ *mem++ = NTBASE;
+
+ /* if start is 0, we will overwrite with the lhs of the first rule */
+ *mem++ = start;
+ *mem++ = 1;
+ *mem++ = 0;
+ prdptr[1] = mem;
+
+ while ((t = gettok ()) == LCURLY)
+ cpycode ();
+
+ if (t != C_IDENTIFIER)
+ error ("bad syntax on first rule");
+
+ if (!start)
+ prdptr[0][1] = chfind (1, tokname);
+
+ /* read rules */
+
+ while (t != MARK && t != ENDFILE) {
+
+ /* process a rule */
+
+ if (t == '|') {
+ rhsfill ((char *) 0); /* restart fill of rhs */
+ *mem = *prdptr[nprod - 1];
+ if (++mem >= &tracemem[new_memsize])
+ exp_mem (1);
+ } else if (t == C_IDENTIFIER) {
+ *mem = chfind (1, tokname);
+ if (*mem < NTBASE)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how nonterminal is translated.
+ */
+ error ("illegal nonterminal in grammar rule");
+ if (++mem >= &tracemem[new_memsize])
+ exp_mem (1);
+ lhsfill (tokname); /* new rule: restart strings */
+ } else
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error ("illegal rule: missing semicolon or | ?");
+
+ /* read rule body */
+
+
+ t = gettok ();
+ more_rule:
+ while (t == IDENTIFIER) {
+ *mem = chfind (1, tokname);
+ if (*mem < NTBASE)
+ levprd[nprod] = toklev[*mem] & ~04;
+ if (++mem >= &tracemem[new_memsize])
+ exp_mem (1);
+ rhsfill (tokname); /* add to rhs string */
+ t = gettok ();
+ }
+
+ if (t == PREC) {
+ if (gettok () != IDENTIFIER)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate %%prec.
+ */
+ error ("illegal %%prec syntax");
+ j = chfind (2, tokname);
+ if (j >= NTBASE)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate %%prec.
+ */
+ error ("nonterminal %s illegal after %%prec",
+ nontrst[j - NTBASE].name);
+ levprd[nprod] = toklev[j] & ~04;
+ t = gettok ();
+ }
+
+ if (t == '=') {
+ had_act[nprod] = 1;
+ levprd[nprod] |= ACTFLAG;
+ (void) fprintf (faction, "\ncase %d:", nprod);
+ cpyact (mem - prdptr[nprod] - 1);
+ /* !SPP (void) fprintf(faction, " break;"); */
+
+ if ((t = gettok ()) == IDENTIFIER) {
+ /* action within rule... */
+
+#ifdef XYACC_DEBUG
+ lrprnt(); /* dump lhs, rhs */
+#endif
+ (void) sprintf (actname, "$$%d", nprod);
+ /*
+ * make it nonterminal
+ */
+ j = chfind (1, actname);
+
+ /*
+ * the current rule will become rule
+ * number nprod+1 move the contents down,
+ * and make room for the null
+ */
+
+ if (mem + 2 >= &tracemem[new_memsize])
+ exp_mem (1);
+ for (p = mem; p >= prdptr[nprod]; --p)
+ p[2] = *p;
+ mem += 2;
+
+ /* enter null production for action */
+
+ p = prdptr[nprod];
+
+ *p++ = j;
+ *p++ = -nprod;
+
+ /* update the production information */
+
+ levprd[nprod + 1] = levprd[nprod] & ~ACTFLAG;
+ levprd[nprod] = ACTFLAG;
+
+ if (++nprod >= nprodsz)
+ exp_prod ();
+ prdptr[nprod] = p;
+
+ /*
+ * make the action appear in
+ * the original rule
+ */
+ *mem++ = j;
+ if (mem >= &tracemem[new_memsize])
+ exp_mem (1);
+ /* get some more of the rule */
+ goto more_rule;
+ }
+ }
+ while (t == ';')
+ t = gettok ();
+ *mem++ = -nprod;
+ if (mem >= &tracemem[new_memsize])
+ exp_mem (1);
+
+ /* check that default action is reasonable */
+
+ if (ntypes && !(levprd[nprod] & ACTFLAG) &&
+ nontrst[*prdptr[nprod] - NTBASE].tvalue) {
+ /* no explicit action, LHS has value */
+ int tempty;
+ tempty = prdptr[nprod][1];
+ if (tempty < 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * LHS means Left Hand Side. It does not need to be translated.
+ */
+ error ("must return a value, since LHS has a type");
+ else if (tempty >= NTBASE)
+ tempty = nontrst[tempty - NTBASE].tvalue;
+ else
+ tempty = TYPE (toklev[tempty]);
+ if (tempty != nontrst[*prdptr[nprod] - NTBASE].tvalue) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how action is transltated in yacc man page or documents.
+ */
+ error ("default action causes potential type clash");
+ }
+ }
+
+ if (++nprod >= nprodsz)
+ exp_prod ();
+ prdptr[nprod] = mem;
+ levprd[nprod] = 0;
+ }
+ /* end of all rules */
+
+#ifdef XYACC_DEBUG
+ end_debug(); /* finish fdebug file's input */
+#endif
+ finact ();
+ if (t == MARK) {
+ /*
+ if (gen_lines)
+ (void) fprintf(fsppout, "\n# a line %d \"%s\"\n",
+ lineno, infile);
+ */
+ while ((c = getc (finput)) != EOF)
+ (void) putc (c, fsppout);
+ }
+ (void) fclose (finput);
+}
+
+static void
+finact ()
+{
+ /* finish action routine */
+ (void) fclose (faction);
+ (void) fprintf (fsppout, "define\tYYERRCODE\t%d\n", tokset[2].value);
+}
+
+static char *
+cstash (s)
+ register char *s;
+{
+ char *temp;
+ static int used = 0;
+ static int used_save = 0;
+ static int exp_cname = CNAMSZ;
+ int len = strlen (s);
+
+ /*
+ * 2/29/88 -
+ * Don't need to expand the table, just allocate new space.
+ */
+ used_save = used;
+ while (len >= (exp_cname - used_save)) {
+ exp_cname += CNAMSZ;
+ if (!used)
+ free ((char *) cnames);
+ if ((cnames = (char *) malloc (sizeof (char) * exp_cname)) == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("cannot expand string dump");
+ cnamp = cnames;
+ used = 0;
+ }
+
+ temp = cnamp;
+ do {
+ *cnamp++ = *s;
+ }
+ while (*s++);
+ used += cnamp - temp;
+ return (temp);
+}
+
+static int
+defin (int t, char *s)
+{
+ /* define s to be a terminal if t=0 or a nonterminal if t=1 */
+
+ int val;
+
+ val = 0;
+ if (t) {
+ if (++nnonter >= nnontersz)
+ exp_nonterm ();
+ nontrst[nnonter].name = cstash (s);
+ return (NTBASE + nnonter);
+ }
+ /* must be a token */
+ if (++ntokens >= ntoksz)
+ exp_ntok ();
+ tokset[ntokens].name = cstash (s);
+
+ /* establish value for token */
+
+ if (s[0] == ' ' && s[2] == 0) { /* single character literal */
+ val = findchtok (s[1]);
+ } else if (s[0] == ' ' && s[1] == '\\') { /* escape sequence */
+ if (s[3] == 0) { /* single character escape sequence */
+ switch (s[2]) {
+ /* character which is escaped */
+ case 'a':
+ (void) warning (1,
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to warning() function.
+ * Do not trasnlate ANSI C, \\a.
+ */
+ "\\a is ANSI C \"alert\" character");
+#if __STDC__ - 1 == 0
+ val = '\a';
+ break;
+#else
+ val = '\007';
+ break;
+#endif
+ case 'v':
+ val = '\v';
+ break;
+ case 'n':
+ val = '\n';
+ break;
+ case 'r':
+ val = '\r';
+ break;
+ case 'b':
+ val = '\b';
+ break;
+ case 't':
+ val = '\t';
+ break;
+ case 'f':
+ val = '\f';
+ break;
+ case '\'':
+ val = '\'';
+ break;
+ case '"':
+ val = '"';
+ break;
+ case '?':
+ val = '?';
+ break;
+ case '\\':
+ val = '\\';
+ break;
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ default:
+ error ("invalid escape");
+ }
+ } else if (s[2] <= '7' && s[2] >= '0') { /* \nnn sequence */
+ int i = 3;
+ val = s[2] - '0';
+ while (isdigit (s[i]) && i <= 4) {
+ if (s[i] >= '0' && s[i] <= '7')
+ val = val * 8 + s[i] - '0';
+ else
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ */
+ error ("illegal octal number");
+ i++;
+ }
+ if (s[i] != 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\nnn.
+ */
+ error ("illegal \\nnn construction");
+ if (val > 255)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate
+ * \\nnn, \\xnnnnnnnn.
+ */
+ error
+ ("\\nnn exceed \\377; use \\xnnnnnnnn for char value of multibyte char");
+ if (val == 0 && i >= 4)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\000.
+ */
+ error ("'\\000' is illegal");
+ } else if (s[2] == 'x') { /* hexadecimal \xnnn sequence */
+ int i = 3;
+ val = 0;
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to warning() function.
+ * Do not translate \\x, ANSI C.
+ */
+ (void) warning (1, "\\x is ANSI C hex escape");
+ if (isxdigit (s[i]))
+ while (isxdigit (s[i])) {
+ int tmpval;
+ if (isdigit (s[i]))
+ tmpval = s[i] - '0';
+ else if (s[i] >= 'a')
+ tmpval = s[i] - 'a' + 10;
+ else
+ tmpval = s[i] - 'A' + 10;
+ val = 16 * val + tmpval;
+ i++;
+ } else
+ error ("illegal hexadecimal number");
+ if (s[i] != 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\xnn.
+ */
+ error ("illegal \\xnn construction");
+#define LWCHAR_MAX 0x7fffffff
+ if ((unsigned) val > LWCHAR_MAX)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\xnnnnnnnn and %#x.
+ */
+ error (" \\xnnnnnnnn exceed %#x", LWCHAR_MAX);
+ if (val == 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate \\x00.
+ */
+ error ("'\\x00' is illegal");
+ val = findchtok (val);
+ } else
+ error ("invalid escape");
+ } else {
+ val = extval++;
+ }
+ tokset[ntokens].value = val;
+ toklev[ntokens] = 0;
+ return (ntokens);
+}
+
+static void
+defout ()
+{
+ /* write out the defines (at the end of the declaration section) */
+
+ register int i, c;
+ register char *cp;
+
+ for (i = ndefout; i <= ntokens; ++i) {
+
+ cp = tokset[i].name;
+ if (*cp == ' ') { /* literals */
+ (void) fprintf (fdebug, WSFMT ("\t\"%s\",\t%d,\n"),
+ tokset[i].name + 1, tokset[i].value);
+ continue; /* was cp++ */
+ }
+
+ for (; (c = *cp) != 0; ++cp) {
+ if (islower (c) || isupper (c) || isdigit (c) || c == '_')
+ /* EMPTY */ ;
+ else
+ goto nodef;
+ }
+
+ (void) fprintf (fdebug,
+ WSFMT ("\t\"%s\",\t%d,\n"), tokset[i].name,
+ tokset[i].value);
+ (void) fprintf (fsppout, WSFMT ("define\t%s\t\t%d\n"),
+ tokset[i].name, tokset[i].value);
+ if (fdefine != NULL)
+ (void) fprintf (fdefine,
+ WSFMT ("define\t%s\t\t%d\n"), tokset[i].name,
+ tokset[i].value);
+
+ nodef:;
+ }
+ ndefout = ntokens + 1;
+}
+
+static int
+gettok ()
+{
+ int i, base;
+ static int peekline; /* number of '\n' seen in lookahead */
+ int c, match, reserve;
+ begin:
+ reserve = 0;
+ lineno += peekline;
+ peekline = 0;
+ c = getc (finput);
+ /*
+ * while (c == ' ' || c == '\n' || c == '\t' || c == '\f') {
+ */
+ while (isspace (c)) {
+ if (c == '\n')
+ ++lineno;
+ c = getc (finput);
+ }
+ if (c == '#') { /* skip comment */
+ lineno += skipcom ();
+ goto begin;
+ }
+
+ switch (c) {
+
+ case EOF:
+ return (ENDFILE);
+ case '{':
+ (void) ungetc (c, finput);
+ return ('='); /* action ... */
+ case '<': /* get, and look up, a type name (union member name) */
+ i = 0;
+ while ((c = getc (finput)) != '>' && c != EOF && c != '\n') {
+ tokname[i] = c;
+ if (++i >= toksize)
+ exp_tokname ();
+ }
+ if (c != '>')
+ error ("unterminated < ... > clause");
+ tokname[i] = 0;
+ if (i == 0)
+ error ("missing type name in < ... > clause");
+ for (i = 1; i <= ntypes; ++i) {
+ if (!strcmp (typeset[i], tokname)) {
+ numbval = i;
+ return (TYPENAME);
+ }
+ }
+ typeset[numbval = ++ntypes] = cstash (tokname);
+ return (TYPENAME);
+
+ case '"':
+ case '\'':
+ match = c;
+ tokname[0] = ' ';
+ i = 1;
+ for (;;) {
+ c = getc (finput);
+ if (c == '\n' || c == EOF)
+ error ("illegal or missing ' or \"");
+ if (c == '\\') {
+ c = getc (finput);
+ tokname[i] = '\\';
+ if (++i >= toksize)
+ exp_tokname ();
+ } else if (c == match)
+ break;
+ tokname[i] = c;
+ if (++i >= toksize)
+ exp_tokname ();
+ }
+ break;
+
+ case '%':
+ case '\\':
+
+ switch (c = getc (finput)) {
+
+ case '0':
+ return (TERM);
+ case '<':
+ return (LEFT);
+ case '2':
+ return (BINARY);
+ case '>':
+ return (RIGHT);
+ case '%':
+ case '\\':
+ return (MARK);
+ case '=':
+ return (PREC);
+ case '{':
+ return (LCURLY);
+ default:
+ reserve = 1;
+ }
+
+ default:
+
+ if (isdigit (c)) { /* number */
+ numbval = c - '0';
+ base = (c == '0') ? 8 : 10;
+ for (c = getc (finput); isdigit (c); c = getc (finput)) {
+ numbval = numbval * base + c - '0';
+ }
+ (void) ungetc (c, finput);
+ return (NUMBER);
+ } else if (islower (c) || isupper (c) ||
+ c == '_' || c == '.' || c == '$') {
+ i = 0;
+ while (islower (c) || isupper (c) ||
+ isdigit (c) || c == '_' || c == '.' || c == '$') {
+ tokname[i] = c;
+ if (reserve && isupper (c))
+ tokname[i] = tolower (c);
+ if (++i >= toksize)
+ exp_tokname ();
+ c = getc (finput);
+ }
+ } else
+ return (c);
+
+ (void) ungetc (c, finput);
+ }
+
+ tokname[i] = 0;
+
+ if (reserve) { /* find a reserved word */
+ if (!strcmp (tokname, "term"))
+ return (TERM);
+ if (!strcmp (tokname, "token"))
+ return (TERM);
+ if (!strcmp (tokname, "left"))
+ return (LEFT);
+ if (!strcmp (tokname, "nonassoc"))
+ return (BINARY);
+ if (!strcmp (tokname, "binary"))
+ return (BINARY);
+ if (!strcmp (tokname, "right"))
+ return (RIGHT);
+ if (!strcmp (tokname, "prec"))
+ return (PREC);
+ if (!strcmp (tokname, "start"))
+ return (START);
+ if (!strcmp (tokname, "type"))
+ return (TYPEDEF);
+ if (!strcmp (tokname, "union"))
+ return (UNION);
+ error ("invalid escape, or illegal reserved word: %s", tokname);
+ }
+
+ /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
+
+ c = getc (finput);
+ /*
+ * while (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '/')
+ * {
+ */
+ while (isspace (c) || c == '/') {
+ if (c == '\n') {
+ ++peekline;
+ } else if (c == '#') { /* look for comments */
+ peekline += skipcom ();
+ }
+ c = getc (finput);
+ }
+ if (c == ':')
+ return (C_IDENTIFIER);
+ (void) ungetc (c, finput);
+ return (IDENTIFIER);
+}
+
+static int
+fdtype (int t)
+{
+ /* determine the type of a symbol */
+ int v;
+ if (t >= NTBASE)
+ v = nontrst[t - NTBASE].tvalue;
+ else
+ v = TYPE (toklev[t]);
+ if (v <= 0)
+ error ("must specify type for %s",
+ (t >= NTBASE) ? nontrst[t - NTBASE].name : tokset[t].name);
+ return (v);
+}
+
+static int
+chfind (int t, char *s)
+{
+ int i;
+
+ if (s[0] == ' ')
+ t = 0;
+ TLOOP (i) {
+ if (!strcmp (s, tokset[i].name)) {
+ return (i);
+ }
+ }
+ NTLOOP (i) {
+ if (!strcmp (s, nontrst[i].name)) {
+ return (i + NTBASE);
+ }
+ }
+ /* cannot find name */
+ if (t > 1)
+ error ("%s should have been defined earlier", s);
+ return (defin (t, s));
+}
+
+static void
+cpyunion ()
+{
+ /*
+ * copy the union declaration to the output,
+ * and the define file if present
+ */
+ int level, c;
+ if (gen_lines)
+ (void) fprintf (fsppout, "\n# line %d \"%s\"\n", lineno, infile);
+ (void) fprintf (fsppout, "typedef union\n");
+ if (fdefine)
+ (void) fprintf (fdefine, "\ntypedef union\n");
+ (void) fprintf (fsppout, "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
+ if (fdefine)
+ (void) fprintf (fdefine, "#ifdef __cplusplus\n\tYYSTYPE\n#endif\n");
+
+ level = 0;
+ for (;;) {
+ if ((c = getc (finput)) == EOF)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * EOF - End Of File.
+ * Do not translate %%union.
+ */
+ error ("EOF encountered while processing %%union");
+ (void) putc (c, fsppout);
+ if (fdefine)
+ (void) putc (c, fdefine);
+
+ switch (c) {
+
+ case '\n':
+ ++lineno;
+ break;
+
+ case '{':
+ ++level;
+ break;
+
+ case '}':
+ --level;
+ if (level == 0) { /* we are finished copying */
+ (void) fprintf (fsppout, " YYSTYPE;\n");
+ if (fdefine)
+ (void) fprintf (fdefine,
+ " YYSTYPE;\nextern YYSTYPE yylval;\n");
+ return;
+ }
+ }
+ }
+}
+
+static void
+cpycode ()
+{
+ /* copies code between \{ and \} */
+ int c;
+ FILE *out;
+
+
+ c = getc (finput);
+ if (c == '\n') {
+ c = getc (finput);
+ lineno++;
+ }
+
+ /* The %{ .. %} section is divided up into a global and a local region.
+ * The global region is first, so set the out file to fsppout (write
+ * directly into SPP output file). The start of the local declarations
+ * for the parser is marked by %L. When this is seen, direct output
+ * into the temp file fudecl, which is later inserted into the
+ * declarations section of yyparse.
+ */
+ out = fsppout;
+
+ if (gen_lines)
+ (void) fprintf (out, "\n# line %d \"%s\"\n", lineno, infile);
+ for (; c >= 0; c = getc (finput)) {
+ if (c == '\\') {
+ if ((c = getc (finput)) == '}')
+ return;
+ else
+ putc ('\\', out);
+ }
+ if (c == '%') {
+ if ((c = getc (finput)) == '}') {
+ return;
+ } else if (c == 'L') {
+ out = fudecl;
+ continue;
+ } else
+ putc ('%', out);
+ }
+ putc (c, out);
+ if (c == '\n')
+ ++lineno;
+ }
+
+ error ("eof before %%}");
+}
+
+static int
+skipcom ()
+{
+ register int ch;
+
+ /* skip over SPP comments */
+ while ((ch = getc (finput)) != '\n')
+ if (ch == EOF)
+ error ("EOF inside comment");
+
+ return (1);
+}
+
+
+static void
+cpyact (int offset)
+{
+ /* copy C action to the next ; or closing } */
+ int brac, c, match, j, s, tok, argument;
+ char id_name[NAMESIZE + 1];
+ int id_idx = 0;
+
+ if (gen_lines) {
+ (void) fprintf (faction, "\n# line %d \"%s\"\n", lineno, infile);
+ act_lines++;
+ }
+ brac = 0;
+ id_name[0] = 0;
+ loop:
+ c = getc (finput);
+ swt:
+ switch (c) {
+ case ';':
+ if (brac == 0) {
+ (void) putc (c, faction);
+ return;
+ }
+ goto lcopy;
+ case '{':
+ brac++;
+ goto lcopy;
+ case '$':
+ s = 1;
+ tok = -1;
+ argument = 1;
+ while ((c = getc (finput)) == ' ' || c == '\t')
+ /* NULL */ ;
+ if (c == '<') { /* type description */
+ (void) ungetc (c, finput);
+ if (gettok () != TYPENAME)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate $<ident>
+ */
+ error ("bad syntax on $<ident> clause");
+ tok = numbval;
+ c = getc (finput);
+ }
+ if (c == '$') {
+ (void) fprintf (faction, "yyval");
+ if (ntypes) { /* put out the proper tag... */
+ if (tok < 0)
+ tok = fdtype (*prdptr[nprod]);
+ (void) fprintf (faction, WSFMT (".%s"), typeset[tok]);
+ }
+ goto loop;
+ }
+ if (c == '-') {
+ s = -s;
+ c = getc (finput);
+ }
+ if (isdigit (c)) {
+ j = 0;
+ while (isdigit (c)) {
+ j = j * 10 + c - '0';
+ c = getc (finput);
+ }
+ j = j * s - offset;
+ if (j > 0) {
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate $%d.
+ */
+ error ("Illegal use of $%d", j + offset);
+ }
+
+ switch (-j) {
+ case 0:
+ fprintf (faction, "yypvt");
+ break;
+ case 1:
+ fprintf (faction, "yypvt-YYOPLEN");
+ break;
+ default:
+ fprintf (faction, "yypvt-%d*YYOPLEN", -j);
+ }
+
+
+ if (ntypes) { /* put out the proper tag */
+ if (j + offset <= 0 && tok < 0)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate $%d.
+ */
+ error ("must specify type of $%d", j + offset);
+ if (tok < 0)
+ tok = fdtype (prdptr[nprod][j + offset]);
+ (void) fprintf (faction, WSFMT (".%s"), typeset[tok]);
+ }
+ goto swt;
+ }
+ (void) putc ('$', faction);
+ if (s < 0)
+ (void) putc ('-', faction);
+ goto swt;
+ case '}':
+ if (--brac)
+ goto lcopy;
+ (void) putc (c, faction);
+ return;
+ case '/': /* look for comments */
+ (void) putc (c, faction);
+ c = getc (finput);
+ if (c != '*')
+ goto swt;
+ /* it really is a comment */
+ (void) putc (c, faction);
+ c = getc (finput);
+ while (c != EOF) {
+ while (c == '*') {
+ (void) putc (c, faction);
+ if ((c = getc (finput)) == '/')
+ goto lcopy;
+ }
+ (void) putc (c, faction);
+ if (c == '\n')
+ ++lineno;
+ c = getc (finput);
+ }
+ error ("EOF inside comment");
+ /* FALLTHRU */
+ case '\'': /* character constant */
+ case '"': /* character string */
+ match = c;
+ (void) putc (c, faction);
+ while ((c = getc (finput)) != EOF) {
+ if (c == '\\') {
+ (void) putc (c, faction);
+ c = getc (finput);
+ if (c == '\n')
+ ++lineno;
+ } else if (c == match)
+ goto lcopy;
+ else if (c == '\n')
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * This error message is issued when
+ * quoted string has multiple lines.
+ */
+ error ("newline in string or char. const.");
+ (void) putc (c, faction);
+ }
+ error ("EOF in string or character constant");
+ /* FALLTHRU */
+ case EOF:
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Check how 'action' is translated in yacc mapage/document.
+ */
+ error ("action does not terminate");
+ /* FALLTHRU */
+ case '\n':
+ ++lineno;
+ goto lcopy;
+ }
+ lcopy:
+ (void) putc (c, faction);
+ /*
+ * Save the possible identifier name.
+ * Used to print out a warning message.
+ */
+ if (id_idx >= NAMESIZE) {
+ /*
+ * Error. Silently ignore.
+ */
+ /* EMPTY */ ;
+ }
+ /*
+ * If c has a possibility to be a
+ * part of identifier, save it.
+ */
+ else if (isalnum (c) || c == '_') {
+ id_name[id_idx++] = c;
+ id_name[id_idx] = 0;
+ } else {
+ id_idx = 0;
+ id_name[id_idx] = 0;
+ }
+ goto loop;
+}
+
+static void
+lhsfill (s) /* new rule, dump old (if exists), restart strings */
+ char *s;
+{
+ static int lhs_len = LHS_TEXT_LEN;
+ int s_lhs = strlen (s);
+ if (s_lhs >= lhs_len) {
+ lhs_len = s_lhs + 2;
+ lhstext = (char *)
+ realloc ((char *) lhstext, sizeof (char) * lhs_len);
+ if (lhstext == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * LHS -- Left Hand Side.
+ */
+ error ("couldn't expanded LHS length");
+ }
+ rhsfill ((char *) 0);
+ (void) strcpy (lhstext, s); /* don't worry about too long of a name */
+}
+
+static void
+rhsfill (s)
+ char *s; /* either name or 0 */
+{
+ static char *loc; /* next free location in rhstext */
+ static int rhs_len = RHS_TEXT_LEN;
+ static int used = 0;
+ int s_rhs = (s == NULL ? 0 : strlen (s));
+ register char *p;
+
+ if (!s) { /* print out and erase old text */
+ if (*lhstext) /* there was an old rule - dump it */
+ lrprnt ();
+ (loc = rhstext)[0] = 0;
+ return;
+ }
+ /* add to stuff in rhstext */
+ p = s;
+
+ used = loc - rhstext;
+ if ((s_rhs + 3) >= (rhs_len - used)) {
+ static char *textbase;
+ textbase = rhstext;
+ rhs_len += s_rhs + RHS_TEXT_LEN;
+ rhstext = (char *)
+ realloc ((char *) rhstext, sizeof (char) * rhs_len);
+ if (rhstext == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * RHS -- Right Hand Side.
+ */
+ error ("couldn't expanded RHS length");
+ loc = loc - textbase + rhstext;
+ }
+
+ *loc++ = ' ';
+ if (*s == ' ') { /* special quoted symbol */
+ *loc++ = '\''; /* add first quote */
+ p++;
+ }
+ while ((*loc = *p++)) {
+ if (loc++ > &rhstext[RHS_TEXT_LEN] - 3)
+ break;
+ }
+
+ if (*s == ' ')
+ *loc++ = '\'';
+ *loc = 0; /* terminate the string */
+}
+
+static void
+lrprnt ()
+{ /* print out the left and right hand sides */
+ char *rhs;
+ char *m_rhs = NULL;
+
+ if (!*rhstext) /* empty rhs - print usual comment */
+ rhs = " /* empty */";
+ else {
+ int idx1; /* tmp idx used to find if there are d_quotes */
+ int idx2; /* tmp idx used to generate escaped string */
+ char *p;
+ /*
+ * Check if there are any double quote in RHS.
+ */
+ for (idx1 = 0; rhstext[idx1] != 0; idx1++) {
+ if (rhstext[idx1] == '"') {
+ /*
+ * A double quote is found.
+ */
+ idx2 = strlen (rhstext) * 2;
+ p = m_rhs = (char *)
+ malloc ((idx2 + 1) * sizeof (char));
+ if (m_rhs == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * RHS - Right Hand Side.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("Couldn't allocate memory for RHS.");
+ /*
+ * Copy string
+ */
+ for (idx2 = 0; rhstext[idx2] != 0; idx2++) {
+ /*
+ * Check if this quote is escaped or not
+ */
+ if (rhstext[idx2] == '"') {
+ int tmp_l = idx2 - 1;
+ int cnt = 0;
+ while (tmp_l >= 0 && rhstext[tmp_l] == '\\') {
+ cnt++;
+ tmp_l--;
+ }
+ /*
+ * If quote is not escaped,
+ * then escape it.
+ */
+ if (cnt % 2 == 0)
+ *p++ = '\\';
+ }
+ *p++ = rhstext[idx2];
+ }
+ *p = 0;
+ /*
+ * Break from the loop
+ */
+ break;
+ }
+ }
+ if (m_rhs == NULL)
+ rhs = rhstext;
+ else
+ rhs = m_rhs;
+ }
+ (void) fprintf (fdebug, WSFMT ("\t\"%s :%s\",\n"), lhstext, rhs);
+ if (m_rhs)
+ free (m_rhs);
+}
+
+
+#ifdef XYACC_DEBUG
+
+static void
+beg_debug ()
+{ /* dump initial sequence for fdebug file */
+ (void) fprintf (fdebug, "typedef struct\n");
+ (void) fprintf (fdebug, "#ifdef __cplusplus\n\tyytoktype\n");
+ (void) fprintf (fdebug, "#endif\n{\n");
+ (void) fprintf (fdebug, "#ifdef __cplusplus\nconst\n#endif\n");
+ (void) fprintf (fdebug, "char *t_name; int t_val; } yytoktype;\n");
+ (void) fprintf (fdebug,
+ "#ifndef YYDEBUG\n#\tdefine YYDEBUG\t%d", gen_testing);
+ (void) fprintf (fdebug, "\t/*%sallow debugging */\n#endif\n\n",
+ gen_testing ? " " : " don't ");
+ (void) fprintf (fdebug, "#if YYDEBUG\n\nyytoktype yytoks[] =\n{\n");
+}
+
+
+static void
+end_toks ()
+{ /* finish yytoks array, get ready for yyred's strings */
+ (void) fprintf (fdebug, "\t\"-unknown-\",\t-1\t/* ends search */\n");
+ (void) fprintf (fdebug, "};\n\n");
+ (void) fprintf (fdebug, "#ifdef __cplusplus\nconst\n#endif\n");
+ (void) fprintf (fdebug, "char * yyreds[] =\n{\n");
+ (void) fprintf (fdebug, "\t\"-no such reduction-\",\n");
+}
+
+
+static void
+end_debug ()
+{ /* finish yyred array, close file */
+ lrprnt (); /* dump last lhs, rhs */
+ (void) fprintf (fdebug, "};\n#endif /* YYDEBUG */\n");
+ (void) fclose (fdebug);
+}
+
+#endif
+
+
+/*
+ * 2/29/88 -
+ * The normal length for token sizes is NAMESIZE - If a token is
+ * seen that has a longer length, expand "tokname" by NAMESIZE.
+ */
+static void
+exp_tokname ()
+{
+ toksize += NAMESIZE;
+ tokname = (char *) realloc ((char *) tokname, sizeof (char) * toksize);
+}
+
+
+/*
+ * 2/29/88 -
+ *
+ */
+static void
+exp_prod ()
+{
+ int i;
+ nprodsz += NPROD;
+
+ prdptr =
+ (int **) realloc ((char *) prdptr, sizeof (int *) * (nprodsz + 2));
+ levprd = (int *) realloc ((char *) levprd, sizeof (int) * (nprodsz + 2));
+ had_act = (char *)
+ realloc ((char *) had_act, sizeof (char) * (nprodsz + 2));
+ for (i = nprodsz - NPROD; i < nprodsz + 2; ++i)
+ had_act[i] = 0;
+
+ if ((*prdptr == NULL) || (levprd == NULL) || (had_act == NULL))
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("couldn't expand productions");
+}
+
+/*
+ * 2/29/88 -
+ * Expand the number of terminals. Initially there are NTERMS;
+ * each time space runs out, the size is increased by NTERMS.
+ * The total size, however, cannot exceed MAXTERMS because of
+ * the way LOOKSETS(struct looksets) is set up.
+ * Tables affected:
+ * tokset, toklev : increased to ntoksz
+ *
+ * tables with initial dimensions of TEMPSIZE must be changed if
+ * (ntoksz + NNONTERM) >= TEMPSIZE : temp1[]
+ */
+static void
+exp_ntok ()
+{
+ ntoksz += NTERMS;
+
+ tokset = (TOKSYMB *) realloc ((char *) tokset, sizeof (TOKSYMB) * ntoksz);
+ toklev = (int *) realloc ((char *) toklev, sizeof (int) * ntoksz);
+
+ if ((tokset == NULL) || (toklev == NULL))
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate NTERMS.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("couldn't expand NTERMS");
+}
+
+
+static void
+exp_nonterm ()
+{
+ nnontersz += NNONTERM;
+
+ nontrst = (NTSYMB *)
+ realloc ((char *) nontrst, sizeof (TOKSYMB) * nnontersz);
+ if (nontrst == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Do not translate NTERMS.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("couldn't expand NNONTERM");
+}
+
+void
+exp_mem (flag)
+ int flag;
+{
+ int i;
+ static int *membase;
+ new_memsize += MEMSIZE;
+
+ membase = tracemem;
+ tracemem = (int *)
+ realloc ((char *) tracemem, sizeof (int) * new_memsize);
+ if (tracemem == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("couldn't expand mem table");
+ if (flag) {
+ for (i = 0; i <= nprod; ++i)
+ prdptr[i] = prdptr[i] - membase + tracemem;
+ mem = mem - membase + tracemem;
+ } else {
+ size += MEMSIZE;
+ temp1 = (int *) realloc ((char *) temp1, sizeof (int) * size);
+ optimmem = optimmem - membase + tracemem;
+ }
+}
+
+static int
+findchtok (chlit)
+ int chlit;
+/*
+ * findchtok(chlit) returns the token number for a character literal
+ * chlit that is "bigger" than 255 -- the max char value that the
+ * original yacc was build for. This yacc treate them as though
+ * an ordinary token.
+ */
+{
+ int i;
+
+ if (chlit < 0xff)
+ return (chlit); /* single-byte char */
+ for (i = 0; i < nmbchars; ++i) {
+ if (mbchars->character == chlit)
+ return (mbchars->tvalue);
+ }
+
+ /* Not found. Register it! */
+ if (++nmbchars > nmbcharsz) { /* Make sure there's enough space */
+ nmbcharsz += NMBCHARSZ;
+ mbchars = (MBCLIT *)
+ realloc ((char *) mbchars, sizeof (MBCLIT) * nmbcharsz);
+ if (mbchars == NULL)
+ error ("too many character literals");
+ }
+ mbchars[nmbchars - 1].character = chlit;
+ return (mbchars[nmbchars - 1].tvalue = extval++);
+ /* Return the newly assigned token. */
+}
+
+/*
+ * When -p is specified, symbol prefix for
+ * yy{parse, lex, error}(),
+ * yy{lval, val, char, debug, errflag, nerrs}
+ * are defined to the specified name.
+ */
+#ifdef PREFIX_DEFINE
+
+static void
+put_prefix_define (char *pre)
+{
+ char *syms[] = {
+ /* Functions */
+ "parse",
+ "lex",
+ "error",
+ /* Variables */
+ "lval",
+ "val",
+ "char",
+ "debug",
+ "errflag",
+ "nerrs",
+ NULL
+ };
+ int i;
+
+ for (i = 0; syms[i]; i++)
+ (void) fprintf (fsppout, "define\tyy%s\t%s%s\n",
+ syms[i], pre, syms[i]);
+}
+
+#endif
+
+
diff --git a/unix/boot/xyacc/y3.c b/unix/boot/xyacc/y3.c
new file mode 100644
index 00000000..1b6ac149
--- /dev/null
+++ b/unix/boot/xyacc/y3.c
@@ -0,0 +1,606 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+//#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "dextern.h"
+
+static void go2gen (int);
+static void precftn (int, int, int);
+static void wract (int);
+static void wrstate (int);
+static void wdef (char *, int);
+static void wrmbchars (void);
+ /* important local variables */
+static int lastred; /* number of the last reduction of a state */
+int *defact;
+extern int *toklev;
+extern int cwp;
+
+int exca[NSTATES * 2]; /* buffer states for printing with warray */
+int nexca;
+
+
+ /* I/O descriptors */
+
+extern FILE *finput; /* input file */
+extern FILE *faction; /* file for saving actions */
+extern FILE *fdefine; /* file for #defines */
+extern FILE *fudecl; /* file for user declarations */
+extern FILE *ftable; /* parser tables file */
+extern FILE *fsppout; /* SPP output file */
+extern FILE *ftemp; /* tempfile to pass 2 */
+extern FILE *foutput; /* y.output file */
+
+
+
+
+/* print the output for the states */
+void
+output ()
+{
+ int i, k, c;
+ register WSET *u, *v;
+
+ /*
+ (void) fprintf(fsppout, "static YYCONST yytabelem yyexca[] ={\n");
+ */
+
+ SLOOP (i) { /* output the stuff for state i */
+ nolook = !(tystate[i] == MUSTLOOKAHEAD);
+ closure (i);
+ /* output actions */
+ nolook = 1;
+ aryfil (temp1, ntoksz + nnontersz + 1, 0);
+ WSLOOP (wsets, u) {
+ c = *(u->pitem);
+ if (c > 1 && c < NTBASE && temp1[c] == 0) {
+ WSLOOP (u, v) {
+ if (c == *(v->pitem))
+ putitem (v->pitem + 1, (LOOKSETS *) 0);
+ }
+ temp1[c] = state (c);
+ } else if (c > NTBASE && temp1[(c -= NTBASE) + ntokens] == 0) {
+ temp1[c + ntokens] = amem[indgo[i] + c];
+ }
+ }
+ if (i == 1)
+ temp1[1] = ACCEPTCODE;
+ /* now, we have the shifts; look at the reductions */
+ lastred = 0;
+ WSLOOP (wsets, u) {
+ c = *(u->pitem);
+ if (c <= 0) { /* reduction */
+ lastred = -c;
+ TLOOP (k) {
+ if (BIT (u->ws.lset, k)) {
+ if (temp1[k] == 0)
+ temp1[k] = c;
+ else if (temp1[k] < 0) {
+ /*
+ * reduce/reduce
+ * conflict
+ */
+ /* BEGIN CSTYLED */
+ if (foutput != NULL)
+ (void) fprintf (foutput,
+ WSFMT
+ ("\n%d: reduce/reduce conflict"
+ " (red'ns %d and %d ) on %s"),
+ i, -temp1[k], lastred,
+ symnam (k));
+ if (-temp1[k] > lastred)
+ temp1[k] = -lastred;
+ ++zzrrconf;
+ /* END CSTYLED */
+ } else
+ /*
+ * potentia
+ * shift/reduce
+ * conflict.
+ */
+ precftn (lastred, k, i);
+ }
+ }
+ }
+ }
+ wract (i);
+ }
+
+ /*
+ (void) fprintf(fsppout, "\t};\n");
+ */
+ warray ("yyexca", exca, nexca);
+ wdef ("YYNPROD", nprod);
+ if (nmbchars > 0) {
+ wrmbchars ();
+ }
+}
+
+static int pkdebug = 0;
+int
+apack (p, n)
+ int *p;
+ int n;
+{
+ /* pack state i from temp1 into amem */
+ int off;
+ int *pp, *qq;
+ int *q, *rr;
+ int diff;
+
+ /*
+ * we don't need to worry about checking because we
+ * we will only look up entries known to be there...
+ */
+
+ /* eliminate leading and trailing 0's */
+
+ q = p + n;
+ for (pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off)
+ /* NULL */ ;
+ if (pp > q)
+ return (0); /* no actions */
+ p = pp;
+
+ /* now, find a place for the elements from p to q, inclusive */
+ /* for( rr=amem; rr<=r; ++rr,++off ){ *//* try rr */
+ rr = amem;
+ for (;; ++rr, ++off) {
+ while (rr >= &amem[new_actsize - 1])
+ exp_act (&rr);
+ qq = rr;
+ for (pp = p; pp <= q; ++pp, ++qq) {
+ if (*pp) {
+ diff = qq - rr;
+ while (qq >= &amem[new_actsize - 1]) {
+ exp_act (&rr);
+ qq = diff + rr;
+ }
+ if (*pp != *qq && *qq != 0)
+ goto nextk;
+ }
+ }
+
+ /* we have found an acceptable k */
+
+ if (pkdebug && foutput != NULL)
+ (void) fprintf (foutput,
+ "off = %d, k = %" PRIdPTR "\n", off, rr - amem);
+
+ qq = rr;
+ for (pp = p; pp <= q; ++pp, ++qq) {
+ if (*pp) {
+ diff = qq - rr;
+ while (qq >= &amem[new_actsize - 1]) {
+ exp_act (&rr);
+ qq = diff + rr;
+ }
+ if (qq > memp)
+ memp = qq;
+ *qq = *pp;
+ }
+ }
+ if (pkdebug && foutput != NULL) {
+ for (pp = amem; pp <= memp; pp += 10) {
+ (void) fprintf (foutput, "\t");
+ for (qq = pp; qq <= pp + 9; ++qq)
+ (void) fprintf (foutput, "%d ", *qq);
+ (void) fprintf (foutput, "\n");
+ }
+ }
+ return (off);
+ nextk:;
+ }
+ /* error("no space in action table" ); */
+ /* NOTREACHED */
+}
+
+void
+go2out ()
+{
+ /* output the gotos for the nontermninals */
+ int i, j, k, best, count, cbest, times;
+
+ (void) fprintf (ftemp, "$\n"); /* mark begining of gotos */
+
+ for (i = 1; i <= nnonter; ++i) {
+ go2gen (i);
+ /* find the best one to make default */
+ best = -1;
+ times = 0;
+ for (j = 0; j < nstate; ++j) { /* is j the most frequent */
+ if (tystate[j] == 0)
+ continue;
+ if (tystate[j] == best)
+ continue;
+ /* is tystate[j] the most frequent */
+ count = 0;
+ cbest = tystate[j];
+ for (k = j; k < nstate; ++k)
+ if (tystate[k] == cbest)
+ ++count;
+ if (count > times) {
+ best = cbest;
+ times = count;
+ }
+ }
+
+ /* best is now the default entry */
+ zzgobest += (times - 1);
+ for (j = 0; j < nstate; ++j) {
+ if (tystate[j] != 0 && tystate[j] != best) {
+ (void) fprintf (ftemp, "%d,%d,", j, tystate[j]);
+ zzgoent += 1;
+ }
+ }
+
+ /* now, the default */
+
+ zzgoent += 1;
+ (void) fprintf (ftemp, "%d\n", best);
+
+ }
+}
+
+static int g2debug = 0;
+static void
+go2gen (int c)
+{
+ /* output the gotos for nonterminal c */
+ int i, work, cc;
+ ITEM *p, *q;
+
+ /* first, find nonterminals with gotos on c */
+ aryfil (temp1, nnonter + 1, 0);
+ temp1[c] = 1;
+
+ work = 1;
+ while (work) {
+ work = 0;
+ PLOOP (0, i) {
+ if ((cc = prdptr[i][1] - NTBASE) >= 0) {
+ /* cc is a nonterminal */
+ if (temp1[cc] != 0) {
+ /*
+ * cc has a goto on c
+ * thus, the left side of
+ * production i does too.
+ */
+ cc = *prdptr[i] - NTBASE;
+ if (temp1[cc] == 0) {
+ work = 1;
+ temp1[cc] = 1;
+ }
+ }
+ }
+ }
+ }
+
+ /* now, we have temp1[c] = 1 if a goto on c in closure of cc */
+
+ if (g2debug && foutput != NULL) {
+ (void) fprintf (foutput, WSFMT ("%s: gotos on "), nontrst[c].name);
+ NTLOOP (i) if (temp1[i])
+ (void) fprintf (foutput, WSFMT ("%s "), nontrst[i].name);
+ (void) fprintf (foutput, "\n");
+ }
+
+ /* now, go through and put gotos into tystate */
+ aryfil (tystate, nstate, 0);
+ SLOOP (i) {
+ ITMLOOP (i, p, q) {
+ if ((cc = *p->pitem) >= NTBASE) {
+ if (temp1[cc -= NTBASE]) {
+ /* goto on c is possible */
+ tystate[i] = amem[indgo[i] + c];
+ break;
+ }
+ }
+ }
+ }
+}
+
+/* decide a shift/reduce conflict by precedence. */
+static void
+precftn (int r, int t, int s)
+{
+
+ /*
+ * r is a rule number, t a token number
+ * the conflict is in state s
+ * temp1[t] is changed to reflect the action
+ */
+
+ int lp, lt, action;
+
+ lp = levprd[r];
+ lt = toklev[t];
+ if (PLEVEL (lt) == 0 || PLEVEL (lp) == 0) {
+ /* conflict */
+ if (foutput != NULL)
+ (void) fprintf (foutput,
+ WSFMT ("\n%d: shift/reduce conflict"
+ " (shift %d, red'n %d) on %s"),
+ s, temp1[t], r, symnam (t));
+ ++zzsrconf;
+ return;
+ }
+ if (PLEVEL (lt) == PLEVEL (lp))
+ action = ASSOC (lt) & ~04;
+ else if (PLEVEL (lt) > PLEVEL (lp))
+ action = RASC; /* shift */
+ else
+ action = LASC; /* reduce */
+
+ switch (action) {
+ case BASC: /* error action */
+ temp1[t] = ERRCODE;
+ return;
+ case LASC: /* reduce */
+ temp1[t] = -r;
+ return;
+ }
+}
+
+
+/* WRACT -- Output the state I. Modified to save state array in exca
+ * for later printing by warray.
+ */
+static void
+wract (int i)
+{
+ /* output state i */
+ /* temp1 has the actions, lastred the default */
+ int p, p0, p1;
+ int ntimes, tred, count, j;
+ int flag;
+
+ /* find the best choice for lastred */
+
+ lastred = 0;
+ ntimes = 0;
+ TLOOP (j) {
+ if (temp1[j] >= 0)
+ continue;
+ if (temp1[j] + lastred == 0)
+ continue;
+ /* count the number of appearances of temp1[j] */
+ count = 0;
+ tred = -temp1[j];
+ levprd[tred] |= REDFLAG;
+ TLOOP (p) {
+ if (temp1[p] + tred == 0)
+ ++count;
+ }
+ if (count > ntimes) {
+ lastred = tred;
+ ntimes = count;
+ }
+ }
+
+ /*
+ * for error recovery, arrange that, if there is a shift on the
+ * error recovery token, `error', that the default be the error action
+ if (temp1[2] > 0)
+ */
+ if (temp1[1] > 0)
+ lastred = 0;
+
+ /* clear out entries in temp1 which equal lastred */
+ TLOOP (p) {
+ if (temp1[p] + lastred == 0)
+ temp1[p] = 0;
+ }
+
+ wrstate (i);
+ defact[i] = lastred;
+
+ flag = 0;
+ TLOOP (p0) {
+ if ((p1 = temp1[p0]) != 0) {
+ if (p1 < 0) {
+ p1 = -p1;
+ goto exc;
+ } else if (p1 == ACCEPTCODE) {
+ p1 = -1;
+ goto exc;
+ } else if (p1 == ERRCODE) {
+ p1 = 0;
+ goto exc;
+ exc:
+ if (flag++ == 0) {
+ exca[nexca++] = -1;
+ exca[nexca++] = i;
+ }
+ exca[nexca++] = tokset[p0].value;
+ exca[nexca++] = p1;
+ ++zzexcp;
+ if (nexca >= NSTATES * 2) {
+ error ("state table overflow");
+ }
+ } else {
+ (void) fprintf (ftemp, "%d,%d,", tokset[p0].value, p1);
+ ++zzacent;
+ }
+ }
+ }
+ if (flag) {
+ defact[i] = -2;
+ exca[nexca++] = -2;
+ exca[nexca++] = lastred;
+ }
+ (void) fprintf (ftemp, "\n");
+}
+
+static void
+wrstate (int i)
+{
+ /* writes state i */
+ int j0, j1;
+ register ITEM *pp, *qq;
+ register WSET *u;
+
+ if (foutput == NULL)
+ return;
+ (void) fprintf (foutput, "\nstate %d\n", i);
+ ITMLOOP (i, pp, qq) {
+ (void) fprintf (foutput, WSFMT ("\t%s\n"), writem (pp->pitem));
+ }
+ if (tystate[i] == MUSTLOOKAHEAD) {
+ /* print out empty productions in closure */
+ WSLOOP (wsets + (pstate[i + 1] - pstate[i]), u) {
+ if (*(u->pitem) < 0)
+ (void) fprintf (foutput, WSFMT ("\t%s\n"), writem (u->pitem));
+ }
+ }
+
+ /* check for state equal to another */
+ TLOOP (j0) if ((j1 = temp1[j0]) != 0) {
+ (void) fprintf (foutput, WSFMT ("\n\t%s "), symnam (j0));
+ if (j1 > 0) { /* shift, error, or accept */
+ if (j1 == ACCEPTCODE)
+ (void) fprintf (foutput, "accept");
+ else if (j1 == ERRCODE)
+ (void) fprintf (foutput, "error");
+ else
+ (void) fprintf (foutput, "shift %d", j1);
+ } else
+ (void) fprintf (foutput, "reduce %d", -j1);
+ }
+
+ /* output the final production */
+ if (lastred)
+ (void) fprintf (foutput, "\n\t. reduce %d\n\n", lastred);
+ else
+ (void) fprintf (foutput, "\n\t. error\n\n");
+
+ /* now, output nonterminal actions */
+ j1 = ntokens;
+ for (j0 = 1; j0 <= nnonter; ++j0) {
+ if (temp1[++j1])
+ (void) fprintf (foutput,
+ WSFMT ("\t%s goto %d\n"),
+ symnam (j0 + NTBASE), temp1[j1]);
+ }
+}
+
+static void
+wdef (char *s, int n)
+{
+ /* output a definition of s to the value n */
+ (void) fprintf (fsppout, WSFMT ("define\t%s\t\t%d\n"), s, n);
+}
+
+# define NDP_PERLINE 8
+
+void
+warray (s, v, n)
+ char *s;
+ int *v, n;
+{
+ register int i, j;
+
+ fprintf (ftable, "short\t%s[%d]\n", s, n);
+
+ for (j = 0; j < n; j += NDP_PERLINE) {
+ fprintf (ftable, "data\t(%s(i),i=%3d,%3d)\t/",
+ s, j + 1, (j + NDP_PERLINE < n) ? j + NDP_PERLINE : n);
+
+ for (i = j; i < j + NDP_PERLINE && i < n; i++) {
+ if ((i == j + NDP_PERLINE - 1) || i >= n - 1)
+ fprintf (ftable, "%4d/\n", v[i]);
+ else
+ fprintf (ftable, "%4d,", v[i]);
+ }
+ }
+}
+
+void
+hideprod ()
+{
+ /*
+ * in order to free up the mem and amem arrays for the optimizer,
+ * and still be able to output yyr1, etc., after the sizes of
+ * the action array is known, we hide the nonterminals
+ * derived by productions in levprd.
+ */
+
+ int i, j;
+
+ j = 0;
+ levprd[0] = 0;
+ PLOOP (1, i) {
+ if (!(levprd[i] & REDFLAG)) {
+ ++j;
+ if (foutput != NULL) {
+ (void) fprintf (foutput,
+ WSFMT ("Rule not reduced: %s\n"),
+ writem (prdptr[i]));
+ }
+ }
+ levprd[i] = *prdptr[i] - NTBASE;
+ }
+ if (j)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * Check how 'reduced' is translated in yacc man page/document.
+ */
+ (void) fprintf (stderr, "%d rules never reduced\n", j);
+}
+
+
+static int
+cmpmbchars (p, q)
+ MBCLIT *p, *q;
+{
+ /* Compare two MBLITs. */
+ return ((p->character) - (q->character));
+}
+
+static void
+wrmbchars ()
+{
+ int i;
+
+ return wdef ("YYNMBCHARS", nmbchars);
+ qsort (mbchars, nmbchars, sizeof (*mbchars),
+ (int (*)(const void *, const void *)) cmpmbchars);
+ (void) fprintf (ftable,
+ "static struct{\n\tchar character;"
+ "\n\tint tvalue;\n}yymbchars[YYNMBCHARS]={\n");
+ for (i = 0; i < nmbchars; ++i) {
+ (void) fprintf (ftable, "\t{%#x,%d}",
+ (int) mbchars[i].character, mbchars[i].tvalue);
+ if (i < nmbchars - 1) {
+ /* Not the last. */
+ (void) fprintf (ftable, ",\n");
+ }
+ }
+ (void) fprintf (ftable, "\n};\n");
+}
diff --git a/unix/boot/xyacc/y4.c b/unix/boot/xyacc/y4.c
new file mode 100644
index 00000000..2badc0e5
--- /dev/null
+++ b/unix/boot/xyacc/y4.c
@@ -0,0 +1,528 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+//#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "dextern.h"
+#include <wctype.h>
+#define NOMORE -1000
+
+static void gin (int);
+static void stin (int);
+static void osummary (void);
+static void aoutput (void);
+static void arout (char *, int *, int);
+static int nxti (void);
+static int gtnm (void);
+
+static int *ggreed;
+static int *pgo;
+static int *yypgo;
+
+static int maxspr = 0; /* maximum spread of any entry */
+static int maxoff = 0; /* maximum offset into an array */
+int *optimmem;
+static int *maxa;
+
+static int nxdb = 0;
+static int adb = 0;
+
+ /* I/O descriptors */
+
+extern FILE *finput; /* input file */
+extern FILE *faction; /* file for saving actions */
+extern FILE *fdefine; /* file for #defines */
+extern FILE *fudecl; /* file for user declarations */
+extern FILE *ftable; /* parser tables file */
+extern FILE *fsppout; /* SPP output file */
+extern FILE *ftemp; /* tempfile to pass 2 */
+extern FILE *foutput; /* y.output file */
+
+
+void
+callopt ()
+{
+ int i, *p, j, k, *q;
+
+ ggreed = (int *) malloc (sizeof (int) * size);
+ pgo = (int *) malloc (sizeof (int) * size);
+ yypgo = &nontrst[0].tvalue;
+
+ /* read the arrays from tempfile and set parameters */
+
+ if ((finput = fopen (TEMPNAME, "r")) == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * tempfile can be translated as temporary file.
+ */
+ error ("optimizer cannot open tempfile");
+
+ optimmem = tracemem;
+ pgo[0] = 0;
+ temp1[0] = 0;
+ nstate = 0;
+ nnonter = 0;
+ for (;;) {
+ switch (gtnm ()) {
+
+ case '\n':
+ temp1[++nstate] = (--optimmem) - tracemem;
+ /* FALLTHRU */
+
+ case ',':
+ continue;
+
+ case '$':
+ break;
+
+ default:
+ error ("bad tempfile");
+ }
+ break;
+ }
+
+ temp1[nstate] = yypgo[0] = (--optimmem) - tracemem;
+
+ for (;;) {
+ switch (gtnm ()) {
+
+ case '\n':
+ yypgo[++nnonter] = optimmem - tracemem;
+ /* FALLTHRU */
+ case ',':
+ continue;
+
+ case EOF:
+ break;
+
+ default:
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * tempfile can be translated as 'temporary file'.
+ */
+ error ("bad tempfile");
+ }
+ break;
+ }
+
+ yypgo[nnonter--] = (--optimmem) - tracemem;
+
+ for (i = 0; i < nstate; ++i) {
+ k = 32000;
+ j = 0;
+ q = tracemem + temp1[i + 1];
+ for (p = tracemem + temp1[i]; p < q; p += 2) {
+ if (*p > j)
+ j = *p;
+ if (*p < k)
+ k = *p;
+ }
+ if (k <= j) {
+ /*
+ * nontrivial situation
+ * temporarily, kill this for compatibility
+ */
+ /* j -= k; j is now the range */
+ if (k > maxoff)
+ maxoff = k;
+ }
+ tystate[i] = (temp1[i + 1] - temp1[i]) + 2 * j;
+ if (j > maxspr)
+ maxspr = j;
+ }
+
+ /* initialize ggreed table */
+ for (i = 1; i <= nnonter; ++i) {
+ ggreed[i] = 1;
+ j = 0;
+ /* minimum entry index is always 0 */
+ q = tracemem + yypgo[i + 1] - 1;
+ for (p = tracemem + yypgo[i]; p < q; p += 2) {
+ ggreed[i] += 2;
+ if (*p > j)
+ j = *p;
+ }
+ ggreed[i] = ggreed[i] + 2 * j;
+ if (j > maxoff)
+ maxoff = j;
+ }
+
+ /* now, prepare to put the shift actions into the amem array */
+ for (i = 0; i < new_actsize; ++i)
+ amem[i] = 0;
+ maxa = amem;
+
+ for (i = 0; i < nstate; ++i) {
+ if (tystate[i] == 0 && adb > 1)
+ (void) fprintf (ftable, "State %d: null\n", i);
+ indgo[i] = YYFLAG1;
+ }
+
+ while ((i = nxti ()) != NOMORE) {
+ if (i >= 0)
+ stin (i);
+ else
+ gin (-i);
+ }
+
+ if (adb > 2) { /* print a array */
+ for (p = amem; p <= maxa; p += 10) {
+ (void) fprintf (ftable, "%4" PRIdPTR " ", p - amem);
+ for (i = 0; i < 10; ++i)
+ (void) fprintf (ftable, "%4d ", p[i]);
+ (void) fprintf (ftable, "\n");
+ }
+ }
+
+
+ /* write out the output appropriate to the language */
+ aoutput ();
+ osummary ();
+ ZAPFILE (TEMPNAME);
+}
+
+static void
+gin (int i)
+{
+ int *r, *s, *q1, *q2;
+ int *p;
+
+ /* enter gotos on nonterminal i into array amem */
+ ggreed[i] = 0;
+
+ q2 = tracemem + yypgo[i + 1] - 1;
+ q1 = tracemem + yypgo[i];
+
+ /* now, find a place for it */
+
+ /* for( p=amem; p < &amem[new_actsize]; ++p ){ */
+ p = amem;
+ for (;;) {
+ while (p >= &amem[new_actsize])
+ exp_act (&p);
+ if (*p)
+ goto nextgp;
+ for (r = q1; r < q2; r += 2) {
+ s = p + *r + 1;
+ /*
+ * Check if action table needs to
+ * be expanded or not. If so,
+ * expand it.
+ */
+ while (s >= &amem[new_actsize]) {
+ exp_act (&p);
+ s = p + *r + 1;
+ }
+ if (*s)
+ goto nextgp;
+ if (s > maxa) {
+ while ((maxa = s) >= &amem[new_actsize])
+ /* error( "amem array overflow" ); */
+ exp_act (&p);
+ }
+ }
+ /* we have found a spot */
+ *p = *q2;
+ if (p > maxa) {
+ while ((maxa = p) >= &amem[new_actsize])
+ /* error("amem array overflow"); */
+ exp_act (&p);
+ }
+ for (r = q1; r < q2; r += 2) {
+ s = p + *r + 1;
+ /*
+ * Check if action table needs to
+ * be expanded or not. If so,
+ * expand it.
+ */
+ while (s >= &amem[new_actsize]) {
+ exp_act (&p);
+ s = p + *r + 1;
+ }
+ *s = r[1];
+ }
+
+ pgo[i] = p - amem;
+ if (adb > 1)
+ (void) fprintf (ftable,
+ "Nonterminal %d, entry at %d\n", i, pgo[i]);
+ goto nextgi;
+
+ nextgp:
+ ++p;
+ }
+ /* error( "cannot place goto %d\n", i ); */
+ nextgi:;
+}
+
+static void
+stin (int i)
+{
+ int *r, n, nn, flag, j, *q1, *q2;
+ int *s;
+
+ tystate[i] = 0;
+
+ /* Enter state i into the amem array */
+
+ q2 = tracemem + temp1[i + 1];
+ q1 = tracemem + temp1[i];
+ /* Find an acceptable place */
+
+ nn = -maxoff;
+ more:
+ for (n = nn; n < new_actsize; ++n) {
+ flag = 0;
+ for (r = q1; r < q2; r += 2) {
+ s = *r + n + amem;
+ if (s < amem)
+ goto nextn;
+ /*
+ * Check if action table needs to
+ * be expanded or not. If so,
+ * expand it.
+ */
+ while (s >= &amem[new_actsize]) {
+ exp_act ((int **) NULL);
+ s = *r + n + amem;
+ }
+ if (*s == 0)
+ ++flag;
+ else if (*s != r[1])
+ goto nextn;
+ }
+
+ /*
+ * check that the position equals another
+ * only if the states are identical
+ */
+ for (j = 0; j < nstate; ++j) {
+ if (indgo[j] == n) {
+ if (flag)
+ /*
+ * we have some disagreement.
+ */
+ goto nextn;
+ if (temp1[j + 1] + temp1[i] == temp1[j] + temp1[i + 1]) {
+ /* states are equal */
+ indgo[i] = n;
+ if (adb > 1)
+ (void) fprintf (ftable,
+ "State %d: entry at"
+ " %d equals state %d\n", i, n, j);
+ return;
+ }
+ goto nextn; /* we have some disagreement */
+ }
+ }
+
+ for (r = q1; r < q2; r += 2) {
+ while ((s = *r + n + amem) >= &amem[new_actsize]) {
+ /*
+ * error( "out of space");
+ */
+ exp_act ((int **) NULL);
+ }
+ if (s > maxa)
+ maxa = s;
+ if (*s != 0 && *s != r[1])
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ * Leave this untrasnlated. Yacc internal error.
+ */
+ error ("clobber of amem array, pos'n %d, by %d",
+ s - amem, r[1]);
+ *s = r[1];
+ }
+ indgo[i] = n;
+ if (adb > 1)
+ (void) fprintf (ftable, "State %d: entry at %d\n", i, indgo[i]);
+ return;
+ nextn:;
+ }
+
+ /* error( "Error; failure to place state %d\n", i ); */
+ exp_act ((int **) NULL);
+ nn = new_actsize - ACTSIZE;
+ goto more;
+ /* NOTREACHED */
+}
+
+static int
+nxti ()
+{
+ /* finds the next i */
+ int i, max, maxi;
+ max = 0;
+ maxi = 0;
+
+ for (i = 1; i <= nnonter; ++i)
+ if (ggreed[i] >= max) {
+ max = ggreed[i];
+ maxi = -i;
+ }
+
+ for (i = 0; i < nstate; ++i)
+ if (tystate[i] >= max) {
+ max = tystate[i];
+ maxi = i;
+ }
+ if (nxdb)
+ (void) fprintf (ftable, "nxti = %d, max = %d\n", maxi, max);
+ if (max == 0)
+ return (NOMORE);
+ else
+ return (maxi);
+}
+
+static void
+osummary ()
+{
+ /* write summary */
+ int i, *p;
+
+ if (foutput == NULL)
+ return;
+ i = 0;
+ for (p = maxa; p >= amem; --p) {
+ if (*p == 0)
+ ++i;
+ }
+
+ (void) fprintf (foutput,
+ "Optimizer space used: input %" PRIdPTR
+ "/%d, output %" PRIdPTR "/%d\n",
+ optimmem - tracemem + 1, new_memsize, maxa - amem + 1,
+ new_actsize);
+ (void) fprintf (foutput, "%" PRIdPTR " table entries, %d zero\n",
+ (maxa - amem) + 1, i);
+ (void) fprintf (foutput, "maximum spread: %d, maximum offset: %d\n",
+ maxspr, maxoff);
+
+}
+
+
+/* AOUTPUT -- This version is for SPP.
+ */
+static void
+aoutput ()
+{
+ /* write out the optimized parser */
+
+ fprintf (fsppout, "define\tYYLAST\t\t%d\n", (int) (maxa - amem + 1));
+
+ arout ("yyact", amem, (maxa - amem) + 1);
+ arout ("yypact", indgo, nstate);
+ arout ("yypgo", pgo, nnonter + 1);
+}
+
+
+/* AROUT -- Output SPP declarations and initializations for a Yacc table.
+ */
+# define NDP_PERLINE 8
+
+static void
+arout (s, v, n)
+ char *s;
+ int *v, n;
+{
+ register int i, j;
+
+ fprintf (ftable, "short\t%s[%d]\n", s, n);
+
+ for (j = 0; j < n; j += NDP_PERLINE) {
+ fprintf (ftable, "data\t(%s(i),i=%3d,%3d)\t/",
+ s, j + 1, (j + NDP_PERLINE < n) ? j + NDP_PERLINE : n);
+
+ for (i = j; i < j + NDP_PERLINE && i < n; i++) {
+ if ((i == j + NDP_PERLINE - 1) || i >= n - 1)
+ fprintf (ftable, "%4d/\n", v[i]);
+ else
+ fprintf (ftable, "%4d,", v[i]);
+ }
+ }
+}
+
+static int
+gtnm ()
+{
+ int s, val, c;
+
+ /* read and convert an integer from the standard input */
+ /* return the terminating character */
+ /* blanks, tabs, and newlines are ignored */
+
+ s = 1;
+ val = 0;
+
+ while ((c = getc (finput)) != EOF) {
+ if (iswdigit (c))
+ val = val * 10 + c - '0';
+ else if (c == '-')
+ s = -1;
+ else
+ break;
+ }
+ *optimmem++ = s * val;
+ if (optimmem >= &tracemem[new_memsize])
+ exp_mem (0);
+ return (c);
+}
+
+void
+exp_act (ptr)
+ int **ptr;
+{
+ static int *actbase;
+ int i;
+ new_actsize += ACTSIZE;
+
+ actbase = amem;
+ amem = (int *) realloc ((char *) amem, sizeof (int) * new_actsize);
+ if (amem == NULL)
+/*
+ * TRANSLATION_NOTE -- This is a message from yacc.
+ * This message is passed to error() function.
+ *
+ * You may just translate this as:
+ * 'Could not allocate internally used memory.'
+ */
+ error ("couldn't expand action table");
+
+ for (i = new_actsize - ACTSIZE; i < new_actsize; ++i)
+ amem[i] = 0;
+ if (ptr != NULL)
+ *ptr = *ptr - actbase + amem;
+ if (memp >= amem)
+ memp = memp - actbase + amem;
+ if (maxa >= amem)
+ maxa = maxa - actbase + amem;
+}
diff --git a/unix/boot/xyacc/yaccpar.x b/unix/boot/xyacc/yaccpar.x
new file mode 100644
index 00000000..71a323b4
--- /dev/null
+++ b/unix/boot/xyacc/yaccpar.x
@@ -0,0 +1,238 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+# Parser for yacc output, translated to the IRAF SPP language. The contents
+# of this file form the bulk of the source of the parser produced by Yacc.
+# Yacc recognizes several macros in the yaccpar input source and replaces
+# them as follows:
+# A user suppled "global" definitions and declarations
+# B parser tables
+# C user supplied actions (reductions)
+# The remainder of the yaccpar code is not changed.
+
+define yystack_ 10 # statement labels for gotos
+define yynewstate_ 20
+define yydefault_ 30
+define yyerrlab_ 40
+define yyabort_ 50
+
+define YYFLAG (-1000) # defs used in user actions
+define YYERROR goto yyerrlab_
+define YYACCEPT return (OK)
+define YYABORT return (ERR)
+
+
+# YYPARSE -- Parse the input stream, returning OK if the source is
+# syntactically acceptable (i.e., if compilation is successful),
+# otherwise ERR. The parameters YYMAXDEPTH and YYOPLEN must be
+# supplied by the caller in the %{ ... %} section of the Yacc source.
+# The token value stack is a dynamically allocated array of operand
+# structures, with the length and makeup of the operand structure being
+# application dependent.
+
+int procedure yyparse (fd, yydebug, yylex)
+
+int fd # stream to be parsed
+bool yydebug # print debugging information?
+int yylex() # user-supplied lexical input function
+extern yylex()
+
+short yys[YYMAXDEPTH] # parser stack -- stacks tokens
+pointer yyv # pointer to token value stack
+pointer yyval # value returned by action
+pointer yylval # value of token
+int yyps # token stack pointer
+pointer yypv # value stack pointer
+int yychar # current input token number
+int yyerrflag # error recovery flag
+int yynerrs # number of errors
+
+short yyj, yym # internal variables
+pointer yysp, yypvt
+short yystate, yyn
+int yyxi, i
+errchk salloc, yylex
+
+$A # User declarations go here.
+$B # YACC parser tables defining the finite automaton go here.
+
+begin
+ call smark (yysp)
+ call salloc (yyv, (YYMAXDEPTH+2) * YYOPLEN, TY_STRUCT)
+
+ # Initialization. The first element of the dynamically allocated
+ # token value stack (yyv) is used for yyval, the second for yylval,
+ # and the actual stack starts with the third element.
+
+ yystate = 0
+ yychar = -1
+ yynerrs = 0
+ yyerrflag = 0
+ yyps = 0
+ yyval = yyv
+ yylval = yyv + YYOPLEN
+ yypv = yylval
+
+yystack_
+ # SHIFT -- Put a state and value onto the stack. The token and
+ # value stacks are logically the same stack, implemented as two
+ # separate arrays.
+
+ if (yydebug) {
+ call printf ("state %d, char 0%o\n")
+ call pargs (yystate)
+ call pargi (yychar)
+ }
+ yyps = yyps + 1
+ yypv = yypv + YYOPLEN
+ if (yyps > YYMAXDEPTH) {
+ call sfree (yysp)
+ call eprintf ("yacc stack overflow\n")
+ return (ERR)
+ }
+ yys[yyps] = yystate
+ YYMOVE (yyval, yypv)
+
+yynewstate_
+ # Process the new state.
+ yyn = yypact[yystate+1]
+
+ if (yyn <= YYFLAG)
+ goto yydefault_ # simple state
+
+ # The variable "yychar" is the lookahead token.
+ if (yychar < 0) {
+ yychar = yylex (fd, yylval)
+ if (yychar < 0)
+ yychar = 0
+ }
+ yyn = yyn + yychar
+ if (yyn < 0 || yyn >= YYLAST)
+ goto yydefault_
+
+ yyn = yyact[yyn+1]
+ if (yychk[yyn+1] == yychar) { # valid shift
+ yychar = -1
+ YYMOVE (yylval, yyval)
+ yystate = yyn
+ if (yyerrflag > 0)
+ yyerrflag = yyerrflag - 1
+ goto yystack_
+ }
+
+yydefault_
+ # Default state action.
+
+ yyn = yydef[yystate+1]
+ if (yyn == -2) {
+ if (yychar < 0) {
+ yychar = yylex (fd, yylval)
+ if (yychar < 0)
+ yychar = 0
+ }
+
+ # Look through exception table.
+ yyxi = 1
+ while ((yyexca[yyxi] != (-1)) || (yyexca[yyxi+1] != yystate))
+ yyxi = yyxi + 2
+ for (yyxi=yyxi+2; yyexca[yyxi] >= 0; yyxi=yyxi+2) {
+ if (yyexca[yyxi] == yychar)
+ break
+ }
+
+ yyn = yyexca[yyxi+1]
+ if (yyn < 0) {
+ call sfree (yysp)
+ return (OK) # ACCEPT -- all done
+ }
+ }
+
+
+ # SYNTAX ERROR -- resume parsing if possible.
+
+ if (yyn == 0) {
+ switch (yyerrflag) {
+ case 0, 1, 2:
+ if (yyerrflag == 0) { # brand new error
+ call eprintf ("syntax error\n")
+yyerrlab_
+ yynerrs = yynerrs + 1
+ # fall through...
+ }
+
+ # case 1:
+ # case 2: incompletely recovered error ... try again
+ yyerrflag = 3
+
+ # Find a state where "error" is a legal shift action.
+ while (yyps >= 1) {
+ yyn = yypact[yys[yyps]+1] + YYERRCODE
+ if ((yyn >= 0) && (yyn < YYLAST) &&
+ (yychk[yyact[yyn+1]+1] == YYERRCODE)) {
+ # Simulate a shift of "error".
+ yystate = yyact[yyn+1]
+ goto yystack_
+ }
+ yyn = yypact[yys[yyps]+1]
+
+ # The current yyps has no shift on "error", pop stack.
+ if (yydebug) {
+ call printf ("error recovery pops state %d, ")
+ call pargs (yys[yyps])
+ call printf ("uncovers %d\n")
+ call pargs (yys[yyps-1])
+ }
+ yyps = yyps - 1
+ yypv = yypv - YYOPLEN
+ }
+
+ # ABORT -- There is no state on the stack with an error shift.
+yyabort_
+ call sfree (yysp)
+ return (ERR)
+
+
+ case 3: # No shift yet; clobber input char.
+
+ if (yydebug) {
+ call printf ("error recovery discards char %d\n")
+ call pargi (yychar)
+ }
+
+ if (yychar == 0)
+ goto yyabort_ # don't discard EOF, quit
+ yychar = -1
+ goto yynewstate_ # try again in the same state
+ }
+ }
+
+
+ # REDUCE -- Reduction by production yyn.
+
+ if (yydebug) {
+ call printf ("reduce %d\n")
+ call pargs (yyn)
+ }
+ yyps = yyps - yyr2[yyn+1]
+ yypvt = yypv
+ yypv = yypv - yyr2[yyn+1] * YYOPLEN
+ YYMOVE (yypv + YYOPLEN, yyval)
+ yym = yyn
+
+ # Consult goto table to find next state.
+ yyn = yyr1[yyn+1]
+ yyj = yypgo[yyn+1] + yys[yyps] + 1
+ if (yyj >= YYLAST)
+ yystate = yyact[yypgo[yyn+1]+1]
+ else {
+ yystate = yyact[yyj+1]
+ if (yychk[yystate+1] != -yyn)
+ yystate = yyact[yypgo[yyn+1]+1]
+ }
+
+ # Perform action associated with the grammar rule, if any.
+ switch (yym) {
+ $C # YACC replaces this line by the user supplied actions.
+ }
+
+ goto yystack_ # stack new state and value
+end