📄 lpgutil.c
字号:
len = PRINT_LINE_SIZE - 5; print_large_token(line, tok, "", len); strcat(line, " ::= "); i = (PRINT_LINE_SIZE / 2) - 1; offset = MIN(strlen(line)-1, i); len = PRINT_LINE_SIZE - (offset + 4); i = rules[rule_no].rhs; /* symbols before dot */ k = ((rules[rule_no].rhs + item_table[item_no].dot) - 1); for (; i <= k; i++) { symbol = rhs_sym[i]; restore_symbol(tok, RETRIEVE_STRING(symbol)); if (strlen(tok) + strlen(line) > PRINT_LINE_SIZE - 4) { fprintf(syslis,"\n%s", line); ENDPAGE_CHECK; fill_in(tempstr, offset, SPACE); print_large_token(line, tok, tempstr, len); } else strcat(line, tok); strcat(line, BLANK); } /*********************************************************************/ /* We now add a DOT "." to the output line and print the remaining */ /* symbols in the right hand side. If ITEM_NO is a complete item, */ /* we also print the rule number. */ /*********************************************************************/ if (item_table[item_no].dot == 0 || item_table[item_no].symbol == empty) strcpy(tok, "."); else strcpy(tok, " ."); strcat(line, tok); len = PRINT_LINE_SIZE - (offset + 1); for (i = rules[rule_no].rhs + item_table[item_no].dot;/* symbols after dot*/ i <= rules[rule_no + 1].rhs - 1; i++) { symbol = rhs_sym[i]; restore_symbol(tok, RETRIEVE_STRING(symbol)); if (strlen(tok) + strlen(line) > PRINT_LINE_SIZE -1) { fprintf(syslis, "\n%s", line); ENDPAGE_CHECK; fill_in(tempstr, offset, SPACE); print_large_token(line, tok, tempstr, len); } else strcat(line, tok); strcat(line, BLANK); } if (item_table[item_no].symbol == empty) /* complete item */ { sprintf(tok, " (%d)", rule_no); if (strlen(tok) + strlen(line) > PRINT_LINE_SIZE - 1) { fprintf(syslis, "\n%s", line); ENDPAGE_CHECK; fill_in(line,offset, SPACE); } strcat(line,tok); } fprintf(syslis, "\n%s", line); ENDPAGE_CHECK; return;}/*****************************************************************************//* PRINT_STATE: *//*****************************************************************************//* PRINT_STATE prints all the items in a state. NOTE that when single *//* productions are eliminated, certain items that were added in a state by *//* CLOSURE, will no longer show up in the output. Example: If we have the *//* item [A ::= .B] in a state, and the GOTO_REDUCE generated on B has been *//* replaced by say the GOTO or GOTO_REDUCE of A, the item above can no longer*//* be retrieved, since transitions in a given state are reconstructed from *//* the KERNEL and ADEQUATE items of the actions in the GOTO and SHIFT maps. *//*****************************************************************************/void print_state(int state_no){ struct shift_header_type sh; struct goto_header_type go_to; short *item_list; int kernel_size, i, n, item_no, next_state; BOOLEAN end_node, *state_seen, *item_seen; struct node *q; char buffer[PRINT_LINE_SIZE + 1], line[PRINT_LINE_SIZE + 1]; /*********************************************************************/ /* ITEM_SEEN is used to construct sets of items, to help avoid */ /* adding duplicates in a list. Duplicates can occur because an */ /* item from the kernel set will either be shifted on if it is not a */ /* complete item, or it will be a member of the Complete_items set. */ /* Duplicates can also occur because of the elimination of single */ /* productions. */ /*********************************************************************/ state_seen = Allocate_boolean_array(max_la_state + 1); item_seen = Allocate_boolean_array(num_items + 1); item_list = Allocate_short_array(num_items + 1);/* INITIALIZATION -----------------------------------------------------------*/ for ALL_STATES(i) state_seen[i] = FALSE; for ALL_ITEMS(i) item_seen[i] = FALSE; kernel_size = 0;/* END OF INITIALIZATION ----------------------------------------------------*/ i = number_len(state_no) + 8; /* 8 = length("STATE") + 2 spaces + newline*/ fill_in(buffer, (PRINT_LINE_SIZE - i) ,'-'); fprintf(syslis, "\n\n\nSTATE %d %s",state_no, buffer); output_line_no +=3; /*********************************************************************/ /* Print the set of states that have transitions to STATE_NO. */ /*********************************************************************/ n = 0; strcpy(line, "( "); for (end_node = ((q = in_stat[state_no]) == NULL); ! end_node; end_node = (q == in_stat[state_no])) {/* copy list of IN_STAT into array */ q = q -> next; if (! state_seen[q -> value]) { state_seen[q -> value] = TRUE; if (strlen(line) + number_len(q -> value) > PRINT_LINE_SIZE-2) { fprintf(syslis,"\n%s",line); ENDPAGE_CHECK; strcpy(line, " "); } if (q -> value != 0) { sprintf(buffer, "%d ", q -> value); strcat(line, buffer); } } } strcat(line, ")"); fprintf(syslis,"\n%s\n", line); output_line_no++; ENDPAGE_CHECK; /*********************************************************************/ /* Add the set of kernel items to the array ITEM_LIST, and mark all */ /* items seen to avoid duplicates. */ /*********************************************************************/ for (q = statset[state_no].kernel_items; q != NULL; q = q -> next) { kernel_size++; item_no = q -> value; item_list[kernel_size] = item_no; /* add to array */ item_seen[item_no] = TRUE; /* Mark as "seen" */ } /*********************************************************************/ /* Add the Complete Items to the array ITEM_LIST, and mark used. */ /*********************************************************************/ n = kernel_size; for (q = statset[state_no].complete_items; q != NULL; q = q -> next) { item_no = q -> value; if (! item_seen[item_no]) { item_seen[item_no] = TRUE; /* Mark as "seen" */ item_list[++n] = item_no; } } /*********************************************************************/ /* Iterate over the shift map. Shift-Reduce actions are identified */ /* by a negative integer that indicates the rule in question , and */ /* the associated item can be retrieved by indexing the array */ /* ADEQUATE_ITEMS at the location of the rule. For shift-actions, we*/ /* simply take the predecessor-items of all the items in the kernel */ /* of the following state. */ /* If the shift-action is a look-ahead shift, we check to see if the */ /* look-ahead state contains shift actions, and retrieve the next */ /* state from one of those shift actions. */ /*********************************************************************/ sh = shift[statset[state_no].shift_number]; for (i = 1; i <= sh.size; i++) { next_state = SHIFT_ACTION(sh, i); while (next_state > (int) num_states) { struct shift_header_type next_sh; next_sh = shift[lastats[next_state].shift_number]; if (next_sh.size > 0) next_state = SHIFT_ACTION(next_sh, 1); else next_state = 0; } if (next_state == 0) q = NULL; else if (next_state < 0) q = adequate_item[-next_state]; else { q = statset[next_state].kernel_items; if (q == NULL) /* single production state? */ q = statset[next_state].complete_items; } for (; q != NULL; q = q -> next) { item_no = q -> value - 1; if (! item_seen[item_no]) { item_seen[item_no] = TRUE; item_list[++n] = item_no; } } } /*********************************************************************/ /* GOTOS and GOTO-REDUCES are analogous to SHIFTS and SHIFT-REDUCES. */ /*********************************************************************/ go_to = statset[state_no].go_to; for (i = 1; i <= go_to.size; i++) { if (GOTO_ACTION(go_to, i) > 0) { q = statset[GOTO_ACTION(go_to, i)].kernel_items; if (q == NULL) /* single production state? */ q = statset[GOTO_ACTION(go_to, i)].complete_items; } else q = adequate_item[- GOTO_ACTION(go_to, i)]; for (; q != NULL; q = q -> next) { item_no = q -> value - 1; if (! item_seen[item_no]) { item_seen[item_no] = TRUE; item_list[++n] = item_no; } } } /*********************************************************************/ /* Print the Kernel items. If there are any closure items, skip a */ /* line, sort then, then print them. The kernel items are in sorted */ /* order. */ /*********************************************************************/ for (item_no = 1; item_no <= kernel_size; item_no++) print_item(item_list[item_no]); if (kernel_size < n) { fprintf(syslis, "\n"); ENDPAGE_CHECK; qcksrt(item_list, kernel_size + 1, n); for (item_no = kernel_size + 1; item_no <= n; item_no++) print_item(item_list[item_no]); } ffree(item_list); ffree(item_seen); ffree(state_seen); return;}/*****************************************************************************//* NOSPACE: *//*****************************************************************************//* This procedure is invoked when a call to MALLOC, CALLOC or REALLOC fails. *//*****************************************************************************/void nospace(char *file_name, long line_number){ fprintf(stderr, "*** Cannot allocate space ... LPG terminated in " "file %s at line %d\n", file_name, line_number); exit(12);}/************************************************************************//* STRUPR: *//************************************************************************//* StrUpr and StrLwr. *//* These routines set all characters in a string to upper case and lower*//* case (respectively.) These are library routines in DOS, but *//* are defined here for the 370 compiler. *//************************************************************************/char *strupr(char *string){ char *s; /*********************************************************************/ /* While not at end of string, change all lower case to upper case. */ /*********************************************************************/ for (s = string; *s != '\0'; s++) *s = (islower((int) *s) ? toupper((int) *s) : *s); return string;}/************************************************************************//* STRLWR: *//************************************************************************/char *strlwr(char *string){ char *s; /*********************************************************************/ /* While not at end of string, change all upper case to lower case. */ /*********************************************************************/ for (s = string; *s != '\0'; s++) *s = (isupper((int) *s) ? tolower((int) *s) : *s); return string;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -