/*************************************************************** OUTPUT.C This file containts OUTPUT files writer of ZUBR. PART OF : ZUBR - Parsers generator for multiple syntax language compilers . COMPILE : . NOTE : . Copyright (C) 1995 - 2026 by Andrey V.Kosteltsev. All Rights Reserved. ***************************************************************/ /* This file contant RUSSIAN letters( code-page: UTF-8 ) ***************************************************************/ #include #ifndef __NO_COMPILE static int nvectors; static int nentries; static int **froms; static int **tos; static int *tally; static int *width; static int *state_count; static int *order; static int *base; static int *pos; static int maxtable; static int *table; static int *check; static int lowzero; static int high; /************************************************************************* The function matching_vector determines if the vector specified by the input parameter matches a previously considered vector. The test at the start of the function checks if the vector represents a row of shifts over terminal symbols or a row of reductions, or a column of shifts over a nonterminal symbol. ZUBR //and Berkeley Yacc // does not check if a column of shifts over a nonterminal symbols matches a previously considered vector. Because of the nature of LR parsing tables, no two columns can match. Therefore, the only possible match would be between a row and a column. Such matches are unlikely. Therefore, to save time, no attempt is made to see if a column matches a previously considered vector. Matching_vector is poorly designed. The test could easily be made faster. Also, it depends on the vectors being in a specific order. *************************************************************************/ int matching_vector( int vector ) /************************************************************************* Description : matching_vector Concepts : Use Global Variable: static int **froms; | this file static int **tos; | this file static int *tally; | this file static int *width; | this file static int *order; | this file int nstates; | lr0.c Use Functions : Parameters : int vector Return : int *************************************************************************/ { register int i; register int j; register int k; register int t; register int w; register int match; register int prev; i = order[vector]; if( i >= 2*nstates ) return( -1 ); t = tally[i]; w = width[i]; for( prev = vector - 1; prev >= 0; prev-- ) { j = order[prev]; if( width[j] != w || tally[j] != t ) return( -1 ); match = 1; for( k = 0; match && k < t; k++ ) { if( tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k] ) match = 0; } if( match ) return( j ); } return( -1 ); } /******* End of matching_vector( int vector ) ************************/ int pack_vector( int vector ) /************************************************************************* Description : pack_vector Concepts : Use Global Variable: static int **froms; | this file static int **tos; | this file static int *tally; | this file static int *order; | this file static int *pos; | this file static int maxtable; | this file static int *table; | this file static int *check; | this file static int lowzero; | this file static int high; | this file Use Functions : void fatal( char * ); | error.c void no_space( void ); | error.c Parameters : int vector Return : int *************************************************************************/ { register int i, j, k, l; register int t; register int loc; register int ok; register int *from; register int *to; int newmax; i = order[vector]; t = tally[i]; if( !t ) { done( 2 ); } from = froms[i]; to = tos[i]; j = lowzero - from[0]; for( k = 1; k < t; ++k ) if( lowzero - from[k] > j ) j = lowzero - from[k]; for( ;; ++j ) { if( j == 0 ) continue; ok = 1; for( k = 0; ok && k < t; k++ ) { loc = j + from[k]; if( loc >= maxtable ) { if( loc >= MAXTABLE ) fatal( (__mpu_char16_t *)MPU_UCS2( "Maximum table size exceeded" ) ); newmax = maxtable; do { newmax += 200; } while( newmax <= loc ); table = (int *)REALLOC( table, newmax*sizeof( int ) ); if (table == 0) no_space (); check = (int *)REALLOC( check, newmax*sizeof( int ) ); if( check == 0 ) no_space(); for( l = maxtable; l < newmax; ++l ) { table[l] = 0; check[l] = -1; } maxtable = newmax; } if( check[loc] != -1 ) ok = 0; } /* End of for( k = 0; ok && k < t; k++ ) */ for( k = 0; ok && k < vector; k++ ) { if( pos[k] == j ) ok = 0; } if( ok ) { for( k = 0; k < t; k++ ) { loc = j + from[k]; table[loc] = to[k]; check[loc] = from[k]; if( loc > high ) high = loc; } while( check[lowzero] != -1 ) ++lowzero; return( j ); } } /* End of for( ;; ++j ) */ } /******* End of pack_vector( int vector ) ****************************/ int default_goto( int symbol ) /************************************************************************* Description : default_goto Concepts : Use Global Variable: static int *state_count; | this file int *goto_map; | lalr.c int *to_state; | lalr.c int nstates; | lr0.c Use Functions : Parameters : int symbol Return : int *************************************************************************/ { register int i; register int m; register int n; register int default_state; register int max; m = goto_map[symbol]; n = goto_map[symbol + 1]; if( m == n ) return( 0 ); for( i = 0; i < nstates; i++ ) state_count[i] = 0; for( i = m; i < n; i++ ) state_count[to_state[i]]++; max = 0; default_state = 0; for( i = 0; i < nstates; i++ ) { if( state_count[i] > max ) { max = state_count[i]; default_state = i; } } return( default_state ); } /******* Emd of default_goto( int symbol ) ***************************/ void save_column( int symbol, int default_state ) /************************************************************************* Description : save_column Concepts : Use Global Variable: static int **froms; | this file static int **tos; | this file static int *tally; | this file static int *width; | this file int *goto_map; | lalr.c int *from_state; | lalr.c int *to_state; | lalr.c int *symbol_value; | main.c Use Functions : Parameters : int symbol, int default_state Return : [void] *************************************************************************/ { register int i; register int m; register int n; register int *sp; register int *sp1; register int *sp2; register int count; register int symno; m = goto_map[symbol]; n = goto_map[symbol + 1]; count = 0; for( i = m; i < n; i++ ) { if( to_state[i] != default_state ) ++count; } if( count == 0 ) return; symno = symbol_value[symbol] + 2*nstates; froms[symno] = sp1 = sp = NEW2( count, int ); tos[symno] = sp2 = NEW2( count, int ); for( i = m; i < n; i++ ) { if( to_state[i] != default_state ) { *sp1++ = from_state[i]; *sp2++ = to_state[i]; } } tally[symno] = count; width[symno] = sp1[-1] - sp[0] + 1; } /******* End of save_column( int symbol, int default_state ) *********/ void output_check( void ) /************************************************************************* Description : output_check Concepts : Use Global Variable: static int *check; | this file char rflag; | main.c mpu_FILE *output_file; | main.c int outline; | main.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register int i; register int j; if( sflag ) { /* это условие факт. не нужно, т.к. -B сбрасывает -s но тут надо подумать стоит ли сбрасывать -s */ if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "static int %szubr_check[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "static int zubr_check[] =" ) ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "int %szubr_check[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "int zubr_check[] =" ) ); } if( !rflag ) outline += 2; mpu_fprintf( output_file, MPU_UCS2( "\n{\n" ) ); j = 0; for( i = 0; i <= high; i++ ) { if( j >= 10 ) { if( !rflag ) ++outline; mpu_putc( '\n', output_file ); j = 1; } else ++j; mpu_fprintf( output_file, MPU_UCS2( "%6d," ), check[i] ); } if( !rflag ) outline += 3; mpu_fprintf( output_file, MPU_UCS2( "\n};\n\n" ) ); FREE( check ); } /******* End of output_check( void ) *********************************/ void output_table( void ) /************************************************************************* Description : output_table Concepts : Use Global Variable: static int *table; | this file static int high; | this file char rflag; | main.c mpu_FILE *code_file; | main.c mpu_FILE *output_file; | main.c int outline; | main.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register int i; register int j; ++outline; if( bflag ) mpu_fprintf( code_file, MPU_UCS2( "#define %sZUBR_TABLESIZE %d\n" ), name_prefix_upper, high); else mpu_fprintf( code_file, MPU_UCS2( "#define ZUBR_TABLESIZE %d\n" ), high ); if( sflag ) { /* это условие факт. не нужно, т.к. -B сбрасывает -s но тут надо подумать стоит ли сбрасывать -s */ if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "static int %szubr_table[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "static int zubr_table[] =" ) ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "int %szubr_table[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "int zubr_table[] =" ) ); } if( !rflag ) outline += 2; mpu_fprintf( output_file, MPU_UCS2( "\n{\n" ) ); j = 0; for( i = 0; i <= high; i++ ) { if( j >= 10 ) { if( !rflag ) ++outline; mpu_putc( '\n', output_file ); j = 1; } else ++j; mpu_fprintf( output_file, MPU_UCS2( "%6d," ), table[i] ); } if( !rflag ) outline += 3; mpu_fprintf( output_file, MPU_UCS2( "\n};\n\n" ) ); FREE( table ); } /******* End of output_table( void ) *********************************/ void output_base( void ) /************************************************************************* Description : output_base Concepts : Use Global Variable: static int nvectors; | this file static int *base; | this file int nstates; | lr0.c char rflag; | main.c mpu_FILE *output_file; | main.c int outline; | main.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register int i, j; if( sflag ) { /* это условие факт. не нужно, т.к. -B сбрасывает -s но тут надо подумать стоит ли сбрасывать -s */ if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "static int %szubr_sindex[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "static int zubr_sindex[] =" ) ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "int %szubr_sindex[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "int zubr_sindex[] =" ) ); } if( !rflag ) outline += 2; mpu_fprintf( output_file, MPU_UCS2( "\n{\n" ) ); j = 0; for( i = 0; i < nstates; i++ ) { if( j >= 10 ) { if( !rflag ) ++outline; mpu_putc( '\n', output_file ); j = 1; } else ++j; mpu_fprintf( output_file, MPU_UCS2( "%6d," ), base[i] ); } if( !rflag ) outline += 3; if( sflag ) { /* это условие факт. не нужно, т.к. -B сбрасывает -s но тут надо подумать стоит ли сбрасывать -s */ if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "\n};\n\nstatic int %szubr_rindex[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "\n};\n\nstatic int zubr_rindex[] =" ) ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "\n};\n\nint %szubr_rindex[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "\n};\n\nint zubr_rindex[] =" ) ); } if( !rflag ) outline += 2; mpu_fprintf( output_file, MPU_UCS2( "\n{\n" ) ); j = 0; for( i = nstates; i < 2*nstates; i++ ) { if( j >= 10 ) { if( !rflag ) ++outline; mpu_putc( '\n', output_file ); j = 1; } else ++j; mpu_fprintf( output_file, MPU_UCS2( "%6d," ), base[i] ); } if( !rflag ) outline += 3; if( sflag ) { /* это условие факт. не нужно, т.к. -B сбрасывает -s но тут надо подумать стоит ли сбрасывать -s */ if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "\n};\n\nstatic int %szubr_gindex[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "\n};\n\nstatic int zubr_gindex[] =" ) ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "\n};\n\nint %szubr_gindex[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "\n};\n\nint zubr_gindex[] =" ) ); } if( !rflag ) outline += 2; mpu_fprintf( output_file, MPU_UCS2( "\n{\n" ) ); j = 0; for( i = 2*nstates; i < nvectors - 1; i++ ) { if( j >= 10 ) { if( !rflag ) ++outline; mpu_putc( '\n', output_file ); j = 1; } else ++j; mpu_fprintf( output_file, MPU_UCS2( "%6d," ), base[i] ); } if( !rflag ) outline += 3; mpu_fprintf( output_file, MPU_UCS2( "\n};\n\n" ) ); FREE( base ); } /******* End of output_base( void ) **********************************/ void pack_table( void ) /************************************************************************* Description : pack_table Concepts : Use Global Variable: static int nvectors; | this file static int nentries; | this file static int **froms; | this file static int **tos; | this file static int *base; | this file static int *pos; | this file static int maxtable; | this file static int *table; | this file static int *check; | this file static int lowzero; | this file static int high; | this file Use Functions : int pack_vector( int ); | this file int matching_vector( int ); | this file Parameters : [void] Return : [void] *************************************************************************/ { register int i; register int place; register int state; base = NEW2( nvectors, int ); pos = NEW2( nentries, int ); maxtable = 1024; /* 0x400 */ table = NEW2( maxtable, int ); check = NEW2( maxtable, int ); lowzero = 0; high = 0; for( i = 0; i < maxtable; i++ ) check[i] = -1; for( i = 0; i < nentries; i++ ) { state = matching_vector( i ); if( state < 0 ) place = pack_vector( i ); else place = base[state]; pos[i] = place; base[order[i]] = place; } for( i = 0; i < nvectors; i++ ) { if( froms[i] ) FREE( froms[i] ); if( tos[i] ) FREE( tos[i] ); } FREE( froms ); FREE( tos ); FREE( pos ); } /******* End of pack_table( void ) ***********************************/ void sort_actions( void ) /************************************************************************* Description : sort_actions Concepts : Use Global Variable: static int nvectors; | this file static int nentries; | this file static int *tally; | this file static int *width; | this file static int *order; | this file Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register int i; register int j; register int k; register int t; register int w; order = NEW2( nvectors, int ); nentries = 0; for( i = 0; i < nvectors; i++ ) { if( tally[i] > 0 ) { t = tally[i]; w = width[i]; j = nentries - 1; while( j >= 0 && (width[order[j]] < w) ) j--; while( j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t) ) j--; for( k = nentries - 1; k > j; k-- ) order[k + 1] = order[k]; order[j + 1] = i; nentries++; } } } /******* End of sort_actions( void ) *********************************/ void goto_actions( void ) /************************************************************************* Description : goto_actions Concepts : Use Global Variable: static int *state_count; | this file int nsyms; | main.c int start_symbol; | main.c mpu_FILE *output_file; | main.c int outline; | main.c int nstates; | lr0.c Use Functions : void save_column(int, int ); | this file int default_goto( int ); | this file Parameters : [void] Return : [void] *************************************************************************/ { register int i, j, k; state_count = NEW2( nstates, int ); if( sflag ) { /* это условие факт. не нужно, т.к. -B сбрасывает -s но тут надо подумать стоит ли сбрасывать -s */ if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "static int %szubr_dgoto[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "static int zubr_dgoto[] =" ) ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "int %szubr_dgoto[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "int zubr_dgoto[] =" ) ); } if( !rflag ) outline += 2; mpu_fprintf( output_file, MPU_UCS2( "\n{\n" ) ); j = 0; for( i = start_symbol + 1; i < nsyms; i++ ) { if( j >= 10 ) { if( !rflag ) ++outline; mpu_putc( '\n', output_file ); j = 1; } else ++j; k = default_goto( i ); mpu_fprintf( output_file, MPU_UCS2( "%6d," ), k ); save_column( i, k ); } if( !rflag ) outline += 3; mpu_fprintf( output_file, MPU_UCS2( "\n};\n\n" ) ); FREE( state_count ); } /******* End of goto_actions( void ) *********************************/ void token_actions( void ) /************************************************************************* Description : token_actions Concepts : Use Global Variable: static int **froms; | this file static int **tos; | this file static int *tally; | this file static int *width; | this file int nstates; | lr0.c int ntokens; | main.c int *symbol_value; | main.c action **parser; | mkpar.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register int i, j; register int shiftcount, reducecount; register int max, min; register int *actionrow, *r, *s;/*short*/ register action *p; actionrow = NEW2( 2*ntokens, int ); for( i = 0; i < nstates; ++i ) { if( parser[i] ) { for( j = 0; j < 2*ntokens; ++j ) actionrow[j] = 0; shiftcount = 0; reducecount = 0; for( p = parser[i]; p; p = p->next ) { if( p->suppressed == 0 ) { if( p->action_code == SHIFT ) { ++shiftcount; actionrow[p->symbol] = p->number; } else if( p->action_code == REDUCE && p->number != defred[i] ) { ++reducecount; actionrow[p->symbol + ntokens] = p->number; } } /* End if( p->suppressed == 0 ) */ } /* End of for( p = parser[i]; p; p = p->next ) */ tally[i] = shiftcount; tally[nstates+i] = reducecount; width[i] = 0; width[nstates+i] = 0; if( shiftcount > 0 ) { froms[i] = r = NEW2( shiftcount, int ); tos[i] = s = NEW2( shiftcount, int ); min = MAXWORD; max = 0; for( j = 0; j < ntokens; ++j ) { if( actionrow[j] ) { if( min > symbol_value[j] ) min = symbol_value[j]; if( max < symbol_value[j] ) max = symbol_value[j]; *r++ = symbol_value[j]; *s++ = actionrow[j]; } } width[i] = max - min + 1; } /* End if( shiftcount > 0 ) */ if( reducecount > 0 ) { froms[nstates+i] = r = NEW2( reducecount, int ); tos[nstates+i] = s = NEW2( reducecount, int ); min = MAXWORD; max = 0; for( j = 0; j < ntokens; ++j ) { if( actionrow[ntokens+j] ) { if( min > symbol_value[j] ) min = symbol_value[j]; if( max < symbol_value[j] ) max = symbol_value[j]; *r++ = symbol_value[j]; *s++ = actionrow[ntokens+j] - 2; } } width[nstates+i] = max - min + 1; } /* End if( reducecount > 0 ) */ } /* End if( parser[i] ) */ } /* End of for( i = 0; i < nstates; ++i ) */ FREE( actionrow ); } /******* End of token_actions( void ) ********************************/ int is_C_identifier( __mpu_char16_t *name ) /************************************************************************* Description : is_C_identifier Concepts : Use Global Variable: Use Functions : Parameters : char *name Return : int *************************************************************************/ { register __mpu_char16_t *s; register int c; s = name; c = *s; if( c == '"' ) { c = *++s; if( !zubr_is_alpha(c) && c != '_' && c != '$' ) return( 0 ); while( (c = *++s) != '"' ) { if( !zubr_is_alnum(c) && c != '_' && c != '$' ) return( 0 ); } return( 1 ); } if( !zubr_is_alpha(c) && c != '_' && c != '$' ) return( 0 ); while( (c = *++s) ) { if( !zubr_is_alnum(c) && c != '_' && c != '$' ) return( 0 ); } return( 1 ); } /******* End of is_C_identifier( char *name ) ************************/ void output_semantic_actions( void ) /************************************************************************* Description : output_semantic_actions Concepts : Use Global Variable: mpu_FILE *action_file; | main.c char *action_file_name; | main.c mpu_FILE *code_file; | main.c char *code_file_name; | main.c int outline; | main.c char line_format[]; | reader.c Use Functions : void open_error( char * ); | error.c Parameters : [void] Return : [void] *************************************************************************/ { register int c, last; register mpu_FILE *out; mpu_fclose( action_file ); action_file = zubr_fopen( action_file_name, "r" ); if( action_file == NULL ) open_error( action_file_name ); if( (c = mpu_getc( action_file )) == mpu_EOF ) return; out = code_file; last = c; if( c == '\n' ) ++outline; mpu_putc( c, out ); while( (c = mpu_getc( action_file )) != mpu_EOF ) { if( c == '\n' ) ++outline; mpu_putc( c, out ); last = c; } if( last != '\n' ) { ++outline; mpu_putc( '\n', out ); } if( !lflag ) mpu_fprintf( out, line_format, ++outline + 1, code_file_name); } /******* End of output_semantic_actions( void ) **********************/ void output_trailing_text( void ) /************************************************************************* Description : output_trailing_text Concepts : Use Global Variable: char lflag; | main.c mpu_FILE *input_file; | main.c char *input_file_name; | main.c mpu_FILE *code_file; | main.c char *code_file_name; | main.c int lineno; | main.c int outline; | main.c char *cptr; | reader.c char *line; | reader.c char line_format[]; | reader.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register int c, last; register mpu_FILE *in, *out; if( line == 0 ) return; in = input_file; out = code_file; c = *cptr; if( c == '\n' ) { ++lineno; if( (c = mpu_getc( in )) == mpu_EOF ) return; if( !lflag ) { ++outline; mpu_fprintf( out, line_format, lineno, input_file_name ); } if( c == '\n' ) ++outline; mpu_putc( c, out ); last = c; } else { if( !lflag ) { ++outline; mpu_fprintf( out, line_format, lineno, input_file_name ); } do { mpu_putc( c, out ); } while( (c = *++cptr) != '\n' ); ++outline; mpu_putc( '\n', out ); last = '\n'; } while( (c = mpu_getc( in )) != mpu_EOF ) { if( c == '\n' ) ++outline; mpu_putc( c, out ); last = c; } if( mpu_ferror( in ) ) input_error(); if( last != '\n' ) { ++outline; mpu_putc( '\n', out ); } if( !lflag ) mpu_fprintf( out, line_format, ++outline + 1, code_file_name ); } /******* End of output_trailing_text( void ) *************************/ void output_stype( void ) /************************************************************************* Description : output_stype Concepts : Use Global Variable: int ntags; | main.c mpu_FILE *code_file; | main.c int outline; | main.c char unionized; | reader.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { if( !unionized && ntags == 0 ) { outline += 4; if( bflag ) mpu_fprintf( code_file, MPU_UCS2( "#ifndef %sZUBR_STYPE\ntypedef int %sZUBR_STYPE;\n#endif\n\n" ), name_prefix_upper, name_prefix_upper ); else mpu_fprintf( code_file, MPU_UCS2( "#ifndef ZUBR_STYPE\ntypedef int ZUBR_STYPE;\n#endif\n\n" ) ); } } /******* End of output_stype( void ) *********************************/ void output_debug( void ) /************************************************************************* Description : output_debug Concepts : Use Global Variable: int final_state; | mkpar.c char rflag; | main.c char tflag; | main.c int ntokens; | main.c int nrules; | main.c char **symbol_name; | main.c int *symbol_value; | main.c int *ritem; | main.c int *rrhs; | main.c int *rlhs; | main.c mpu_FILE *code_file; | main.c mpu_FILE *output_file; | main.c int outline; | main.c Use Functions : void no_space( void ); | error.c Parameters : [void] Return : [void] *************************************************************************/ { register int i, j, k, max; __mpu_char16_t **symnam, *s; __mpu_char16_t *_char_type = (__mpu_char16_t *)MPU_UCS2( "__mpu_char16_t" ); ++outline; if( bflag ) mpu_fprintf( code_file, MPU_UCS2( "#define %sZUBR_FINAL %d\n" ), name_prefix_upper, final_state ); else mpu_fprintf( code_file, MPU_UCS2( "#define ZUBR_FINAL %d\n" ), final_state ); outline += 3; if( bflag ) mpu_fprintf( code_file, MPU_UCS2( "#ifndef %sZUBR_DEBUG\n#define %sZUBR_DEBUG %d\n#endif\n" ), name_prefix_upper, name_prefix_upper, tflag ); else mpu_fprintf( code_file, MPU_UCS2( "#ifndef ZUBR_DEBUG\n#define ZUBR_DEBUG %d\n#endif\n" ), tflag ); if( rflag ) { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "#ifndef %sZUBR_DEBUG\n#define %sZUBR_DEBUG %d\n#endif\n" ), name_prefix_upper, name_prefix_upper, tflag ); else mpu_fprintf( output_file, MPU_UCS2( "#ifndef ZUBR_DEBUG\n#define ZUBR_DEBUG %d\n#endif\n" ), tflag ); } max = 0; for( i = 2; i < ntokens; ++i ) if( symbol_value[i] > max ) max = symbol_value[i]; ++outline; if( bflag ) mpu_fprintf( code_file, MPU_UCS2( "#define %sZUBR_MAXTOKEN %d\n" ), name_prefix_upper, max ); else mpu_fprintf( code_file, MPU_UCS2( "#define ZUBR_MAXTOKEN %d\n" ), max ); symnam = (__mpu_char16_t **)MALLOC( (max+1)*sizeof(__mpu_char16_t *) ); if( symnam == 0 ) no_space(); /* Note that it is not necessary to initialize the element */ /* symnam[max]. */ for( i = 0; i < max; ++i ) symnam[i] = 0; for( i = ntokens - 1; i >= 2; --i ) symnam[symbol_value[i]] = symbol_name[i]; symnam[0] = (__mpu_char16_t *)MPU_UCS2( "end-of-file" ); if( !rflag ) ++outline; if( sflag ) { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "#if %sZUBR_DEBUG\nstatic %s *%szubr_name[] =" ), name_prefix_upper, _char_type, name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "#if ZUBR_DEBUG\nstatic %s *zubr_name[] =" ), _char_type ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "#if %sZUBR_DEBUG\n%s *%szubr_name[] =" ), name_prefix_upper, _char_type, name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "#if ZUBR_DEBUG\n%s *zubr_name[] =" ), _char_type ); } if( !rflag ) ++outline; mpu_fprintf( output_file, MPU_UCS2( "\n{" ) ); j = 80; for( i = 0; i <= max; ++i ) { if( (s = symnam[i]) ) { if( s[0] == '"' ) { k = 7; while( *++s != '"' ) { ++k; if( *s == '\\' ) { k += 2; if( *++s == '\\' ) ++k; } } j += k; if( j > 80 ) { if( !rflag ) ++outline; mpu_fprintf( output_file, MPU_UCS2( "\n " ) ); j = k; } mpu_fprintf( output_file, MPU_UCS2( "u\"\\\"" ) ); s = symnam[i]; while( *++s != '"' ) { if( *s == '\\' ) { mpu_fprintf( output_file, MPU_UCS2( "\\\\" ) ); if( *++s == '\\' ) mpu_fprintf( output_file, MPU_UCS2( "\\\\" ) ); else mpu_putc( *s, output_file ); } else mpu_putc( *s, output_file ); } mpu_fprintf( output_file, MPU_UCS2( "\\\"\"," ) ); } /* End if( s[0] == '"' ) */ else if( s[0] == '\'' ) { if( s[1] == '"' ) { j += 7; if( j > 80 ) { if( !rflag ) ++outline; mpu_putc( '\n', output_file ); j = 7; } mpu_fprintf( output_file, MPU_UCS2( "u\"'\\\"'\"," ) ); } else { k = 5; while( *++s != '\'' ) { ++k; if( *s == '\\' ) { k += 2; if ( *++s == '\\' ) ++k; } } j += k; if( j > 80 ) { if( !rflag ) ++outline; mpu_fprintf( output_file, MPU_UCS2( "\n " ) ); j = k; } mpu_fprintf( output_file, MPU_UCS2( "u\"'" ) ); s = symnam[i]; while( *++s != '\'' ) { if( *s == '\\' ) { mpu_fprintf( output_file, MPU_UCS2( "\\\\" ) ); if( *++s == '\\' ) mpu_fprintf( output_file, MPU_UCS2( "\\\\" ) ); else mpu_putc( *s, output_file ); } else mpu_putc( *s, output_file ); } mpu_fprintf( output_file, MPU_UCS2( "'\"," ) ); } } /* End if( s[0] == '\'' ) */ else { k = mpu_str16len( s ) + 3; j += k; if( j > 80 ) { if( !rflag ) ++outline; mpu_fprintf( output_file, MPU_UCS2( "\n " ) ); j = k; } mpu_fprintf( output_file, MPU_UCS2( "u\"" ) ); do { mpu_putc( *s, output_file ); } while( *++s ); mpu_fprintf( output_file, MPU_UCS2( "\"," ) ); } } /* End if( s = symnam[i] ) */ else { j += 2; if( j > 80 ) { if( !rflag ) ++outline; mpu_fprintf( output_file, MPU_UCS2( "\n " ) ); j = 2; } mpu_fprintf( output_file, MPU_UCS2( "0," ) ); } } /* End of for (i = 0; i <= max; ++i) */ if( !rflag ) outline += 3; mpu_fprintf( output_file, MPU_UCS2( "\n};\n\n" ) ); FREE( symnam ); if( !rflag ) ++outline; if( sflag ) { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "static %s *%szubr_rule[] =\n" ), _char_type, name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "static %s *zubr_rule[] =\n" ), _char_type ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "%s *%szubr_rule[] =\n" ), _char_type, name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "%s *zubr_rule[] =\n" ), _char_type ); } if( !rflag ) ++outline; mpu_fprintf( output_file, MPU_UCS2( "{\n" ) ); for( i = 2; i < nrules; ++i ) { mpu_fprintf( output_file, MPU_UCS2( " MPU_UCS2(\"" ) ); mpu_fprintf( output_file, MPU_UCS2( "%s :" ), symbol_name[rlhs[i]] ); for( j = rrhs[i]; ritem[j] > 0; ++j ) { s = symbol_name[ritem[j]]; if( s[0] == '"' ) { mpu_fprintf( output_file, MPU_UCS2( " \\\"" ) ); while( *++s != '"' ) { if( *s == '\\' ) { if( s[1] == '\\' ) mpu_fprintf( output_file, MPU_UCS2( "\\\\\\\\" ) ); else { mpu_fprintf( output_file, MPU_UCS2( "\\\\" ) ); mpu_putc( s[1], output_file ); } ++s; } else mpu_putc( *s, output_file ); } mpu_fprintf( output_file, MPU_UCS2( "\\\"" ) ); } else if( s[0] == '\'' ) { if( s[1] == '"' ) mpu_fprintf( output_file, MPU_UCS2( " '\\\"'" ) ); else if( s[1] == '\\' ) { if( s[2] == '\\' ) mpu_fprintf( output_file, MPU_UCS2( " '\\\\\\\\" ) ); else { mpu_fprintf( output_file, MPU_UCS2( " '\\\\" ) ); mpu_putc( s[2], output_file ); } s += 2; while( *++s != '\'' ) mpu_putc( *s, output_file ); mpu_putc( '\'', output_file ); } else { mpu_fprintf( output_file, MPU_UCS2( " '" ) ); mpu_putc( s[1], output_file ); mpu_fprintf( output_file, MPU_UCS2( "'" ) ); } } else mpu_fprintf( output_file, MPU_UCS2( " %s" ), s ); } /* End of for (j = rrhs[i]; ritem[j] > 0; ++j) */ if( !rflag ) ++outline; mpu_fprintf( output_file, MPU_UCS2( "\"),\n" ) ); } /* End of for (i = 2; i < nrules; ++i) */ if( !rflag ) outline += 3; mpu_fprintf( output_file, MPU_UCS2( "};\n#endif\n\n" ) ); if( rflag ) { /* Print 'End of FILE' into z_tab.c */ mpu_fprintf( output_file, MPU_UCS2( "\ /************************ End of File **************************/\n" ) ); } } /******* End of output_debug( void ) *********************************/ void output_actions( void ) /************************************************************************* Description : output_actions Concepts : Use Global Variable: static int nvectors; | this file static int **froms; | this file static int **tos; | this file static int *tally; | this file static int *width; | this file int *lookaheads; | lalr.c int *LAruleno; | lalr.c unsigned *LA; | lalr.c int *accessing_symbol; | lalr.c int *goto_map; | lalr.c int *from_state; | lalr.c int *to_state; | lalr.c int nstates; | lr0.c int ntokens; | main.c int nvars; | main.c Use Functions : void output_check( void ); | this file void output_table( void ); | this file void output_base( void ); | this file void pack_table( void ); | this file void sort_actions( void ); | this file void goto_actions( void ); | this file void token_actions( void ); | this file Parameters : [void] Return : [void] *************************************************************************/ { nvectors = 2*nstates + nvars; froms = NEW2( nvectors, int * ); tos = NEW2( nvectors, int * ); tally = NEW2( nvectors, int ); width = NEW2( nvectors, int ); token_actions(); FREE( lookaheads ); FREE( LA ); FREE( LAruleno ); FREE( accessing_symbol ); goto_actions(); FREE( goto_map + ntokens ); FREE( from_state ); FREE( to_state ); sort_actions(); pack_table(); output_base(); output_table(); output_check(); } /******* End of output_actions( void ) *******************************/ void output_zubr_defred( void ) /************************************************************************* Description : output_zubr_defred Concepts : Use Global Variable: int nstates; | lr0.c char rflag; | main.c mpu_FILE *output_file; | main.c int outline; | main.c int *defred; | mkpar.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register int i, j; if( sflag ) { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "static int %szubr_defred[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "static int zubr_defred[] =" ) ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "int %szubr_defred[] =" ), name_prefix ); else mpu_fprintf( output_file, MPU_UCS2( "int zubr_defred[] =" ) ); } if( !rflag ) outline += 2; mpu_fprintf( output_file, MPU_UCS2( "\n{\n" ) ); j = 0; for( i = 0; i < nstates; i++ ) { if( j < 10 ) ++j; else { if( !rflag ) ++outline; mpu_putc( '\n', output_file ); j = 1; } mpu_fprintf( output_file, MPU_UCS2( "%6d," ), (defred[i] ? defred[i] - 2 : 0) ); } if( !rflag ) outline += 3; mpu_fprintf( output_file, MPU_UCS2( "\n};\n\n" ) ); } /******* End of output_zubr_defred( void ) ***************************/ void output_rule_data( void ) /************************************************************************* Description : output_rule_data Concepts : Use Global Variable: char rflag; | main.c int nrules; | main.c int start_symbol; | main.c int *symbol_value; | main.c int *rrhs; | main.c int *rlhs; | main.c mpu_FILE *output_file; | main.c int outline; | main.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register int i; register int j; if( !rflag ) outline +=2; else { /* Print 'HEADER' into file z_tab.c */ mpu_fprintf( output_file, MPU_UCS2( "\n\ /***************************************************************\n\ This file prodused by ZUBR for save the read-only tables.\n\ ***************************************************************/\n\n\n" ) ); } if( sflag ) { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "static int %szubr_lhs[] =\n{\n%6d," ), name_prefix, symbol_value[start_symbol] ); else mpu_fprintf( output_file, MPU_UCS2( "static int zubr_lhs[] =\n{\n%6d," ), symbol_value[start_symbol] ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "int %szubr_lhs[] =\n{\n%6d," ), name_prefix, symbol_value[start_symbol] ); else mpu_fprintf( output_file, MPU_UCS2( "int zubr_lhs[] =\n{\n%6d," ), symbol_value[start_symbol] ); } j = 1; for( i = 3; i < nrules; i++ ) { if( j >= 10 ) { if( !rflag) ++outline; mpu_putc( '\n', output_file ); j = 1; } else ++j; mpu_fprintf( output_file, MPU_UCS2( "%6d," ), symbol_value[rlhs[i]] ); } if( !rflag ) outline += 3; mpu_fprintf( output_file, MPU_UCS2( "\n};\n\n" ) ); if( !rflag ) outline +=2; if( sflag ) { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "static int %szubr_len[] =\n{\n%6d," ), name_prefix, 2 ); else mpu_fprintf( output_file, MPU_UCS2( "static int zubr_len[] =\n{\n%6d," ), 2 ); } else { if( bflag ) mpu_fprintf( output_file, MPU_UCS2( "int %szubr_len[] =\n{\n%6d," ), name_prefix, 2 ); else mpu_fprintf( output_file, MPU_UCS2( "int zubr_len[] =\n{\n%6d," ), 2 ); } j = 1; for( i = 3; i < nrules; i++ ) { if( j >= 10 ) { if( !rflag ) ++outline; mpu_putc( '\n', output_file ); j = 1; } else j++; mpu_fprintf( output_file, MPU_UCS2( "%6d," ), rrhs[i + 1] - rrhs[i] - 1 ); } if( !rflag ) outline += 3; mpu_fprintf( output_file, MPU_UCS2( "\n};\n\n" ) ); } /******* End of output_rule_data( void ) *****************************/ void output_defines( void ) /************************************************************************* Description : output_defines Concepts : Use Global Variable: char dflag; | main.c int ntokens; | main.c char **symbol_name; | main.c int *symbol_value; | main.c mpu_FILE *union_file; | main.c char *union_file_name; | main.c mpu_FILE *code_file; | main.c mpu_FILE *defines_file; | main.c int outline; | main.c char unionized; | reader.c Use Functions : int is_C_identifier( char * ); | this file void open_error( char * ); | error.c Parameters : [void] Return : [void] *************************************************************************/ { register int c, i; register __mpu_char16_t *s; if( dflag ) { mpu_fprintf( defines_file, MPU_UCS2( "\n\ /***************************************************************\n\ This file prodused by ZUBR for used token definitions and\n\ union declaration.\n\ ***************************************************************/\n" ) ); } ++outline; mpu_putc( '\n', code_file ); if( dflag ) mpu_putc( '\n', defines_file ); if( !iflag ) { for( i = 2; i < ntokens; ++i ) { s = symbol_name[i]; if( is_C_identifier( s ) ) { mpu_fprintf( code_file, MPU_UCS2( "#define " ) ); if( dflag ) mpu_fprintf( defines_file, MPU_UCS2( "#define " ) ); c = *s; if( c == '"' ) { while( (c = *++s) != '"' ) { mpu_putc( c, code_file ); if( dflag ) mpu_putc( c, defines_file ); } } else { do { mpu_putc( c, code_file ); if( dflag ) mpu_putc( c, defines_file ); } while( (c = *++s) ); } ++outline; mpu_fprintf( code_file, MPU_UCS2( " %d\n" ), symbol_value[i] ); if( dflag ) mpu_fprintf( defines_file, MPU_UCS2( " %d\n" ), symbol_value[i] ); } } /* End of for( i = 2; i < ntokens; ++i ) */ } /* End if( !iflag ) */ else { ++outline; mpu_fprintf( code_file, MPU_UCS2( "#include \"%s\"\n" ), inc_token_filename ); if( dflag ) mpu_fprintf( defines_file, MPU_UCS2( "#include \"%s\"\n" ), inc_token_filename ); } ++outline; mpu_putc( '\n', code_file ); if( dflag ) mpu_putc( '\n', defines_file ); outline += 2; if( bflag ) mpu_fprintf( code_file, MPU_UCS2( "#define %sZUBR_ERRCODE %d\n\n" ), name_prefix_upper, symbol_value[1] ); else mpu_fprintf( code_file, MPU_UCS2( "#define ZUBR_ERRCODE %d\n\n" ), symbol_value[1] ); if( dflag && unionized ) { mpu_fclose( union_file ); union_file = zubr_fopen( union_file_name, "r" ); if( union_file == NULL ) open_error( union_file_name ); while( (c = mpu_getc( union_file )) != mpu_EOF ) mpu_putc( c, defines_file ); if( bflag ) mpu_fprintf( defines_file, MPU_UCS2( " %sZUBR_STYPE;\n\nextern %sZUBR_STYPE %szubr_lval;\n\n" ), name_prefix_upper, name_prefix_upper, name_prefix ); else mpu_fprintf( defines_file, MPU_UCS2( " ZUBR_STYPE;\n\nextern ZUBR_STYPE zubr_lval;\n\n" ) ); } if( dflag ) { mpu_fprintf( defines_file, MPU_UCS2( "\ /************************ End of File **************************/\n" ) ); } } /******* End of output_defines( void ) *******************************/ void output_stored_text( void ) /************************************************************************* Description : output_stored_text Concepts : Use Global Variable: mpu_FILE *text_file; | main.c char *text_file_name; | main.c mpu_FILE *code_file; | main.c char *code_file_name; | main.c int outline; | main.c char line_format[]; | reader.c Use Functions : void open_error( char * ); | error.c Parameters : [void] Return : [void] *************************************************************************/ { register int c; register mpu_FILE *in, *out; mpu_fclose( text_file ); text_file = zubr_fopen( text_file_name, "r" ); if( text_file == NULL ) open_error( text_file_name ); in = text_file; if( (c = mpu_getc( in )) == mpu_EOF ) return; out = code_file; if( c == '\n' ) ++outline; mpu_putc( c, out ); while( (c = mpu_getc( in )) != mpu_EOF ) { if( c == '\n' ) ++outline; mpu_putc( c, out ); } if( !lflag ) mpu_fprintf( out, line_format, ++outline + 1, code_file_name ); } /******* End of output_stored_text( void ) ***************************/ void free_reductions( void ) /************************************************************************* Description : free_reductions Concepts : Use Global Variable: reductions **reduction_table; | lalr.c reductions *first_reduction; | lr0.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register reductions *rp, *next; FREE( reduction_table ); for( rp = first_reduction; rp; rp = next ) { next = rp->next; FREE( rp ); } } /******* End of free_reductions( void ) ******************************/ void free_shifts( void ) /************************************************************************* Description : free_shifts Concepts : Use Global Variable: shifts **shift_table; | lalr.c shifts *first_shift; | lr0.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register shifts *sp, *next; FREE( shift_table ); for( sp = first_shift; sp; sp = next ) { next = sp->next; FREE( sp ); } } /******* End of free_shifts( void ) **********************************/ void free_itemsets( void ) /************************************************************************* Description : free_itemsets Concepts : Use Global Variable: core **state_table; | lalr.c core *first_state; | lr0.c Use Functions : Parameters : [void] Return : [void] *************************************************************************/ { register core *cp, *next; FREE( state_table ); for( cp = first_state; cp; cp = next ) { next = cp->next; FREE( cp ); } } /******* End of free_itemsets( void ) ********************************/ void output( void ) /************************************************************************* Description : output Concepts : Use Global Variable: char rflag; | main.c Use Functions : void free_reductions( void ); | this file void free_shifts( void ); | this file void free_itemsets( void ); | this file void output_semantic_actions(void); | this file void output_trailing_text( void ); | this file void output_stype( void ); | this file void output_debug( void ); | this file void output_stored_text( void ); | this file void output_defines( void ); | this file void output_actions( void ); | this file void output_zubr_defred( void ); | this file void output_rule_data( void ); | this file void free_parser( void ); | mkpar.c Parameters : [void] Return : [void] *************************************************************************/ { free_itemsets(); free_shifts(); free_reductions(); output_stored_text(); output_defines(); output_rule_data(); output_zubr_defred(); output_actions(); free_parser(); output_debug(); output_stype (); if( rflag ) write_extern_tables(); write_header(); write_header_definitions(); output_trailing_text(); write_begin_body(); write_parse_name_definition(); write_end_body(); output_semantic_actions(); write_trailer(); } /******* End of output( void ) *****************************/ #endif /* __NO_COMPILE */ /******************* END OF FILE OUTPUT.C ********************/