📄 lpgparse.c
字号:
PRNT("Options in effect:"); strcpy(output_line, " "); for (i = 1; i <= top; i++) { if (strlen(output_line) + strlen(opt_string[i]) > PRINT_LINE_SIZE-1) { PRNT(output_line); strcpy(output_line, " "); } strcat(output_line, opt_string[i]); if (strlen(output_line) + 2 < PRINT_LINE_SIZE-1) strcat(output_line, " "); } PRNT(output_line); PRNT(""); if (warnings_bit) { if (table_opt == OPTIMIZE_SPACE) { if (default_opt < 4) { PRNTWNG("DEFAULT_OPTion requested must be >= 4"); } } else if (shift_default_bit) { PRNTWNG("SHIFT-DEFAULT option is only valid for Space tables") } }/*********************************************************************//* Check if there are any conflicts in the options. *//*********************************************************************/ temp[0] = '\0'; if (minimum_distance <= 1) { PRNT("MIN_DISTANCE must be > 1"); exit(12); } if (maximum_distance <= minimum_distance + 1) { PRNT("MAX_DISTANCE must be > MIN_DISTANCE + 1"); exit(12); } if (strcmp(blockb, blocke) == 0) strcpy(temp, "BLOCKB and BLOCKE"); else if (strlen(blockb) == 1 && blockb[0] == escape) strcpy(temp, "BLOCKB and ESCAPE"); else if (strlen(blockb) == 1 && blockb[0] == ormark) strcpy(temp, "BLOCKB and ORMARK"); else if (strlen(blocke) == 1 && blocke[0] == escape) strcpy(temp, "ESCAPE and BLOCKE"); else if (strlen(blocke) == 1 && blocke[0] == ormark) strcpy(temp, "ORMARK and BLOCKE"); else if (strcmp(hblockb, hblocke) == 0) strcpy(temp, "HBLOCKB and HBLOCKE"); else if (strlen(hblockb) == 1 && hblockb[0] == escape) strcpy(temp, "HBLOCKB and ESCAPE"); else if (strlen(hblockb) == 1 && hblockb[0] == ormark) strcpy(temp, "HBLOCKB and ORMARK"); else if (strlen(hblocke) == 1 && hblocke[0] == escape) strcpy(temp, "ESCAPE and HBLOCKE"); else if (strlen(hblocke) == 1 && hblocke[0] == ormark) strcpy(temp, "ORMARK and HBLOCKE"); else if (ormark == escape) strcpy(temp, "ORMARK and ESCAPE"); if (temp[0] != '\0') { sprintf(msg_line, "The options %s cannot have the same value", temp); PRNTERR(msg_line); sprintf(msg_line, "Input process aborted at line %d ...", line_no); PRNT(msg_line); exit(12); } if (strlen(hblockb) <= strlen(blockb) && memcmp(hblockb, blockb, strlen(hblockb)) == 0) { sprintf(msg_line, "Hblockb value, %s, cannot be a suffix of blockb: %s", hblockb, blockb); PRNTERR(msg_line); sprintf(msg_line, "Input process aborted at line %d ...", line_no); PRNT(msg_line); exit(12); } return;} /* end process_options_lines *//*****************************************************************************//* HASH: *//*****************************************************************************//* HASH takes as argument a symbol and hashes it into a location in *//* HASH_TABLE. *//*****************************************************************************/static int hash(char *symb){ register unsigned short k; register unsigned long hash_value = 0; for (; *symb != '\0'; symb++) { k = *symb; symb++; hash_value += ((k << 7) + *symb); if (*symb == '\0') break; } return hash_value % HT_SIZE;}/*****************************************************************************//* INSERT_STRING: *//*****************************************************************************//* INSERT_STRING takes as an argument a pointer to a ht_elemt structure and*//* a character string. It inserts the string into the string table and sets *//* the value of node to the index into the string table. *//*****************************************************************************/static void insert_string(struct hash_type *q, char *string){ if (string_offset + strlen(string) >= string_size) { string_size += STRING_BUFFER_SIZE; INT_CHECK(string_size); string_table = (char *) (string_table == (char *) NULL ? malloc(string_size * sizeof(char)) : realloc(string_table, string_size * sizeof(char))); if (string_table == (char *) NULL) nospace(__FILE__, __LINE__); } q -> st_ptr = string_offset; while(string_table[string_offset++] = *string++); /* Copy until NULL */ /* is copied. */ return;}/*****************************************************************************//* ASSIGN_SYMBOL_NO: *//*****************************************************************************//* PROCESS_SYMBOL takes as an argument a pointer to the most recent token *//* which would be either a symbol or a macro name and then processes it. If *//* the token is a a macro name then a check is made to see if it is a pre- *//* defined macro. If it is then an error message is printed and the program *//* is halted. If not, or if the token is a symbol then it is hashed into the *//* hash_table and its string is copied into the string table. A struct is *//* created for the token. The ST_PTR field contains the index into the string*//* table and the NUMBER field is set to zero. Later on if the token is a *//* symbol, the value of the NUMBER field is changed to the appropriate symbol*//* number. However, if the token is a macro name, its value will remain zero.*//* The NAME_INDEX field is set to OMEGA and will be assigned a value later. *//*****************************************************************************//* ASSIGN_SYMBOL_NO takes as arguments a pointer to a node and an image *//* number and assigns a symbol number to the symbol pointed to by the node. *//*****************************************************************************/static void assign_symbol_no(char *string_ptr, int image){ register int i; register struct hash_type *p; i = hash(string_ptr); for (p = hash_table[i]; p != NULL; p = p -> link) { if (EQUAL_STRING(string_ptr, p)) /* Are they the same */ return; } p = (struct hash_type *) talloc(sizeof(struct hash_type)); if (p == (struct hash_type *) NULL) nospace(__FILE__, __LINE__); if (image == OMEGA) { num_symbols++; p -> number = num_symbols; } else p -> number = -image; p -> name_index = OMEGA; insert_string(p, string_ptr); p -> link = hash_table[i]; hash_table[i] = p; return;}/*****************************************************************************//* ALIAS_MAP: *//*****************************************************************************//* ALIAS_MAP takes as input a symbol and an image. It searcheds the hash *//* table for stringptr and if it finds it, it turns it into an alias of the *//* symbol whose number is IMAGE. Otherwise, it invokes PROCESS_SYMBOL and *//* ASSIGN SYMBOL_NO to enter stringptr into the table and then we alias it. *//*****************************************************************************/static void alias_map(char *stringptr, int image){ register struct hash_type *q; for (q = hash_table[hash(stringptr)]; q != NULL; q = q -> link) { if (EQUAL_STRING(stringptr, q)) { q -> number = -image; /* Mark alias of image */ return; } } assign_symbol_no(stringptr, image); return;}/*****************************************************************************//* SYMBOL_IMAGE: *//*****************************************************************************//* SYMBOL_IMAGE takes as argument a symbol. It searches for that symbol *//* in the HASH_TABLE, and if found, it returns its image; otherwise, it *//* returns OMEGA. *//*****************************************************************************/static int symbol_image(char *item){ register struct hash_type *q; for (q = hash_table[hash(item)]; q != NULL; q = q -> link) { if (EQUAL_STRING(item, q)) return ABS(q -> number); } return(OMEGA);}/*****************************************************************************//* NAME_MAP: *//*****************************************************************************//* NAME_MAP takes as input a symbol and inserts it into the HASH_TABLE if it *//* is not yet in the table. If it was already in the table then it is *//* assigned a NAME_INDEX number if it did not yet have one. The name index *//* assigned is returned. *//*****************************************************************************/static int name_map(char *symb){ register int i; register struct hash_type *p; i = hash(symb); for (p = hash_table[i]; p != NULL; p = p -> link) { if (EQUAL_STRING(symb, p)) { if (p -> name_index != OMEGA) return(p -> name_index); else { num_names++; p -> name_index = num_names; return(num_names); } } } p = (struct hash_type *) talloc(sizeof(struct hash_type)); if (p == (struct hash_type *) NULL) nospace(__FILE__, __LINE__); p -> number = 0; insert_string(p, symb); p -> link = hash_table[i]; hash_table[i] = p; num_names++; p -> name_index = num_names; return num_names;}/*****************************************************************************//* PROCESS_GRAMMAR: *//*****************************************************************************//* PROCESS_GRAMMAR is invoked to process the source input. It uses an *//* LALR(1) parser table generated by LPG to recognize the grammar which it *//* places in the rulehdr structure. *//*****************************************************************************/#include "lpgact.i"#include "lpgact.h"#include "lpgprs.h"static void process_grammar(void){ short state_stack[STACK_SIZE]; register int act; scanner(); /* Get first token */ act = START_STATE;process_terminal:/******************************************************************//* Note that this driver assumes that the tables are LPG SPACE *//* tables with no GOTO-DEFAULTS. *//******************************************************************/ state_stack[++stack_top] = act; act = t_action(act, ct, ?); if (act <= NUM_RULES) /* Reduce */ stack_top--; else if ((act > ERROR_ACTION) || /* Shift_reduce */ (act < ACCEPT_ACTION)) /* Shift */ { token_action(); scanner(); if (act < ACCEPT_ACTION) goto process_terminal; act -= ERROR_ACTION; } else if (act == ACCEPT_ACTION) { accept_action(); return; } else error_action();process_non_terminal: do { register int lhs_sym = lhs[act]; /* to bypass IBMC12 bug */ stack_top -= (rhs[act] - 1); rule_action[act](); act = nt_action(state_stack[stack_top], lhs_sym); } while(act <= NUM_RULES); goto process_terminal;}/*****************************************************************************//* SCA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -