⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 attributes.cc

📁 PL/0源码
💻 CC
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////////  attributes.cc - Syntax tree attributes and stack functions.//#include "plzero.h"#include "inpbuf.h"#include <iomanip>#include <strstream>#include "attributes.h"#define PROD_STACK_SIZE 200//  Production stack.  Used to keep track of locations//  of attribute records for productions in progressstatic struct prod_stack_t {    attrib_stack_t *    lhsSave;    attrib_stack_t *    rhsSave;}                       ps [PROD_STACK_SIZE + 1];static attrib_stack_t   as[MAX_ATTR_STACK + 1];static prod_stack_t *   ps_top = &ps[0]; // highest used production stack entrystatic attrib_stack_t * as_top = &as[0]; // highest used attribute stack entryattrib_stack_t *        lhs = &as[0];attrib_stack_t *        rhs = &as[0];syntax_tree_t *         ast_root = NULL;//////////  Start a new production by first saving old values of lhs and rhs,//  updating as_top to make room for new right-hand side,//  and then updating lhs and rhs//void start_production(int length, int seen_so_far){    if (as_top + length > &as[MAX_ATTR_STACK])        die_compiler ("Attribute stack overflow.");    else if (ps_top + 1 > &ps[PROD_STACK_SIZE])        die_compiler ("Production stack overflow.");    else {        ps_top++;        ps_top->lhsSave = lhs;        ps_top->rhsSave = rhs;        lhs = rhs + seen_so_far;        rhs = as_top + 1;        as_top += length;    }}//////////  End a production by restoring the saved values for rhs and lhs,//  and using them to calculate the old values of as_top and seen_so_far.//void end_production(int& seen_so_far){    assert(as_top > &as[0]);        // attribute stack shouldn't be empty at end of production    assert(ps_top > &ps[0]);        // prediction stack shouldn't be empty at end of production    as_top = rhs - 1;    rhs = ps_top->rhsSave;    seen_so_far = lhs - rhs + 1;        // distance between finished child's lhs and parent's rhs,        // plus 1 for the symbol we just finished expanding    lhs = ps_top->lhsSave;    ps_top--;}//////////  Load synthetic attributes of token//void init_token(token_attrib_t attr, int seen_so_far){    (rhs+seen_so_far)->token = attr;}//////////  Utility routine to format a pointer as an 8-character zero-filled//  ascii string in hex.string p2h(void *p) {    ostrstream ost;    ost << hex << setfill('0') << setw(8) << (unsigned int)p;    return ost.str();}//////////////////////////////////////////////////////////////////////////////////  Dump syntax tree to ouput for debugging.////  Dump a node from the syntax tree.  If "recurse" is positive, then//  recursively dump any of the node's children.  "level" is used to indent//  the text.//void dump_syntax_tree(syntax_tree_t *node, int recurse/*=1*/, int level/*=0*/){    if (!node || recurse < 0)         // Drop if recurse counter expired.        return;    cout << p2h(node) << " ("        << setw(3) << node->get_location().get_lineno() << "."        << setw(2) << node->get_location().get_column() << ") ";    if (recurse < 1)                  // Expire non-recurse.        recurse--;    node->dump_object_data(recurse, level);}//////////  Dump a syntax tree node name to stdout.  Automatically indents to show//  the nested level of the node.//static void dump_name(char *name, int level){    int  len;    for (len = 0; len < level * 2; len++)        cout << " ";    cout << name;    for (len += strlen(name); len < 24; len++)        cout << " ";}//////////////////////////////////////////////////////////////////////////////////  Syntax Tree Members:////////////  syntax_tree_t: Abstract type for all syntax tree nodes.//syntax_tree_t::syntax_tree_t(location_t loc){    location = loc;    code_gen_info = NULL;}//////////  Return the location in the source file where the node was created.//location_t syntax_tree_t::get_location(void) const{    return location;}//////////  Dump the contents of the node to stdout for debugging.//void syntax_tree_t::dump_object_data(int recurse, int level) const{    UNUSED_PARAM(recurse);    dump_name("syntax_tree_t", level);}//////////  Destruct a syntax tree node.  Other nodes need more elaborate destructors.//syntax_tree_t::~syntax_tree_t(void){}//////////  Tokens://st_token_t::st_token_t(token_attrib_t attr)    : syntax_tree_t (attr.location){    attributes = attr;}void st_token_t::dump_object_data(int recurse, int level) const{    UNUSED_PARAM(recurse);    dump_name("token", level);    cout << setw(2) << (int)attributes.get_major() << "."        << setw(2) << (int)attributes.get_minor() << "\n";}token_attrib_t st_token_t::get_attributes(void) const{    return attributes;}st_token_t::~st_token_t(void){}//////////  Identifiers://st_identifier_t::st_identifier_t(token_attrib_t attr)    : st_token_t(attr){    symbol_entry = NULL;}void st_identifier_t::dump_object_data(int recurse, int level) const{    UNUSED_PARAM(recurse);    dump_name("identifier", level);    cout << setw(2) << (int)attributes.get_major() << "."        << setw(2) << (int)attributes.get_minor() << " \""        << attributes.get_text() << "\"\n";}//////////  Return a pointer to the symbol table entry for this identifier.//symbol_entry_t *st_identifier_t::get_symbol(void) const{    return symbol_entry;}st_identifier_t::~st_identifier_t(void){}//////////  Number Constants://st_number_t::st_number_t(token_attrib_t attr)        : st_token_t(attr){    value = 0;}//////////  Special constructor for adding number constants into the syntax tree.  This//  is used mosting in the constant optimization code in optimize.cc//st_number_t::st_number_t(token_attrib_t attr, int n_value)        : st_token_t(attr){    value = n_value;}void st_number_t::dump_object_data(int recurse, int level) const{    UNUSED_PARAM(recurse);    dump_name("number", level);    if (value) {        // we've already done the string-to-integer conversion        cout << setw(2) << (int)attributes.get_major() << "."            << setw(2) << (int)attributes.get_minor() << " "            << value << "\n";    }    else {        // we may not have done the string-to-integer conversion yet        cout << setw(2) << (int)attributes.get_major() << "."            << setw(2) << (int)attributes.get_minor() << " \""            << attributes.get_text() << "\"\n";    }}st_number_t::~st_number_t(void){}//////////  Operators://st_operator_t::st_operator_t(location_t loc, st_token_t *id)    : syntax_tree_t(loc){    op = id;}void st_operator_t::dump_object_data(int recurse, int level) const{    dump_name("operator", level);    cout << p2h(op) << "\n";    dump_syntax_tree(op, recurse, level+1);}st_operator_t::~st_operator_t(void){    if (op)        delete op;}//////////  Unary Operators://st_unary_op_t::st_unary_op_t(location_t loc, st_token_t *id,                             syntax_tree_t *opand)    : st_operator_t(loc, id){    operand = opand;}void st_unary_op_t::dump_object_data(int recurse, int level) const{    dump_name("unary_op", level);    cout << p2h(op) << p2h(operand) << "\n";    dump_syntax_tree(op, recurse, level+1);    dump_syntax_tree(operand, recurse, level+1);}st_unary_op_t::~st_unary_op_t(void){    if (operand)        delete operand;}//////////  Binary Operators://st_binary_op_t::st_binary_op_t(location_t loc, st_token_t *id,                               syntax_tree_t *lopand, syntax_tree_t *ropand)    : st_operator_t(loc, id){    left_operand = lopand;    right_operand = ropand;}void st_binary_op_t::dump_object_data(int recurse, int level) const{    dump_name("binary_op", level);    cout << p2h(op) << " " << p2h(left_operand) << " "        << p2h(right_operand) << "\n";    dump_syntax_tree(op, recurse, level+1);    dump_syntax_tree(left_operand, recurse, level+1);    dump_syntax_tree(right_operand, recurse, level+1);}st_binary_op_t::~st_binary_op_t(void){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -