void LGCheckGrammar::C_NULLS () { int h, p, t, s, n; n_nulls = 0; ALLOC (nullable, n_heads); FASTINI (0, nullable, n_heads); do { n = 0; for (h = 0; h < n_heads; h++) { if (nullable [h] == 0) { for (p = f_prod [h]; p < l_prod [h]; p++) { for (t = f_tail [p]; t < l_tail [p]; t++) ///////////////////////////////// { if ((s = tail [t]) < 0) { if (nullable [-s] == 0) goto nextp; } else goto nextp; } n++; n_nulls++; nullable [h] = 1; goto nexth; nextp: continue; } } nexth: continue; } } while (n > 0); }
int PGCreateTables::MRG_ROWZ_N (int **matrix, int n_heads, int *row, int n_states, int opt) { int *density, *indx; int s, i, r, nr, t, x, v; if (opt) { ALLOC (indx, n_states); ALLOC (density, n_states); for (s = 0; s < n_states; s++) indx [s] = s; for (s = 0; s < n_states; s++) { t = ntt_start[s+1] - ntt_start[s]; if (opt == 1) density [s] = -t; /* Maximize Number of Columns. */ else density [s] = t; /* Minimize Number of Columns. */ } SORT2 (density, indx, n_states); FREE (density, n_states); } nr = 0; for (x = 0; x < n_states; x++) // For all states. { if (opt) s = indx[x]; else s = x; for (r = 0; r < nr; r++) // For all rows defined. { for (i = ntt_start[s]; i < ntt_start[s+1]; i++) { if (ntt_action[i] != 0) { v = *(matrix[r] + ntt_symb[i]); if (v != 0 && v != ntt_action[i]) goto Next; } } goto Old; Next: continue; } ALLOC (matrix[nr], n_heads); FASTINI (0, matrix[nr], n_heads); nr++; Old: row [s] = r; for (i = ntt_start[s]; i < ntt_start[s+1]; i++) { if (ntt_action[i] != 0) { *(matrix[r] + ntt_symb[i]) = ntt_action[i]; } } } if (opt) FREE (indx, n_states); return (nr); }
int PGCreateTables::BLD_N (int opt1, int opt2, char *mark) /* Build Nonterminal Matrix. */ { int **Matrix, p, r, multiplier, *n_col, org_size; if (optn[PG_VERBOSE]) prt_log ("N matrix"); else prt_logonly ("N matrix"); ALLOC (N_row, ntt_states); ALLOC (n_col, N_heads); ALLOC (Matrix, ntt_states); N_rows = MRG_ROWZ_N (Matrix, N_heads, N_row, ntt_states, opt1); if (optn[PG_VERBOSE]) prt_log (" %6d ", N_rows); else prt_logonly (" %6d ", N_rows); N_cols = MRG_COLZ (n_col, N_heads, N_rows, Matrix, opt2); org_size = N_rows * N_cols; if (N_prods > 32767 || ntt_states > 32767) multiplier = 4; // int else if (N_prods > 127 || ntt_states > 127) multiplier = 2; // short else multiplier = 1; // char N_total = multiplier*org_size; char num[12] = " "; number (N_total, num); // Gives 9 digits. if (optn[PG_VERBOSE]) prt_log ("x%5ld x %d =%10s", N_cols, multiplier, num); else prt_logonly ("x%5ld x %d =%10s", N_cols, multiplier, num); total0 += N_total; ALLOC (N_matrix, org_size); FASTINI (0, N_matrix, org_size); N_size = DISP_ZEQ (Matrix, N_matrix, N_row, N_rows, N_cols, ntt_states); for (r = 0; r < N_rows; r++) FREE (Matrix [r], N_heads); FREE (Matrix, ntt_states); REALLOC (N_matrix, org_size, N_size); ALLOC (N_col, N_prods); for (p = 0; p < N_prods; p++) { N_col[p] = n_col[head_sym[p]]; } FREE (n_col, N_heads); int vectors = 0; vectors += get_type (N_row, ntt_states) * ntt_states; // row vector vectors += get_type (N_col, N_prods) * N_prods; // column vector OUT_TOT (multiplier*N_size, vectors, mark); return (multiplier*N_size + vectors); }
int PGCreateTables::MRG_ROWE2R (int **matrix, int n_terms, int *row, int n_states) { int s, i, r, nr, *buffer; nr = 0; ALLOC (buffer, n_terms); for (s = 0; s < n_states; s++) // For all states. { if (D_red[s] > 0) // Default reduction for this state? { if (optn[PG_DEFAULTRED]) { row[s] = 0; goto Cont; } FASTINI (D_red[s], buffer, n_terms); // Fill in with the default. } else // Use the list of reductions and terminal symbols. { FASTINI (0, buffer, n_terms); // Initialize to 0 (error). for (i = la_start[s]; i < la_start[s+1]; i++) { buffer [la_symb[i]] = la_red[i]; // Place reduction in buffer. } } for (r = 0; r < nr; r++) { if (FASTCMP (buffer, matrix[r], n_terms)) goto Old; } ALLOC (matrix[nr], n_terms); FASTCPY (buffer, matrix[nr], n_terms); nr++; Old: row [s] = r; Cont: continue; } FREE (buffer, n_terms); return (nr); }
int PGCreateTables::BLD_T (int opt1, int opt2, char *mark) /* Build Terminal Matrix. */ { int **Matrix, r, multiplier, org_size; if (optn[PG_VERBOSE]) prt_log ("T matrix"); else prt_logonly ("T matrix"); ALLOC (T_row, tt_states); ALLOC (T_col, N_terms); ALLOC (Matrix, tt_states); if (optn[PG_BOOLMATRIX] == 0) T_rows = MRG_ROWE2T (Matrix, N_terms, T_row, tt_states, opt1); else T_rows = MRG_ROWZ_T (Matrix, N_terms, T_row, tt_states, opt1); if (optn[PG_VERBOSE]) prt_log (" %6d ", T_rows); else prt_logonly (" %6d ", T_rows); if (optn[PG_BOOLMATRIX] == 0) T_cols = MRG_COLE2 (T_col, N_terms, T_rows, Matrix); else T_cols = MRG_COLZ (T_col, N_terms, T_rows, Matrix, opt2); org_size = T_rows * T_cols; if (N_prods > 32767 || tt_states > 32767) multiplier = 4; // int else if (N_prods > 127 || tt_states > 127) multiplier = 2; // short else multiplier = 1; // char T_total = multiplier*org_size; char num[12] = " "; number (T_total, num); // Gives 9 digits. if (optn[PG_VERBOSE]) prt_log ("x%5ld x %d =%10s", T_cols, multiplier, num); else prt_logonly ("x%5ld x %d =%10s", T_cols, multiplier, num); total0 += T_total; ALLOC (T_matrix, org_size); FASTINI (0, T_matrix, org_size); if (optn[PG_BOOLMATRIX] == 0) T_size = DISP_EQ2 (Matrix, T_matrix, T_row, T_rows, T_cols, tt_states, opt1); else T_size = DISP_ZEQ (Matrix, T_matrix, T_row, T_rows, T_cols, tt_states); for (r = 0; r < T_rows; r++) FREE (Matrix [r], N_terms); FREE (Matrix, tt_states); REALLOC (T_matrix, org_size, T_size); int vectors = 0; vectors += get_type (T_row, tt_states) * tt_states; // row vector vectors += get_type (T_col, N_terms) * N_terms; // column vector OUT_TOT (multiplier*T_size, vectors, mark); return (multiplier*T_size + vectors); }
int PGCreateTables::BLD_R (int opt1, char *mark) /* Build Reduction Matrix. */ { int **Matrix, s, r, multiplier, org_size; if (optn[PG_VERBOSE]) prt_log ("R matrix"); else prt_logonly ("R matrix"); ALLOC (R_row, n_states); ALLOC (R_col, N_terms); ALLOC (Matrix, n_states+1); R_rows = MRG_ROWE2R (Matrix, N_terms, R_row, n_states); if (optn[PG_VERBOSE]) prt_log (" %6d ", R_rows); else prt_logonly (" %6d ", R_rows); R_cols = MRG_COLE2 (R_col, N_terms, R_rows, Matrix); org_size = R_rows * R_cols; ALLOC (R_matrix, org_size); FASTINI (0, R_matrix, org_size); R_size = DISP_EQ2 (Matrix, R_matrix, R_row, R_rows, R_cols, n_states, opt1); for (r = 0; r < R_rows; r++) FREE (Matrix [r], N_terms); FREE (Matrix, n_states+1); REALLOC (R_matrix, org_size, R_size); if (optn[PG_DEFAULTRED]) { for (s = 0; s < n_states; s++) { if (D_red[s] > 0) R_row[s] = D_red[s]; else R_row[s] = -R_row[s]; } } multiplier = get_type (R_matrix, R_size); char num[12] = " "; number (multiplier*R_size, num); if (optn[PG_VERBOSE]) prt_log ("x%5ld x %d =%10s", R_cols, multiplier, num); else prt_logonly ("x%5ld x %d =%10s", R_cols, multiplier, num); total0 += multiplier*R_size; int vectors = 0; vectors += get_type (R_row, n_states) * n_states; // row vector vectors += get_type (R_col, N_terms) * N_terms; // column vector OUT_TOT (multiplier*R_size, vectors, mark); return (multiplier*R_size + vectors); }
int PGBuildLR1::COMPATIBLE (int x, int y) // Check for minimal LR(1) compatibility. { int f, k, nfi, i, la, p; FASTINI (0, reduction_x, N_terms); for (k = f_lrkernel[x]; k < l_lrkernel[x]; k++) // X state final items check { i = lrkernel[k].item; if (item[i].symb == -32767) // Final item? { la = lrkernel[k].LA; p = item[i].prod; if (reduction_x[la] == 0) reduction_x[la] = p; // Define new reduction. else if (reduction_x[la] != p) reduction_x[la] = -1; // Mark as conflict. } } // FASTINI (0, reduction_y, N_terms); // For research only. for (k = f_lrkernel[y]; k < l_lrkernel[y]; k++) // Y state final items check { i = lrkernel[k].item; if (item[i].symb == -32767) // Final item? { la = lrkernel[k].LA; p = item[i].prod; if (reduction_x[la] == 0) // LA not previuosly used (not a conflict)? { // return 0; // Not compatible (special case for research only). } else if (reduction_x[la] == -1) // LA already conflicted by state x! { /* ignore this */ } else if (reduction_x[la] != p) // Definitely a conflict? { return 0; // NOT COMPATIBLE !!! } // if (reduction_y[la] == 0) reduction_y[la] = p; // Define new reduction. // if (reduction_y[la] != p) reduction_y[la] = -1; // Mark as conflict. } } // Could possibly do something with conflicted (-1) entries comparing x to y. // Nothing for now, maybe later. return 1; }
int PGBuildLR1::BuildLR1 () /* Build Canonical LR1 States */ { int h, ns; max_clo = 0; C_ITEMS (); max_states = optn[MAX_STA]; max_finals = optn[MAX_FIN]; max_kernels = optn[MAX_KER]; max_child = optn[MAX_CH]; // Global variable. max_lookback = optn[MAX_LB]; max_lookahead = optn[MAX_LA]; max_include = optn[MAX_INC]; max_ntt = optn[MAX_NTT]; max_tails = optn[MAX_TAIL]; max_closure = max_tails; // ? max_lrkernels = max_kernels; // ? max_hashes = 2*max_states + 1; hash_div = UINT_MAX / max_hashes + 1; ALLOC (ntt_item, max_ntt ); ALLOC (accessor, max_states ); ALLOC (f_final, max_states ); ALLOC (l_final, max_states ); ALLOC (f_lrkernel, max_states ); ALLOC (l_lrkernel, max_states ); ALLOC (lrkernel, max_lrkernels); ALLOC (final, max_finals ); ALLOC (Tgotos, max_states ); ALLOC (Ngotos, max_states ); ALLOC (N_clo, max_states ); ALLOC (closure, max_closure); ALLOC (inclosure_term, N_terms ); ALLOC (inclosure_head, N_heads ); ALLOC (Closure, max_states ); ALLOC (Closure_Term, max_states ); ALLOC (Closure_Head, max_states ); ALLOC (hash_vector, max_hashes ); ALLOC (new_head, N_heads); ALLOC (reduction_x, N_terms); ALLOC (reduction_y, N_terms); ALLOC (item_added, n_items); ALLOC (prod_added, N_prods); ALLOC (first_time, N_heads); ALLOC (reduce_state, N_prods); ALLOC (lookahead, N_heads); for (h = 0; h < N_heads; h++) ALLOC (lookahead[h], N_terms); ALLOC (L_tail, N_prods); for (int p = 0; p < N_prods; p++) L_tail[p] = F_tail[p+1]; FASTINI ( 0, reduce_state, N_prods); FASTINI (-1, hash_vector, max_hashes); n_finals = 0; n_lrkernels = 0; n_kernels = 0; accessor[0] = 0; n_nonttran = 0; n_termtran = 0; ro_states = 0; s_states = 0; rr_states = 0; sr_states = 0; top = 0; n_states = 1; tt_states = 0; nt_states = 0; extra_states = 0; n_collisions = 0; C_FIRST (N_heads, N_terms, N_prods, F_prod, F_tail, Tail, FIRST, nullable, head_sym); MAKE_KERNEL(0); DO_CLOSURE (0); if (optn[PG_STATELIST] > 1) PRINT ("\nSTATE MACHINE WITH CLOSURE ITEMS:\n\n"); for (state = 0; state < n_states; state++) { EXPAND (state); } opt_states = n_states; // Optimum number of states, without reduce-only states for LALR. MAKE_LR0_KERNELS (); FREE (lrkernel, max_lrkernels); FREE (f_lrkernel, max_states ); FREE (l_lrkernel, max_states ); char* Grammar; if (optn[PG_LALR_PARSER]) Grammar = "LALR(1) "; else if (optn[PG_LR_PARSER] ) Grammar = "LR(1) "; else Grammar = "CLR(1) "; if (optn[PG_SHIFTREDUCE]) ro_states--; else ro_states = 0; if (optn[PG_LALR_PARSER]) prt_log ("%s %7d states in LALR(1) state machine.\n", Grammar, n_states); else if (optn[PG_LR_PARSER] ) prt_log ("%s %7d states in Minimal LR(1) state machine.\n", Grammar, n_states); else prt_log ("%s %7d states in Canonical LR(1) state machine.\n", Grammar, n_states); if (optn[PG_SHIFTREDUCE]) prt_log (" %7d states after implementing shift-reduce actions.\n", n_states - ro_states); else prt_log (" %7d states removed for shift-reduce actions.\n", 0); REALLOC (final, max_finals, n_finals+1); REALLOC (f_final, max_states, n_states+1); REALLOC (accessor, max_states, n_states ); REALLOC (Tgotos, max_states, opt_states); REALLOC (Ngotos, max_states, opt_states); REALLOC (ntt_item, max_ntt, n_nonttran); for (h = 0; h < N_heads; h++) FREE (lookahead[h], N_terms); FREE (lookahead, N_heads); FREE (l_final, max_states); FREE (N_clo, max_states); FREE (closure, max_closure); FREE (Closure, max_states); FREE (hash_vector, max_hashes); FREE (reduction_x, N_terms); FREE (reduction_y, N_terms); FREE (first_time, N_heads); FREE (new_head, N_heads); FREE (inclosure_term, N_terms); FREE (inclosure_head, N_heads); FREE (item_added, n_items); FREE (prod_added, N_prods); MAKE_LR0_TRANSITIONS (); for (int s = 0; s < opt_states; s++) FREE (Tgotos[s], Tgotos[s][0]+1); FREE (Tgotos, opt_states); for (int s = 0; s < opt_states; s++) FREE (Ngotos[s], Ngotos[s][0]+1); FREE (Ngotos, opt_states); MODIFY_TRANSITIONS (); MTSL (); C_CAMEFROM (n_states, tt_start, tt_action, ntt_start, ntt_action, f_camefrom, camefrom); FREE (reduce_state, N_prods); n_kernels = n_lrkernels; // For stats list in Terminate. if (n_errors) return (0); return (1); }
int PGCreateTables::MRG_ROWE2T (int **matrix, int n_terms, int *row, int n_states, int opt) { uint hash, n_cells, hash_divide; int nr, nc, nt, s, t, i, r, *buffer, *vector, value, cell, *count, c; nr = 0; ALLOC (buffer, n_terms); ALLOC (count, n_states); n_cells = 2*n_states; ALLOC (vector, n_cells); FASTINI (-1, vector, n_cells); hash_divide = UINT_MAX / n_cells + 1; // nc = 0; // number of collisions = 0. for (s = 0; s < n_states; s++) // For all states ... { count[s] = 0; hash = MAX_INT; for (t = 0; t < n_terms; t++) buffer[t] = 0; for (i = tt_start[s]; i < tt_start[s+1]; i++) { if (tt_action[i] != 0) { count[s]++; t = tt_symb[i]; buffer[t] = tt_action[i]; hash += tt_action[i]*i; } } cell = hash % n_cells; // Get first cell. r = vector [cell]; // Get symbol index. while (r >= 0) { if (count[s] != count[r]) goto Cont; for (i = tt_start[s]; i < tt_start[s+1]; i++) // Compare rows. { if (tt_action[i] != 0) { t = tt_symb[i]; if (buffer[t] != matrix[r][t]) goto Cont; } } goto Old; Cont: cell = (hash *= 65549) / hash_divide; // Get new cell number. r = vector[cell]; // Get row index. // nc++; // number of collisions. } vector[cell] = nr; r = nr++; ALLOC (matrix[r], n_terms); // Create a new row ... for (t = 0; t < n_terms; t++) { matrix[r][t] = buffer[t]; } Old: row[s] = r; // Define row pointer. } FREE (buffer, n_terms); FREE (count, n_states); FREE (vector, n_cells); return (nr); }