| 1 | /* Copyright (c) 1979 Regents of the University of California */ |
| 2 | # |
| 3 | /* |
| 4 | * pi - Pascal interpreter code translator |
| 5 | * |
| 6 | * Charles Haley, Bill Joy UCB |
| 7 | * Version 1.1 February 1978 |
| 8 | * |
| 9 | * |
| 10 | * pxp - Pascal execution profiler |
| 11 | * |
| 12 | * Bill Joy UCB |
| 13 | * Version 1.1 February 1978 |
| 14 | */ |
| 15 | |
| 16 | #include "y.tab.h" |
| 17 | /* |
| 18 | * INPUT/OUTPUT |
| 19 | */ |
| 20 | |
| 21 | /* |
| 22 | * The buffer for the input file is normally "ibuf". |
| 23 | * When files are included, however, this may be |
| 24 | * pushed down in the stack of currently active |
| 25 | * files. For this reason, the pointer ibp always |
| 26 | * references the i/o buffer of the current input file. |
| 27 | */ |
| 28 | FILE *ibuf, *ibp; |
| 29 | |
| 30 | /* |
| 31 | * Line and token buffers. Charbuf is the character buffer for |
| 32 | * input lines, token the buffer for tokens returned |
| 33 | * by the scanner. CBSIZE defines the maximum line |
| 34 | * length allowed on input and is doubtless too small. |
| 35 | * The token buffer should be a local array in yylex. |
| 36 | */ |
| 37 | #define CBSIZE 161 |
| 38 | |
| 39 | char charbuf[CBSIZE], *bufp, token[CBSIZE]; |
| 40 | |
| 41 | #define digit(c) (c >= '0' && c <= '9') |
| 42 | #define alph(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) |
| 43 | |
| 44 | /* |
| 45 | * Flag to prevent reprinting current line after |
| 46 | * an error. |
| 47 | */ |
| 48 | char yyprtd; |
| 49 | \f |
| 50 | /* |
| 51 | * The following variables are maintained by |
| 52 | * the scanner in the file lex and used in scanning |
| 53 | * and in parsing. |
| 54 | * |
| 55 | * The variable yychar is the current scanner character. |
| 56 | * Currently, the scanner must be called as |
| 57 | * yychar = yylex() |
| 58 | * even though it should set yychar itself. |
| 59 | * Yychar has value YEOF at end of file, and negative value if |
| 60 | * there is no yychar, e.g. after a shift in the parser. |
| 61 | * |
| 62 | * The variable yycol is the current column in the line whose number |
| 63 | * is given by yyline. Yyecol and yyeline give the position for an |
| 64 | * error message to flag, usually the start of an input token. |
| 65 | * Yylval is the semantic return from the scanner. |
| 66 | * |
| 67 | * In fact all of these variables are "per token". |
| 68 | * In the usual case, only the copies in the scanner token structure |
| 69 | * 'Y' are used, and the #defines below serve to make them look |
| 70 | * like variables. |
| 71 | * |
| 72 | * For the purposes of the error recovery, however, they are copied |
| 73 | * and restored quite freely. For the error recovery also, the |
| 74 | * file name which the input line this token is on and the seek |
| 75 | * pointer of this line in its source file are saved as yyefile |
| 76 | * and yyseekp. The global variable yylinpt is the seek pointer |
| 77 | * of the current input line. |
| 78 | */ |
| 79 | int yycol; |
| 80 | int yyline; |
| 81 | int yyseqid; |
| 82 | int yysavc; |
| 83 | int yylinpt; |
| 84 | |
| 85 | /* *** NOTE *** |
| 86 | * It would be much better to not have the Yyeline and Yyefile |
| 87 | * in the scanner structure and to have a mechanism for mapping |
| 88 | * seqid's to these globally. |
| 89 | */ |
| 90 | struct yytok { |
| 91 | int Yychar; |
| 92 | int Yylval; |
| 93 | int Yyecol; |
| 94 | int Yyeline; |
| 95 | int Yyseekp; |
| 96 | char *Yyefile; |
| 97 | int Yyeseqid; |
| 98 | } Y, OY; |
| 99 | |
| 100 | #define yychar Y.Yychar |
| 101 | #define yylval Y.Yylval |
| 102 | #define yyecol Y.Yyecol |
| 103 | #define yyeline Y.Yyeline |
| 104 | #define yyseekp Y.Yyseekp |
| 105 | #define yyefile Y.Yyefile |
| 106 | #define yyeseqid Y.Yyeseqid |
| 107 | |
| 108 | /* |
| 109 | * Yyval is the semantic value returned by a reduction. |
| 110 | * It is what "$$" is expanded to by yacc. |
| 111 | */ |
| 112 | int *Ps, *yyval; |
| 113 | |
| 114 | /* |
| 115 | * N is the length of a reduction. |
| 116 | * Used externally by "lineof" to get the left and |
| 117 | * right margins for a reduction. |
| 118 | */ |
| 119 | int N; |
| 120 | /* |
| 121 | * Definitions for looking up keywords. |
| 122 | * The keyword array is called yykey, and |
| 123 | * lastkey points at the end of it. |
| 124 | */ |
| 125 | char *lastkey; |
| 126 | |
| 127 | struct kwtab { |
| 128 | char *kw_str; |
| 129 | int kw_val; |
| 130 | } yykey[]; |
| 131 | \f |
| 132 | /* |
| 133 | * ERROR RECOVERY EXTERNALS |
| 134 | */ |
| 135 | |
| 136 | #define CLIMIT 40 /* see yyrecover.c */ |
| 137 | char *tokname(); |
| 138 | char *charname(); |
| 139 | |
| 140 | char *classes[]; |
| 141 | |
| 142 | /* |
| 143 | * Tokens which yacc doesn't define |
| 144 | */ |
| 145 | #define YEOF 0 |
| 146 | #define ERROR 256 |
| 147 | |
| 148 | /* |
| 149 | * Limit on the number of syntax errors |
| 150 | */ |
| 151 | #define MAXSYNERR 100 |
| 152 | |
| 153 | /* |
| 154 | * Big costs |
| 155 | */ |
| 156 | #define HUGE 50 |
| 157 | #define INFINITY 100 |
| 158 | |
| 159 | /* |
| 160 | * Kinds of panics |
| 161 | */ |
| 162 | #define PDECL 0 |
| 163 | #define PSTAT 1 |
| 164 | #define PEXPR 2 |
| 165 | #define PPROG 3 |
| 166 | |
| 167 | #define yyresume() yyResume = 1; |
| 168 | |
| 169 | char yyResume; |
| 170 | |
| 171 | char dquote; |
| 172 | |
| 173 | char errout; |
| 174 | |
| 175 | /* |
| 176 | * Yyidwant and yyidhave are the namelist classes |
| 177 | * of identifiers associated with a identifier reduce |
| 178 | * error, set before the recovery is called. |
| 179 | * Since they may be set again during the forward move |
| 180 | * they must be saved by yyrecover, which uses them in printing |
| 181 | * error messages. |
| 182 | */ |
| 183 | int yyidhave, yyidwant; |
| 184 | \f |
| 185 | /* |
| 186 | * The variables yy*shifts are used to prevent looping and the printing |
| 187 | * of spurious messages in the parser. Yyshifts gives the number of |
| 188 | * true input shifts since the last corrective action. YyOshifts |
| 189 | * is the value of yyshifts before it was last cleared, and is used |
| 190 | * by yyPerror in yypanic.c to suppress messages. |
| 191 | * |
| 192 | * Yytshifts counts true input shifts. It is used to prevent looping |
| 193 | * inserting unique symbols. If yytshifts == yyTshifts (local to |
| 194 | * yyrecover.c) then there has been no shift over true input since |
| 195 | * the last unique symbol insertion. We refuse, in this case, |
| 196 | * to insert more unique symbols so as to prevent looping. |
| 197 | * |
| 198 | * The recovery cannot loop because it guarantees the progress of the |
| 199 | * parse, i.e.: |
| 200 | * |
| 201 | * 1) Any insertion guarantees to shift over 2 symbols, a replacement |
| 202 | * over one symbol. |
| 203 | * |
| 204 | * 2) Unique symbol insertions are limited to one for each true |
| 205 | * symbol of input, or "safe" insertion of the keywords "end" |
| 206 | * and "until" at zero cost (safe since these are know to match |
| 207 | * stack that cannot have been generated - e.g. "begin" or "repeat") |
| 208 | * |
| 209 | * 3) We never panic more than once from a given state without |
| 210 | * shifting over input, i.e. we force the parse stack to shrink |
| 211 | * after each unsuccessful panic. |
| 212 | */ |
| 213 | int yyshifts, yyOshifts; |
| 214 | unsigned yytshifts; |
| 215 | |
| 216 | #ifdef PXP |
| 217 | \f |
| 218 | /* |
| 219 | * Identifier class definitions |
| 220 | */ |
| 221 | #define UNDEF 0 |
| 222 | #define CONST 1 |
| 223 | #define TYPE 2 |
| 224 | #define VAR 3 |
| 225 | #define ARRAY 4 |
| 226 | #define PTRFILE 5 |
| 227 | #define RECORD 6 |
| 228 | #define FIELD 7 |
| 229 | #define PROC 8 |
| 230 | #define FUNC 9 |
| 231 | #define FVAR 10 |
| 232 | #define REF 11 |
| 233 | #define PTR 12 |
| 234 | #define FILET 13 |
| 235 | #define SET 14 |
| 236 | #define RANGE 15 |
| 237 | #define LABEL 16 |
| 238 | #define WITHPTR 17 |
| 239 | #define SCAL 18 |
| 240 | #define STR 19 |
| 241 | #define PROG 20 |
| 242 | #define IMPROPER 21 |
| 243 | \f |
| 244 | /* |
| 245 | * COMMENT FORMATTING DEFINITIONS |
| 246 | */ |
| 247 | |
| 248 | /* |
| 249 | * Count of tokens on this input line |
| 250 | * Note that this can be off if input is not syntactically correct. |
| 251 | */ |
| 252 | int yytokcnt; |
| 253 | int yywhcnt; |
| 254 | |
| 255 | /* |
| 256 | * Types of comments |
| 257 | */ |
| 258 | #define CLMARG 0 |
| 259 | #define CALIGN 1 |
| 260 | #define CTRAIL 2 |
| 261 | #define CRMARG 3 |
| 262 | #define CSRMARG 4 |
| 263 | #define CNL 5 |
| 264 | #define CNLBL 6 |
| 265 | #define CFORM 7 |
| 266 | #define CINCLUD 8 |
| 267 | |
| 268 | /* |
| 269 | * Comment structure |
| 270 | * Cmhp is the head of the current list of comments |
| 271 | */ |
| 272 | struct comment { |
| 273 | struct comment *cmnext; |
| 274 | int cmdelim; |
| 275 | struct commline *cml; |
| 276 | int cmjust; |
| 277 | int cmseqid; |
| 278 | } *cmhp; |
| 279 | |
| 280 | /* |
| 281 | * Structure for holding a comment line |
| 282 | */ |
| 283 | struct commline { |
| 284 | char *cmtext; |
| 285 | int cmcol; /* Only used for first line of comment currently */ |
| 286 | struct commline *cml; |
| 287 | }; |
| 288 | |
| 289 | struct W { |
| 290 | int Wseqid; |
| 291 | int Wcol; |
| 292 | } yyw[MAXDEPTH + 1], *yypw; |
| 293 | |
| 294 | #define commform() quickcomm(CFORM) |
| 295 | #define commnl() quickcomm(CNL) |
| 296 | #define commnlbl() quickcomm(CNLBL) |
| 297 | #endif |