|
|
1.1.1.2 ! root 1: /* $Header: /cvsroot/src/sys/netiso/xebec/llparse.c,v 1.1 1993/04/09 12:02:06 cgd Exp $ */ ! 2: /* $Source: /cvsroot/src/sys/netiso/xebec/llparse.c,v $ */ 1.1 root 3: /* 4: * ************************* NOTICE ******************************* 5: * This code is in the public domain. It cannot be copyrighted. 6: * This ll parser was originally written by Keith Thompson for the 7: * University of Wisconsin Crystal project. 8: * It was based on an FMQ lr parser written by Jon Mauney at the 9: * University of Wisconsin. 10: * It was subsequently modified very slightly by Nancy Hall at the 11: * University of Wisconsin for the Crystal project. 12: * **************************************************************** 13: */ 14: #include "xebec.h" 15: #include "llparse.h" 16: #include "main.h" 17: #include <stdio.h> 18: 19: #include "debug.h" 20: 21: #define LLMINACTION -LLINF 22: 23: short llparsestack[STACKSIZE]; 24: short llstackptr = 0; 25: LLtoken lltoken; 26: 27: llparse() 28: { 29: register havetoken = FALSE; 30: register sym; 31: register LLtoken *t = &lltoken; 32: register parseaction; 33: register accepted = FALSE; 34: 35: llpushprod(llnprods-1); /* $$$ ::= <start symbol> */ 36: 37: do { 38: sym = llparsestack[llstackptr]; 39: IFDEBUG(L) 40: printf("llparse() top of loop, llstackptr=%d, sym=%d\n", 41: llstackptr, sym); 42: ENDDEBUG 43: 44: if(sym < 0) { 45: /* action symbol */ 46: if(sym <= LLMINACTION) { 47: for(;sym<=LLMINACTION;sym++) { 48: llaction(1, t); /* calls llfinprod */ 49: } 50: llstackptr--; 51: continue; 52: } else { llaction(-sym, t); 53: llstackptr--; 54: continue; 55: } 56: } 57: 58: if(sym < llnterms) { 59: 60: /* it's a terminal symbol */ 61: 62: if(!havetoken) { 63: llgettoken(t); 64: havetoken = TRUE; 65: } 66: 67: if(sym == t->llterm) { 68: llpushattr(t->llattrib); 69: llaccept(t); 70: llstackptr--; /* pop terminal */ 71: if(t->llterm == llnterms-1) { /* end symbol $$$ */ 72: accepted = TRUE; 73: } else { 74: havetoken = FALSE; 75: } 76: } else { 77: llparsererror(t); /* wrong terminal on input */ 78: havetoken = FALSE; 79: } 80: continue; 81: } 82: 83: /* non terminal */ 84: 85: if(!havetoken) { 86: llgettoken(t); 87: havetoken = TRUE; 88: } 89: 90: /* consult parse table for new production */ 91: parseaction = llfindaction(sym, t->llterm); 92: 93: if(parseaction == 0) { 94: /* error entry */ 95: llparsererror(t); 96: havetoken = FALSE; 97: continue; 98: } 99: 100: if(llepsilon[parseaction]) { 101: /* epsilon production */ 102: if(llepsilonok(t->llterm)) { 103: llstackptr--; /* pop nonterminal */ 104: llpushprod(parseaction); /* push rhs of production */ 105: } else { 106: llparsererror(t); 107: havetoken = FALSE; 108: } 109: } else { 110: llstackptr--; /* pop nonterminal */ 111: llpushprod(parseaction); /* push rhs of production */ 112: } 113: } while(!accepted); 114: 115: return(0); 116: } 117: 118: llpushprod(prod) /* recognize production prod - push rhs on stack */ 119: short prod; 120: { 121: register start; 122: register length; 123: register count; 124: 125: start = llprodindex[prod].llprodstart; 126: length = llprodindex[prod].llprodlength; 127: 128: IFDEBUG(L) 129: printf("llpushprod(%d) llstackptr=0x%x(%d), length = 0x%x(%d)\n", 130: prod, llstackptr, llstackptr, length , length); 131: /* 132: dump_parse_stack(); 133: */ 134: ENDDEBUG 135: if(llstackptr+length >= STACKSIZE) { 136: fprintf(stderr,"Parse stack overflow. llstackptr=0x%x, length=0x%x\n", 137: llstackptr, length); 138: Exit(-1); 139: } 140: 141: 142: llsetattr(llprodindex[prod].llprodtlen); 143: 144: /* put a marker on the stack to mark beginning of production */ 145: if(llparsestack[llstackptr] <= LLMINACTION) { 146: (llparsestack[llstackptr]) --; /* if there's already one there, don't 147: put another on; just let it represent all of 148: the adjacent markers */ 149: } 150: else { 151: llstackptr++; 152: llparsestack[llstackptr] = LLMINACTION; 153: } 154: 155: for(count=0; count<length; count++) { 156: llstackptr++; 157: llparsestack[llstackptr] = llproductions[start++]; 158: } 159: if(llstackptr > STACKSIZE) { 160: fprintf(stderr, "PARSE STACK OVERFLOW! \n"); Exit(-1); 161: Exit(-1); 162: } 163: } 164: 165: 166: llepsilonok(term) 167: { 168: register ptr; 169: register sym; 170: register pact; 171: register nomore; 172: register rval; 173: 174: IFDEBUG(L) 175: printf("llepsilonok() enter\n"); 176: ENDDEBUG 177: rval = TRUE; 178: 179: ptr = llstackptr; 180: 181: do { 182: sym = llparsestack[ptr]; 183: 184: if(sym < 0) { 185: ptr--; 186: nomore = ptr == 0; 187: continue; 188: } 189: 190: if(sym < llnterms) { 191: nomore = TRUE; 192: rval = sym == term; 193: continue; 194: } 195: 196: pact = llfindaction(sym, term); 197: 198: if(pact == 0) { 199: nomore = TRUE; 200: rval = FALSE; 201: continue; 202: } 203: 204: if(llepsilon[pact] == TRUE) { 205: ptr--; 206: nomore = ptr == 0; 207: } 208: else { 209: nomore = TRUE; 210: } 211: 212: } while(!nomore); 213: 214: return(rval); 215: } 216: 217: 218: short llfindaction(sym, term) 219: { 220: register index; 221: 222: IFDEBUG(L) 223: printf("llfindaction(sym=%d, term=%d) enter \n", sym, term); 224: ENDDEBUG 225: index = llparseindex[sym]; 226: 227: while(llparsetable[index].llterm != 0) { 228: if(llparsetable[index].llterm == term) { 229: return(llparsetable[index].llprod); 230: } 231: index++; 232: } 233: return(0); 234: } 235: 236: 237: llparsererror(token) 238: LLtoken *token; 239: { 240: IFDEBUG(L) 241: fprintf(stderr,"llparsererror() enter\n"); 242: prt_token(token); 243: ENDDEBUG 244: 245: fprintf(stderr, "Syntax error: "); 246: prt_token(token); 247: dump_buffer(); 248: Exit(-1); 249: } 250: 251: 252: llgettoken(token) 253: LLtoken *token; 254: { 255: llscan(token); 256: token->llstate = NORMAL; 257: IFDEBUG(L) 258: printf("llgettoken(): "); 259: prt_token(token); 260: ENDDEBUG 261: } 262: 263: 264: /****************************************************************************** 265: 266: Attribute support routines 267: 268: ******************************************************************************/ 269: /* 270: ** attribute stack 271: ** 272: ** AttrStack = stack of record 273: ** values : array of values; 274: ** ptr : index; 275: ** end; 276: ** 277: */ 278: 279: LLattrib llattributes[LLMAXATTR]; 280: int llattrtop = 0; 281: 282: struct llattr llattrdesc[LLMAXDESC]; 283: 284: int lldescindex = 1; 285: 286: 287: llsetattr(n) 288: { 289: register struct llattr *ptr; 290: 291: IFDEBUG(L) 292: printf("llsetattr(%d) enter\n",n); 293: ENDDEBUG 294: if(lldescindex >= LLMAXDESC) { 295: fprintf(stdout, "llattribute stack overflow: desc\n"); 296: fprintf(stdout, 297: "lldescindex=0x%x, llattrtop=0x%x\n",lldescindex, llattrtop); 298: Exit(-1); 299: } 300: ptr = &llattrdesc[lldescindex]; 301: ptr->llabase = &llattributes[llattrtop]; 302: ptr->lloldtop = ++llattrtop; 303: ptr->llaindex = 1; 304: ptr->llacnt = n+1; /* the lhs ALWAYS uses an attr; it remains on the 305: stack when the production is recognized */ 306: lldescindex++; 307: } 308: 309: llpushattr(attr) 310: LLattrib attr; 311: { 312: struct llattr *a; 313: 314: IFDEBUG(L) 315: printf("llpushattr() enter\n"); 316: ENDDEBUG 317: if(llattrtop + 1 > LLMAXATTR) { 318: fprintf(stderr, "ATTRIBUTE STACK OVERFLOW!\n"); 319: Exit(-1); 320: } 321: a = &llattrdesc[lldescindex-1]; 322: llattributes[llattrtop++] = attr; 323: a->llaindex++; /* inc count of attrs on the stack for this prod */ 324: } 325: 326: llfinprod() 327: { 328: IFDEBUG(L) 329: printf("llfinprod() enter\n"); 330: ENDDEBUG 331: lldescindex--; 332: llattrtop = llattrdesc[lldescindex].lloldtop; 333: llattrdesc[lldescindex-1].llaindex++; /* lhs-of-prod.attr stays on 334: the stack; it is now one of the rhs attrs of the now-top production 335: on the stack */ 336: } 337: 338: #ifndef LINT 339: #ifdef DEBUG 340: dump_parse_stack() 341: { 342: int ind; 343: 344: printf("PARSE STACK:\n"); 345: for(ind=llstackptr; ind>=0; ind--) { 346: printf("%d\t%d\t%s\n", 347: ind, llparsestack[ind], 348: llparsestack[ind]<0? "Action symbol" : llstrings[llparsestack[ind]]); 349: } 350: } 351: 352: #endif DEBUG 353: #endif LINT 354: 355: prt_token(t) 356: LLtoken *t; 357: { 358: fprintf(stdout, "t at 0x%x\n", t); 359: fprintf(stdout, "t->llterm=0x%x\n", t->llterm); (void) fflush(stdout); 360: fprintf(stdout, "TOK: %s\n", llstrings[t->llterm]); 361: (void) fflush(stdout); 362: #ifdef LINT 363: /* to make lint shut up */ 364: fprintf(stdout, "", llnterms, llnsyms, llnprods, llinfinite); 365: #endif LINT 366: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.