diff options
Diffstat (limited to 'unix/boot/xyacc')
-rw-r--r-- | unix/boot/xyacc/Makefile | 21 | ||||
-rw-r--r-- | unix/boot/xyacc/README | 117 | ||||
-rw-r--r-- | unix/boot/xyacc/debug/dc.y | 306 | ||||
-rw-r--r-- | unix/boot/xyacc/debug/y.output | 331 | ||||
-rw-r--r-- | unix/boot/xyacc/debug/ytab.x | 645 | ||||
-rw-r--r-- | unix/boot/xyacc/dextern.h | 382 | ||||
-rw-r--r-- | unix/boot/xyacc/mkpkg.sh | 7 | ||||
-rw-r--r-- | unix/boot/xyacc/y1.c | 1307 | ||||
-rw-r--r-- | unix/boot/xyacc/y2.c | 1952 | ||||
-rw-r--r-- | unix/boot/xyacc/y3.c | 606 | ||||
-rw-r--r-- | unix/boot/xyacc/y4.c | 528 | ||||
-rw-r--r-- | unix/boot/xyacc/yaccpar.x | 238 |
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 |