📄 tabutil.c
字号:
field(naction_symbols_range[i], 4); k++; if (k == 18) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); k = 0; } } if (k != 0) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); } /*************************************************************/ /* Compute and list space required for NACTION_SYMBOLS map. */ /*************************************************************/ num_bytes = 2 * (num_states + offset); if (byte_bit) { if (offset <= 255) num_bytes -= (num_states + 1); if (((table_opt == OPTIMIZE_TIME) && (last_non_terminal <= 255)) || ((table_opt != OPTIMIZE_TIME) && (num_non_terminals <= 255))) num_bytes -= (offset - 1); } sprintf(msg_line, " Storage required for NACTION_SYMBOLS map: " "%ld Bytes", num_bytes); PRNT(msg_line); ffree(naction_symbols_range); /***********************************************************************/ /* Compute map from each symbol to state into which that symbol can */ /* cause a transition: TRANSITION_STATES */ /* TRANSITION_STATES is also written as two vectors like the FOLLOW */ /* map and the ACTION_DOMAIN map. */ /* The first vector contains the starting location in the second */ /* vector for each symbol. */ /* Construct the TRANSITION_STATES map using an array SYMBOL_ROOT */ /* (indexable by each symbol) whose elements are the root of a linked */ /* stack built in STATE_STACK. Another array SYMBOL_COUNT is used to */ /* keep count of the number of states associated with each symbol. */ /* For space tables, the TRANSITION_STATES map is written as two */ /* separate tables: SHIFT_STATES and GOTO_STATES. */ /***********************************************************************/ for ALL_SYMBOLS(symbol) { symbol_root[symbol] = NIL; symbol_count[symbol] = 0; } for (state_no = 2; state_no <= (int) num_states; state_no++) { struct node *q; q = statset[state_no].kernel_items; if (q == NULL) /* is the state a single production state? */ { q = statset[state_no].complete_items; /* pick arbitrary item */ } item_no = q -> value - 1; i = item_table[item_no].symbol; symbol = symbol_map[i]; state_stack[state_no] = symbol_root[symbol]; symbol_root[symbol] = state_no; symbol_count[symbol]++; } /***************************************************************************/ /* We now compute and write the starting location for each terminal symbol */ /***************************************************************************/ offset = 1; /* Offset of the first state */ field(offset, 6); k = 1; for (symbol = 1; symbol <= terminal_ubound; symbol++) { offset += symbol_count[symbol]; field(offset, 6); k++; if (k == 12) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); k = 0; } } if (k != 0) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); } /*********************************************************************/ /* We now write out the range elements of SHIFT_STATES for space */ /* tables or TRANSITION_STATES for time tables. */ /*********************************************************************/ k = 0; for (symbol = 1; symbol <= terminal_ubound; symbol++) { for (state_no = symbol_root[symbol]; state_no != NIL; state_no = state_stack[state_no]) { field(state_index[state_no] + num_rules, 6); k++; if (k == 12) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); k = 0; } } } if (k != 0) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); } /*********************************************************************/ /* If space tables are requested we compute and list space required */ /* for SHIFT_STATES map. The base vector contains NUM_TERMINALS+ 1 */ /* elements, and the vector containing the range elements has size */ /* OFFSET - 1. If time tables are requested we compute and list space*/ /* requirements for TRANSITION_STATES map. The base vector has */ /* NUM_SYMBOLS + 1 elements, and the range elements vector contains */ /* OFFSET - 1 elements. */ /*********************************************************************/ if (table_opt == OPTIMIZE_TIME) { num_bytes = 2 * (num_symbols + offset); sprintf(msg_line, " Storage required for TRANSITION_STATES map: %d Bytes", num_bytes); PRNT(msg_line); } else { num_bytes = 2 * (num_terminals + offset); sprintf(msg_line, " Storage required for SHIFT_STATES map: %d Bytes", num_bytes); PRNT(msg_line); /************************************************************/ /* We now compute and write the starting location for each */ /* non-terminal symbol... */ /************************************************************/ offset = 1; field(offset, 6); /* Offset of the first state */ k = 1; for ALL_NON_TERMINALS(symbol) { offset += symbol_count[symbol]; field(offset, 6); k++; if (k == 12) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); k = 0; } } if (k != 0) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); } /*********************************************************************/ /* We now write out the range elements of GOTO_STATES whose domain */ /* is a non-terminal symbol. */ /*********************************************************************/ k = 0; for ALL_NON_TERMINALS(symbol) { for (state_no = symbol_root[symbol]; state_no != NIL; state_no = state_stack[state_no]) { field(state_index[state_no] + num_rules, 6); k++; if (k == 12) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); k = 0; } } } if (k != 0) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); } /*********************************************************************/ /* We compute and list space required for GOTO_STATES map. The */ /* base vector contains NUM_NON_TERMINALS+ 1 elements, and the vector*/ /* containing the range elements has size OFFSET - 1 */ /*********************************************************************/ num_bytes = 2 * (num_non_terminals + offset); sprintf(msg_line," Storage required for GOTO_STATES map: %d Bytes", num_bytes); PRNT(msg_line); } /*********************************************************************/ /* Write the number associated with the ERROR symbol. */ /*********************************************************************/ field(error_image, 4); field(eolt_image, 4); field(num_names, 4); field(num_scopes, 4); field(scope_rhs_size, 4); field(scope_state_size, 4); if (table_opt == OPTIMIZE_SPACE) field(num_error_rules, 4); *output_ptr++ = '\n'; BUFFER_CHECK(systab); /*********************************************************************/ /* We write out the names map. */ /*********************************************************************/ num_bytes = 0; max_len = 0; for (i = 1; i <= num_names; i++) { int name_len; strcpy(tok, RETRIEVE_NAME(i)); if (tok[0] == '\n') /* we're dealing with special symbol? */ tok[0] = escape; /* replace initial marker with escape. */ name_len = strlen(tok); num_bytes += name_len; if (max_len < name_len) max_len = name_len; field(name_len, 4); if (name_len <= 68) strcpy(output_ptr, tok); else { memcpy(output_ptr, tok, 68); output_ptr+= 68; *output_ptr++ = '\n'; BUFFER_CHECK(systab);; strcpy(tok, tok+68); for (name_len = strlen(tok); name_len > 72; name_len = strlen(tok)) { memcpy(output_ptr, tok, 72); output_ptr+= 72; *output_ptr++ = '\n'; BUFFER_CHECK(systab); strcpy(tok, tok+72); } memcpy(output_ptr, tok, name_len); } output_ptr += name_len; *output_ptr++ = '\n'; BUFFER_CHECK(systab); } /*********************************************************************/ /* We write the name_index of each terminal symbol. The array TEMP */ /* is used to remap the NAME_INDEX values based on the new symbol */ /* numberings. If time tables are requested, the terminals and non- */ /* terminals are mixed together. */ /*********************************************************************/ temp = Allocate_short_array(num_symbols + 1); if (table_opt == OPTIMIZE_TIME) { for ALL_SYMBOLS(symbol) temp[symbol_map[symbol]] = symno[symbol].name_index; k = 0; for ALL_SYMBOLS(symbol) { field(temp[symbol], 4); k++; if (k == 18) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); k = 0; } } if (k != 0) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); } } else { for ALL_TERMINALS(symbol) temp[symbol_map[symbol]] = symno[symbol].name_index; k = 0; for ALL_TERMINALS(symbol) { field(temp[symbol], 4); k++; if (k == 18) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); k = 0; } } if (k != 0) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); } /****************************************************************/ /* We write the name_index of each non_terminal symbol. The */ /* array TEMP is used to remap the NAME_INDEX values based on */ /* the new symbol numberings. */ /****************************************************************/ for ALL_NON_TERMINALS(symbol) temp[symbol_map[symbol]] = symno[symbol].name_index; k = 0; for ALL_NON_TERMINALS(symbol) { field(temp[symbol], 4); k++; if (k == 18) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); k = 0; } } if (k != 0) { *output_ptr++ = '\n'; BUFFER_CHECK(systab); } } /*****************************************************/ /* Compute and list space requirements for NAME map. */ /*****************************************************/ if (max_len > 255) offset = 2 * num_symbols; else offset = num_symbols; if (num_bytes > 255) offset += (2 * num_symbols); else offset += num_symbols; sprintf(msg_line, " Storage required for direct NAME map: %d Bytes", num_bytes + offset); PRNT(msg_line); if (max_len > 255) offset = 2 * num_names; else offset = num_names; if (num_bytes > 255) offset += (2 * num_names); else offset += num_names; if (num_names > 255) offset += (2 * num_symbols); else offset += num_symbols; sprintf(msg_line, " Storage required for indirect NAME map: %d Bytes", num_bytes + offset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -