Copyright Joey Paquet, Lecture 9 Table-Driven Syntax-Directed Translation (Top-Down and Bottom-Up)
Copyright Joey Paquet, Part I Top-Down Table-Driven Syntax-Directed Translation
Copyright Joey Paquet, Top-Down Table-Driven SDT Augment the parser algorithm to implement attribute migration Problem: the attributes have to be pushed and popped at a different pace compared to symbols on the stack Solution: use an additional stack (the semantic stack) to store the attributes
Copyright Joey Paquet, Top-Down Table-Driven SDT Insert example slides here
Copyright Joey Paquet, Part II Bottom-Up Table-Driven Syntax-Directed Translation
Copyright Joey Paquet, Bottom-Up SDT Syntax-directed translation is much easier to implement bottom-up than top-down. Synthetized attributes are propagated from the bottom-up, so we have this propagation mechanism for free in a bottom-up parse The presence of inherited attributes generally comes from the elimination of left-recursions and ambiguities. As these are not a problem in bottom-up parsing, we seldom need to process inherited attributes in bottom-up translation In bottom-up translation, the parse and semantic stacks move in synchronism. Semantic rules are triggered as handles are popped from the stack
Copyright Joey Paquet, Bottom-Up SDT The tree is built by grafting subtrees (handles) to the nodes The semantic actions build the subtrees and for the grafts generally through simple pointer manipulations Generally, all nodes (internal or leaves) are of the same type. Differences can be managed by using a variant record structure: nodeKind = (internal,leaf) treeNode = record token : tokenType case kind : nodeKind of internal : (left,right : *treeNode) leaf : (location : integer) end
Copyright Joey Paquet, Bottom-Up SDT Tree nodes may also contain a pointer to a linked list of instruction (e.g. 3AC or ASM) that will be filled later in the code generation (translation) phase. Such a representation enables high-level code optimization To manage the creating of the tree, the frames on the stack need to incorporate tree structures: symbolType = (nonTerm,term) frame = record case symbolType of nonTerm : (root : *nodePtr) term : (loc : integer) end
Copyright Joey Paquet, Bottom-Up SDT We need a makeTree function that will be used to create subtrees and a makeLeaf function that will be used to create tree leaves: nodePtr makeTree(op tokenType, rightSon,leftSon nodePtr{ nodePtr = new(nodePtr) rootPtr.kind = internal rootPtr.token = op rootPtr.left = leftSon rootPtr.right = rightSon return rootPtr}
Copyright Joey Paquet, Bottom-Up SDT nodePtr makeLeaf(tok tokenType, location integer{ rootPtr = new(nodePtr) leafPtr.kind = leaf leafPtr.token = tok leafPtr.location = location return leafPtr}
Copyright Joey Paquet, Bottom-Up SDT: Example Insert example slides here
Copyright Joey Paquet, Bottom-Up SDT We can use a similar process to build other kinds of intermediate representations A similar process can also be used to generate target code directly, but that diminishes the possibilities of high-level code optimization