void LGCheckGrammar::p_prod (int p, int dot, char *before) { int t, u, d; if (p < 0) { p = -p; prt_log ("%s%s -> ", before, head_name [head_sym [p]]); } else { prt_log ("%s%5d %s -> ", before, p, head_name [head_sym [p]]); } t = f_tail [p]; u = l_tail [p]; d = t + dot; if (dot == -1) d = u; for (;;) { if (t == d) prt_sta (". "); if (t >= u) break; p_sym (tail [t], " "); t++; } prt_log ("\n"); }
char* PG::slash_inside_keyword (char* term_name, char quote) { static char string[128]; int i = 1; char *p; if (term_name[0] == '\'') p = term_name+1; else p = term_name; do { if (*p != '\\') { string[i++] = *p++; if (i > 127) { n_errors++; if (n_errors == 1) prt_log ("\n"); prt_log ("In file '%s', literal is longer than 128 characters.\n\n", grmfid); PG::Terminate (6); } } else { p++; string[i++] = *p++; } } while (*p != 0); string[0] = quote; if (string[i-1] == '\'') string[i-1] = quote; else string[i++] = quote; string[i] = 0; // printf ("%s\n", string); return (string); }
int PGCreateTables::CreateTables () { char* m; int Bi = 0; int Ti = 0, Tj = 0; int Ni = 0, Nj = 0; int Ri = 0; if (optn[PG_ANALYZEONLY]) return 0; m = " "; total0 = total1 = total2 = 0; if (optn [PG_MINIMIZE]) { if (optn[PG_VERBOSE]) prt_log (" rows cols matrix list vect total\n"); else prt_logonly (" rows cols matrix list vect total\n"); MIN_B (&Bi); MIN_T (&Ti, &Tj); MIN_N (&Ni, &Nj); MIN_R (&Ri); m = "*"; if (optn[PG_VERBOSE]) prt_log ("\n"); else prt_logonly ("\n"); } if (optn[PG_VERBOSE]) prt_log (" rows cols matrix list vect total\n"); else prt_logonly (" rows cols matrix list vect total\n"); BLD_B (Bi, m); BLD_T (Ti, Tj, m); BLD_N (Ni, Nj, m); BLD_R (Ri, m); char n1[16] = " "; char n2[16] = " "; char n3[16] = " "; number (total1, n1); number (total2, n2); number (total1+total2, n3); if (optn[PG_VERBOSE]) prt_log ("Total %9s +%9s =%9s\n\n", n1, n2, n3); else prt_logonly ("Total %9s +%9s =%9s\n\n", n1, n2, n3); FREE (tt_symb, n_ttran); FREE (tt_action, n_ttran); FREE (tt_start, n_states+1); FREE (ntt_start, n_states+1); FREE (ntt_symb, n_nttran); FREE (ntt_action, n_nttran); FREE (la_start, n_states+1); FREE (la_red, max_lookah); FREE (la_symb, max_lookah); // Reduce production length by 1, so no "-1" adjustment is required in skl file. for (int p = 0; p < N_prods; p++) prod_len[p]--; return (1); }
void LGCheckGrammar::P_UNDEFINED () { int t, n = n_errors; if (n_terms > max_char_set+1) { strcpy (gft, ".lex"); strcpy (grmfid, gdn); strcat (grmfid, gfn); strcat (grmfid, gft); char* Input_start = input_start; char* Input_end = input_end; char** Line_ptr = line_ptr; input_start = lex_input_start; input_end = lex_input_end; line_ptr = lex_line_ptr; for (t = max_char_set+1; t < n_terms; t++) // Skip <eof> { if (term_type[t] & LEXFILE) prt_error ("'%s' is listed in the .lex file, but not defined in the .lgr file", term_name[t], 0, term_line[t]); } strcpy (gft, ".lgr"); strcpy (grmfid, gdn); strcat (grmfid, gfn); strcat (grmfid, gft); input_start = Input_start; input_end = Input_end; line_ptr = Line_ptr; for (t = max_char_set+1; t < n_terms; t++) // Skip <eof> { if (!(term_type[t] & LEXFILE)) { char code = charcode[*term_name[t]]; if ( code == DIGIT || code == QUOTE) { prt_error ("'%s' is not a predefined symbol", term_name[t], 0, term_line[t]); prt_log ("Predefined symbols are:\n"); prt_log (" 0..31\n"); for (int i = 32; i < 127; i++) prt_log (" %s\n", term_name[i]); prt_log (" 127..255\n"); LG::Terminate(95); } else { prt_error ("'%s' is not defined in the lexical grammar (.lgr file)", term_name[t], 0, term_line[t]); } } } } FREE (term_type, n_terms); }
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::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 PGCreateTables::BLD_B (int opt1, char *mark) // Build Boolean Matrix. { char** Matrix; int r, org_size; if (optn[PG_BOOLMATRIX] == 0) return 0; if (optn[PG_VERBOSE]) prt_log ("B matrix"); else prt_logonly ("B matrix"); ALLOC (B_row, n_states); ALLOC (B_col, N_terms); ALLOC (Matrix, n_states+1); B_rows = MRG_ROWE1B (Matrix, N_terms, B_row, n_states); if (optn[PG_VERBOSE]) prt_log (" %6d ", B_rows); else prt_logonly (" %6d ", B_rows); B_cols = MRG_COLE1B (B_col, N_terms, B_rows, Matrix); B_size = B_rows * B_cols; total0 += B_size; char num[12] = " "; number (B_size, num); // Gives 9 digits. if (optn[PG_VERBOSE]) prt_log ("x%5ld x 1 =%10s", B_cols, num); else prt_logonly ("x%5ld x 1 =%10s", B_cols, num); org_size = (B_rows)*((B_cols+7)/8*8); ALLOC (B_matrix, org_size); memset (B_matrix, 0, org_size); B_size = DISP_EQ1B (Matrix, B_matrix, B_row, B_rows, B_cols, opt1); for (r = 0; r < B_rows; r++) FREE (Matrix[r], N_terms); FREE (Matrix, n_states+1); int vectors = 0; if (optn[PG_BOOLMATRIX] > 1) { vectors += N_terms; B_size = MAKE_PACKED (B_matrix, B_size); } REALLOC (B_matrix, org_size, B_size); vectors += get_type (B_row, n_states) * n_states; // row vector vectors += get_type (B_col, N_terms) * N_terms; // column vector OUT_TOT (B_size, vectors, mark); return (B_size + vectors); }
int LG::Terminate (int rc) { double dsec; int min, sec, thou, i; char num[14] = " "; if (n_states > org_states) org_states = n_states; if (n_prods > max_n_prods) max_n_prods = n_prods; // brute force fix. else max_n_prods++; // brute force fix again. if (n_prods < 0) n_prods = 0; // In case of early syntax error. if (optn[LG_VERBOSE] > 1) { optncount[MAX_SYM] = n_symbs; optncount[MAX_PRO] = n_prods; optncount[MAX_TAIL] = n_tails; optncount[MAX_EBNF] = amt_space; optncount[MAX_STA] = org_states; optncount[MAX_FIN] = n_finals; optncount[MAX_KER] = n_kernels; optncount[MAX_NTT] = n_nonttran; optncount[MAX_TT] = n_termtran; optncount[MAX_TTA] = n_ttas; optncount[MAX_LB] = n_lookbacks; optncount[MAX_LA] = n_lookah; optncount[MAX_INC] = n_includes; optncount[MAX_CH] = max_child_usage; optncount[MAX_ND] = 0; for (i = 0; *MAOption[i].name != 0; i++) { prt_num (MAOption[i].desc, optncount[MAOption[i].numb], MAOption[i].name, optn[MAOption[i].numb]); } prt_logonly ("\n"); } char* es = "s"; char* ws = "s"; if (n_errors == 1) es = ""; if (n_warnings == 1) ws = ""; time2 = clock (); dsec = (double)(time2-time1) / CLOCKS_PER_SEC; min = dsec/60; sec = dsec-min*60; thou = (dsec-min*60-sec)*1000; int x = memory_max/1024/1024; int y = memory_max/1024 - 1024*x; prt_log ("%1d min %1d.%03d sec, %d.%03d MB, %d warning%s, %d error%s.\n\n", min, sec, thou, x, y, n_warnings, ws, n_errors, es); close_con (); close_grm (); close_sta (); close_lst (); if (n_errors > 0) quit (n_errors); return 0; }
int PG::Terminate (int rc) { double dsec; int i, min, sec, thou; inputt (); if (optn[PG_VERBOSE] > 1) { optncount[MAX_SYM] = Symtab::n_symbols; optncount[MAX_PRO] = N_prods; optncount[MAX_TAIL] = N_tails; optncount[MAX_EBNF] = 0; optncount[MAX_STA] = org_states; optncount[MAX_FIN] = n_finals; optncount[MAX_KER] = n_kernels; optncount[MAX_NTT] = n_nttran; optncount[MAX_TT] = n_ttran; optncount[MAX_TTA] = n_ttas; optncount[MAX_LB] = n_lookbacks; optncount[MAX_LA] = n_lookah; optncount[MAX_INC] = n_includes; optncount[MAX_CH] = max_child_usage; optncount[MAX_ND] = n_nditems; for (i = 0; *MAOption[i].name != 0; i++) { prt_num (MAOption[i].desc, optncount[MAOption[i].numb], MAOption[i].name, optn[MAOption[i].numb]); } prt_logonly ("\n"); } PGParser::terminate (); char* es = "s"; char* ws = "s"; char* cs = "s"; if (n_errors == 1) es = ""; if (n_warnings == 1) ws = ""; if (c_states == 1) cs = ""; time2 = clock (); dsec = (double)(time2-time1) / CLOCKS_PER_SEC; min = dsec/60; sec = dsec-min*60; thou = (dsec-min*60-sec)*1000; int x = memory_max/1024/1024; int y = memory_max/1024 - 1024*x; prt_log ("%1d min %1d.%03d sec, %d.%03d MB, %d warning%s, %d error%s.\n\n", min, sec, thou, x, y, n_warnings, ws, n_errors, es); close_con (); close_grm (); // close_log (); close_sta (); close_lst (); if (n_errors > 0) quit (n_errors); return 0; }
void LGCheckGrammar::P_USELESS_PROD () { int h, p; for (h = 1; h < n_heads; h++) { for (p = f_prod[h]; p < l_prod[h]; p++) { if ((l_tail[p] - f_tail[p]) == 1) { if (h == -tail [f_tail[p]]) { prt_log ("%s(%04d) : ", grmfid, prod_line[p]); p_prod (-p, -1, ""); prt_log ("\n"); prt_error ("Useless production", 0, 0, prod_line[p]); } } } } }
int LGCheckGrammar::p_sym (int s, char *sp) { char *p; if (s >= 0) /* Terminal symbol? */ p = term_name[s]; else /* Nonterminal symbol? */ p = head_name[-s]; prt_log ("%s%s", p, sp); return (strlen(p) + strlen(sp)); }
void PGCreateTables::OUT_TOT (int size, int vectors, char *mark) { char n1[12] = " "; char n2[12] = " "; char n3[12] = " "; number (size, n1); number (vectors, n2); number (size+vectors, n3); if (optn[PG_VERBOSE]) prt_log (" ->%9s +%9s =%9s %s\n", n1, n2, n3, mark); else prt_logonly (" ->%9s +%9s =%9s %s\n", n1, n2, n3, mark); total1 += size; total2 += vectors; }
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 PGBuildLR1::TRANSITION (int sym) { uint probe; LRKERNEL temp; int compatible = 1; int fk, lk, nk, ni, fi, i, j, k, x, y, p; // PRT_LRSTA (n_states); fk = f_lrkernel[n_states]; lk = l_lrkernel[n_states]; nk = lk - fk; fi = 0; x = n_states; #ifdef PG_DEBUG PRT_LRSTA (x); #endif if (optn[PG_CLR_PARSER]) { if (nk > 1) { LR1_SORT (lrkernel, fk, lk); } probe = hash_no % max_hashes; while ((y = hash_vector[probe]) != -1) // Get state y with same hash cell. { if (l_lrkernel[y] - f_lrkernel[y] == nk) // Same number of kernels? { for (i = f_lrkernel[x], j = f_lrkernel[y]; i < l_lrkernel[x]; i++, j++) { if (lrkernel[i].item != lrkernel[j].item) goto Next1; if (lrkernel[i].LA != lrkernel[j].LA ) goto Next1; } n_lrkernels = fk; // Reset this. return (y); // Return old state number. } Next1: probe = (hash_no *= 65549) / hash_div; } } else // PG_LR_PARSER or PG_LALR_PARSER { ni = LR0_SORT (lrkernel, fk, lk); if (ni == 1) // Number of lrkernel items is 1 or 0? { i = lrkernel[fk].item; // Get item # if (item[i].symb == -32767) { if (optn[PG_LALR_PARSER]) { p = item [i].prod; // Get production. reduce_state[p] = 1; // Mark production for reduce-state creation. return (-p); // Return production number. } fi = i; // Save the final item. } } probe = hash_no % max_hashes; while ((y = hash_vector[probe]) != -1) // Get state y with same hash cell. { #ifdef PG_DEBUG PRINT ("Comparing to:\n\n"); PRT_LRSTA (y); #endif int n = 0, m = 0; memset (item_added, 0, n_items); for (i = f_lrkernel[x]; i < l_lrkernel[x]; i++) { if (item_added[lrkernel[i].item] == 0) // Item not added yet? { n++; item_added [lrkernel[i].item] = 1; // Add it. } } for (i = f_lrkernel[y]; i < l_lrkernel[y]; i++) { if (item_added[lrkernel[i].item] == 0) goto Next2; // Missmatch! if (item_added[lrkernel[i].item] == 1) // Match!? { m++; item_added [lrkernel[i].item] = 2; } } if (n == m) // LALR(1) satisfied? { if (!optn[PG_LALR_PARSER]) { if (!COMPATIBLE (x, y)) { compatible = 0; goto Next2; } } #ifdef PG_DEBUG PRINT ("Got a match!\n"); #endif n_lrkernels = fk; // Reset this, not a new state. if (fi) // If final item defined? { p = item [fi].prod; // Get production. reduce_state[p] = 1; // Mark production for reduce-state creation. return (-p); // Return production number. } return (y); // Return old state number. } Next2: probe = (hash_no *= 65549) / hash_div; } } if (!compatible) extra_states++; if (fi) // If final item defined by LR or LALR? { #ifdef PG_DEBUG PRINT ("Reduce-ony state!\n"); #endif p = item [fi].prod; // Get production. reduce_state[p] = 1; // Mark production for reduce-state creation. return (-p); // Return production number. } // NEW STATE ... #ifdef PG_DEBUG PRINT ("New state %d\n", n_states); #endif accessor [n_states] = sym; hash_vector [probe] = n_states; DO_CLOSURE (n_states); if (n_states % 50000 == 0) prt_log (" %7d states\n", n_states); if (n_states >= max_states) MemCrash ("Number of states", max_states); return (n_states++); }
void PG::OutputLexicalSymbols () { char* p; char string[256]; int filedesc, first, i, k, n, ns, len; int* seq; ALLOC (seq, N_terms); SORTNAMES (term_name, N_terms, seq); strcpy (lexfid, gdn); strcat (lexfid, gfn); strcat (lexfid, ".lex"); if (chmod (lexfid, S_IWRITE) == 0) // File can be written ? { if (unlink (lexfid) != 0) // Delete it? { if (++n_errors == 1) prt_log ("\n"); prt_log ("Output file '%s' cannot be written!\n", lexfid); PG::Terminate (1); } } filedesc = open (lexfid, O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE); /* <lexical> symbols */ len = sprintf (string, "\n/* %s lexical symbols, generated by LRSTAR. */\n\n", gfn); write (filedesc, string, len); len = sprintf (string, " \"tab=%d\"\n\n", optn[PG_TAB]); write (filedesc, string, len); n = 0; for (i = 0; i < N_terms; i++) { if (seq[i] == 0) continue; // Skip <error> symbol. if (seq[i] == eof_term && optn[PG_EOFINCLUDED] == 0) continue; if (term_name[seq[i]][0] == '<') { n++; write (filedesc, " ", 3); k = strlen(term_name[seq[i]]); write (filedesc, term_name[seq[i]], k); ns = (max_terml - k + 3); if (ns > 0) write (filedesc, spaces, ns); k = sprintf (string, "%5d", seq[i]); write (filedesc, string, k); write (filedesc, "\n", 1); } } if (n) first = 1; /* Keywords */ n = 0; char quote = '\''; for (i = 0; i < N_terms; i++) { if (itsakeyword(term_name[seq[i]])) { n++; if (first) { first = 0; write (filedesc, "\n", 1); } write (filedesc, " ", 3); p = slash_inside_keyword (term_name[seq[i]], quote); len = strlen (p); write (filedesc, p, len); ns = (max_terml - len + 3); if (ns > 0) write (filedesc, spaces, ns); len = sprintf (string, "%5d", seq[i]); write (filedesc, string, len); write (filedesc, "\n", 1); } } if (n) first = 1; /* 'literal' symbols */ for (i = 0; i < N_terms; i++) { if (term_name[seq[i]][0] == '{') continue; if (term_name[seq[i]][0] == '<') continue; if (itsakeyword (term_name[seq[i]])) continue; if (first) { first = 0; write (filedesc, "\n", 1); } write (filedesc, " ", 3); p = slash_inside (term_name[seq[i]]); len = strlen (p); write (filedesc, p, len); ns = (max_terml - len + 3); if (ns > 0) write (filedesc, spaces, ns); len = sprintf (string, "%5d", seq[i]); write (filedesc, string, len); write (filedesc, "\n", 1); } if (n) first = 1; /* {semantic} symbols (for debugging only) for (i = 0; i < N_terms; i++) { if (term_name[seq[i]][0] != '{') continue; if (first) { first = 0; write (filedesc, "\n", 1); } write (filedesc, " ", 3); k = strlen(term_name[seq[i]]); write (filedesc, term_name[seq[i]], k); ns = (max_terml - k + 3); if (ns > 0) write (filedesc, spaces, ns); len = sprintf (string, "%5d", seq[i]); write (filedesc, string, len); write (filedesc, "\n", 1); } */ FREE (seq, N_terms); len = sprintf (string, "\n/* End of %s lexical symbols. */\n\n", gfn); write (filedesc, string, len); close (filedesc); chmod (lexfid, S_IREAD); // Make output file read-only. }
void PGPrintHtml::PrintHtml () { char fid [MAX_PATH]; int line_length; int h, p, t, s, l, nh; head_on = 0; strcpy (fid, gdn); strcat (fid, gfn); strcat (fid, gft); strcat (fid, ".grammar.html"); if (optn[PG_HTML] == 0) { unlink (fid); return; } fp = fopen (fid, "w"); if (fp == NULL) { n_errors++; prt_log ("\nFile %s cannot be created.\n", fid); PG::Terminate (1); } fprintf (fp, "<head>\n"); fprintf (fp, "<title>%s grammar.</title>\n", gfn); fprintf (fp, "<meta name=\"description\" content=\"%s grammar.\">\n", gfn); fprintf (fp, "<style>\n"); fprintf (fp, "a:link { color: #000000; text-decoration: none; };\n"); fprintf (fp, "a:visited { color: #000000; text-decoration: none; };\n"); fprintf (fp, "a:hover { color: #000000; text-decoration: underline; };\n"); fprintf (fp, "a:active { color: #000000; text-decoration: underline; };\n"); fprintf (fp, "</style>\n"); fprintf (fp, "</head>\n"); fprintf (fp, "<basefont face=verdana>\n"); fprintf (fp, "<body bgcolor=\"white\" text=\"black\" link=\"blue\" vlink=\"blue\" alink=\"blue\">\n"); fprintf (fp, "<pre> <b>%s</b> grammar (output from <a href=\"http://lrtec.com/\">LRSTAR</a>).\n</pre>\n", gfn); if (optn[PG_HTML] == 0) { fprintf (fp, "<pre>\n 'h' option was not specified.</pre>\n"); goto Ret; } // NONTERMINALS. nh = N_heads; for (h = 0; h < nh; h++) { fprintf (fp, "<a name=\"%s\"><pre>", head_name[h]); fprintf (fp, "%4d ", h); ph_head (h, "</a>\n"); for (p = F_prod [h]; p < F_prod [h+1]; p++) { line_length = 16; fprintf (fp, " %4d -> ", p); for (t = F_tail [p]; t < F_tail [p+1]; t++) { s = Tail [t]; if (s >= 0) l = strlen (term_name[s]); else l = strlen (head_name[-s]); if (line_length > 16 && line_length + l > 100) { fprintf (fp, "\n "); line_length = 16; } line_length += ph_sym (s, " "); } fprintf (fp, "\n"); } fprintf (fp, "</pre>\n"); } fprintf (fp, "<pre>\n End of <b>%s</b> grammar listing.\n</pre>\n", gfn); for (h = 0; h < 30; h++) { fprintf (fp, "<pre><br></pre>\n"); } Ret: fprintf (fp, "</body>\n"); fprintf (fp, "</html>\n\n"); fclose (fp); }
int LG::Start (int na, char *arg []) /* Display program information. */ { int i, ne, filedesc, a, x, rc; char dn[256], fn[256], ft[256], string[64]; time1 = clock(); memory_usage = 0; memory_max = 0; ne = 0; n_errors = 0; max_child_usage = 0; exefid[0] = 0; illegal_char_state = -1; for (i = 0; i < 256; i++) spaces [i] = ' '; strcpy (gft, ".lgr"); strcpy (grmfid, gdn); strcat (grmfid, gfn); strcat (grmfid, gft); open_con (grmfid); open_grm (grmfid); open_sta (grmfid); strcpy (gft, ".lex"); strcpy (grmfid, gdn); strcat (grmfid, gfn); strcat (grmfid, gft); filedesc = open (grmfid, 0); // Open .lex file first. if (filedesc >= 0) // .lex file found! { prt_log ("%s.lex file: reading ...\n", gfn); if (!inputi ("%%")) return 0; lex_input_start = input_start; lex_input_end = input_end; lex_line_ptr = line_ptr; } else { prt_log ("%s.lex file: not found.\n", gfn); prt_log ("%s.lgr file: reading ...\n\n", gfn); strcpy (gft, ".lgr"); strcpy (grmfid, gdn); strcat (grmfid, gfn); strcat (grmfid, gft); if (!inputi ("")) return 0; lex_input_start = 0; lex_input_end = 0; lex_line_ptr = 0; } for (i = 0; i < 159; i++) spaces [i] = ' '; memory_usage = 0; memory_max = 0; ne = 0; n_warnings = 0; n_errors = 0; return 1; }
char* PG::slash_inside (char* term_name) { static char string[128]; char *p = term_name+1; char c = 0; int i = 1; do { if (*p != '\\') { string[i++] = *p++; if (i > 127) { n_errors++; if (n_errors == 1) prt_log ("\n"); prt_log ("In file '%s', literal is longer than 128 characters.\n\n", grmfid); PG::Terminate (6); } } else { p++; if (*p == '\'') { if (c == 0) c = '\"'; else if (c == '\'') { n_errors++; if (n_errors == 1) prt_log ("\n"); prt_log ("In file '%s', literal contains both \' and \", cannot convert for use in lexical grammar.\n", grmfid); PG::Terminate (6); } } else if (*p == '\"') { if (c == 0) c = '\''; else if (c == '\"') { n_errors++; if (n_errors == 1) prt_log ("\n"); prt_log ("In file '%s', literal contains both \' and \", cannot convert for use in lexical grammar.\n\n", grmfid); PG::Terminate (6); } } string[i++] = *p++; } } while (*p != 0); if (c != '\"') { string[0] = '\''; } else { string[0] = '\"'; string[i-1] = '\"'; } string[i] = 0; // printf ("%s\n", string); return (string); }
int LGCheckGrammar::CheckGrammar () { if (optn[LG_VERBOSE] > 2) printf ("Checking grammar for problems ...\n"); C_LENG (); C_NULLS (); C_HEADSYM (); CHECK_LEXICALS (); if (n_errors) return 0; if (optn[LG_VERBOSE] > 2) printf ("Checking for unreachable symbols ...\n"); P_UNREACHABLES (); if (n_errors) return 0; if (optn[LG_VERBOSE] > 2) printf ("Checking for undefined symbols ...\n"); P_UNDEFINED (); if (n_errors) return 0; if (optn[LG_VERBOSE] > 2) printf ("Checking for useless productions ...\n"); P_USELESS_PROD (); if (n_errors) return 0; if (optn[LG_VERBOSE] > 2) printf ("Checking for null tokens ...\n"); P_NULL_TOKENS (); if (n_errors) return 0; if (optn[LG_VERBOSE] > 2) printf ("Checking for unreducible symbols ...\n"); P_UNREDUCIBLES (); if (n_errors) return 0; if (optn[LG_VERBOSE] > 2) printf ("Checking for cycles in grammar ...\n"); C_CYCLES(); if (n_errors) return 0; FREE (head_sym, n_heads); // Free this, DO_BACK_SUB changes n_heads. prt_log ("Grammar %7d rules, ", n_prods); prt_log ("%d terminals, ", max_char_set); prt_log ("%d nonterminals.\n", n_heads); PrintGrammar (); if (n_errors > 0) return (0); FREE (head_type, n_heads); FREE (head_line, n_heads); FREE (prod_type, n_prods); FREE (prod_line, n_prods); FREE (term_line, n_terms); if (optn[LG_VERBOSE] > 2) printf ("Doing back-substitutions for null symbols ...\n"); DO_BACK_SUB (); if (optn[LG_VERBOSE] > 2) printf ("Done with back-substitutions !!!\n"); if (optn[LG_VERBOSE] > 2) PrintGrammar (); // Printing grammar for 2nd time? return (1); }