|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)yytree.c 5.1 (Berkeley) 6/5/85"; ! 9: #endif not lint ! 10: ! 11: #include "whoami.h" ! 12: #include "0.h" ! 13: #include "tree.h" ! 14: #include "tree_ty.h" ! 15: ! 16: extern int *spacep; ! 17: ! 18: /* ! 19: * LIST MANIPULATION ROUTINES ! 20: * ! 21: * The grammar for Pascal is written left recursively. ! 22: * Because of this, the portions of parse trees which are to resemble ! 23: * lists are in the somewhat inconvenient position of having ! 24: * the nodes built from left to right, while we want to eventually ! 25: * have as semantic value the leftmost node. ! 26: * We could carry the leftmost node as semantic value, but this ! 27: * would be inefficient as to add a new node to the list we would ! 28: * have to chase down to the end. Other solutions involving a head ! 29: * and tail pointer waste space. ! 30: * ! 31: * The simple solution to this apparent dilemma is to carry along ! 32: * a pointer to the leftmost node in a list in the rightmost node ! 33: * which is the current semantic value of the list. ! 34: * When we have completed building the list, we can retrieve this ! 35: * left end pointer very easily; neither adding new elements to the list ! 36: * nor finding the left end is thus expensive. As the bottommost node ! 37: * has an unused next pointer in it, no space is wasted either. ! 38: * ! 39: * The nodes referred to here are of the T_LISTPP type and have ! 40: * the form: ! 41: * ! 42: * T_LISTPP some_pointer next_element ! 43: * ! 44: * Here some_pointer points to the things of interest in the list, ! 45: * and next_element to the next thing in the list except for the ! 46: * rightmost node, in which case it points to the leftmost node. ! 47: * The next_element of the rightmost node is of course zapped to the ! 48: * NIL pointer when the list is completed. ! 49: * ! 50: * Thinking of the lists as tree we heceforth refer to the leftmost ! 51: * node as the "top", and the rightmost node as the "bottom" or as ! 52: * the "virtual root". ! 53: */ ! 54: ! 55: /* ! 56: * Make a new list ! 57: */ ! 58: struct tnode * ! 59: newlist(new) ! 60: register struct tnode *new; ! 61: { ! 62: ! 63: if (new == TR_NIL) ! 64: return (TR_NIL); ! 65: return ((struct tnode *) tree3(T_LISTPP, (int) new, ! 66: (struct tnode *) spacep)); ! 67: } ! 68: ! 69: /* ! 70: * Add a new element to an existing list ! 71: */ ! 72: struct tnode * ! 73: addlist(vroot, new) ! 74: register struct tnode *vroot; ! 75: struct tnode *new; ! 76: { ! 77: register struct tnode *top; ! 78: ! 79: if (new == TR_NIL) ! 80: return (vroot); ! 81: if (vroot == TR_NIL) ! 82: return (newlist(new)); ! 83: top = vroot->list_node.next; ! 84: vroot->list_node.next = (struct tnode *) spacep; ! 85: return ((struct tnode *) tree3(T_LISTPP, (int) new, top)); ! 86: } ! 87: ! 88: /* ! 89: * Fix up the list which has virtual root vroot. ! 90: * We grab the top pointer and return it, zapping the spot ! 91: * where it was so that the tree is not circular. ! 92: */ ! 93: struct tnode * ! 94: fixlist(vroot) ! 95: register struct tnode *vroot; ! 96: { ! 97: register struct tnode *top; ! 98: ! 99: if (vroot == TR_NIL) ! 100: return (TR_NIL); ! 101: top = vroot->list_node.next; ! 102: vroot->list_node.next = TR_NIL; ! 103: return (top); ! 104: } ! 105: ! 106: ! 107: /* ! 108: * Set up a T_VAR node for a qualified variable. ! 109: * Init is the initial entry in the qualification, ! 110: * or NIL if there is none. ! 111: * ! 112: * if we are building pTrees, there has to be an extra slot for ! 113: * a pointer to the namelist entry of a field, if this T_VAR refers ! 114: * to a field name within a WITH statement. ! 115: * this extra field is set in lvalue, and used in VarCopy. ! 116: */ ! 117: struct tnode * ! 118: setupvar(var, init) ! 119: char *var; ! 120: register struct tnode *init; ! 121: { ! 122: ! 123: if (init != TR_NIL) ! 124: init = newlist(init); ! 125: # ifndef PTREE ! 126: return (tree4(T_VAR, NOCON, (struct tnode *) var, init)); ! 127: # else ! 128: return tree5( T_VAR, NOCON, (struct tnode *) var, init, TR_NIL ); ! 129: # endif ! 130: } ! 131: ! 132: /* ! 133: * set up a T_TYREC node for a record ! 134: * ! 135: * if we are building pTrees, there has to be an extra slot for ! 136: * a pointer to the namelist entry of the record. ! 137: * this extra field is filled in in gtype, and used in RecTCopy. ! 138: */ ! 139: struct tnode * ! 140: setuptyrec( line , fldlist ) ! 141: int line; ! 142: struct tnode *fldlist; ! 143: { ! 144: ! 145: # ifndef PTREE ! 146: return tree3( T_TYREC , line , fldlist ); ! 147: # else ! 148: return tree4( T_TYREC , line , fldlst , TR_NIL ); ! 149: # endif ! 150: } ! 151: ! 152: /* ! 153: * set up a T_FIELD node for a field. ! 154: * ! 155: * if we are building pTrees, there has to be an extra slot for ! 156: * a pointer to the namelist entry of the field. ! 157: * this extra field is set in lvalue, and used in SelCopy. ! 158: */ ! 159: struct tnode * ! 160: setupfield( field , other ) ! 161: struct tnode *field; ! 162: struct tnode *other; ! 163: { ! 164: ! 165: # ifndef PTREE ! 166: return tree3( T_FIELD , (int) field , other ); ! 167: # else ! 168: return tree4( T_FIELD , (int) field , other , TR_NIL ); ! 169: # endif ! 170: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.