diff options
Diffstat (limited to 'src/verbose.c')
| -rw-r--r-- | src/verbose.c | 584 |
1 files changed, 584 insertions, 0 deletions
diff --git a/src/verbose.c b/src/verbose.c new file mode 100644 index 0000000..3f3e318 --- /dev/null +++ b/src/verbose.c @@ -0,0 +1,584 @@ + +/*************************************************************** + VERBOSE.C + + This file containts VERBOSE file 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 <defs.h> + +#ifndef __NO_COMPILE + + +static int *null_rules; + +/* NOTE * + In this file for output '\t'(tab) symbol use 12 space characters. + My be use the following string 'u" ' for find that symbols. + * END */ + +void log_unused( void ) +/*************************************************************** + + Description : log unused + + Concepts : + + Use Global Variable: int nrules; | main.c + char **symbol_name; | main.c + int *ritem; | main.c + int *rrhs; | main.c + FILE *verbose_file; | main.c + int *rules_used; | mkpar.c + + Use Functions : + + Parameters : [void] + + Return : [void] + + ***************************************************************/ +{ + register int i; + register int *p; + + mpu_fprintf( verbose_file, MPU_UCS2( "\n\nRules never reduced:\n" ) ); + for( i = 3; i < nrules; ++i ) + { + if( !rules_used[i] ) + { + mpu_fprintf( verbose_file, MPU_UCS2( " %s :" ), + symbol_name[rlhs[i]]); + for( p = ritem + rrhs[i]; *p >= 0; ++p ) + mpu_fprintf( verbose_file, MPU_UCS2( " %s" ), symbol_name[*p] ); + mpu_fprintf( verbose_file, MPU_UCS2( " (%d)\n" ), i - 2 ); + } + } + +} /******* End of log_unused( void ) *************************/ + + +void log_conflicts( void ) +/*************************************************************** + + Description : log conflicts + + Concepts : + + Use Global Variable: FILE *verbose_file; | main.c + int nstates; | lr0.c + int *SRconflicts; | mkpar.c + int *RRconflicts; | mkpar.c + + Use Functions : + + Parameters : [void] + + Return : [void] + + ***************************************************************/ +{ + register int i; + + mpu_fprintf( verbose_file, MPU_UCS2( "\n\n" ) ); + for( i = 0; i < nstates; i++ ) + { + if( SRconflicts[i] || RRconflicts[i] ) + { + mpu_fprintf( verbose_file, MPU_UCS2( "State %d contains " ), i); + if( SRconflicts[i] == 1 ) + mpu_fprintf( verbose_file, MPU_UCS2( "1 shift/reduce conflict" ) ); + else if( SRconflicts[i] > 1 ) + mpu_fprintf( verbose_file, + MPU_UCS2( "%d shift/reduce conflicts" ), + SRconflicts[i] ); + if( SRconflicts[i] && RRconflicts[i] ) + mpu_fprintf( verbose_file, MPU_UCS2( ", u" ) ); + if( RRconflicts[i] == 1 ) + mpu_fprintf( verbose_file, MPU_UCS2( "1 reduce/reduce conflict" ) ); + else if( RRconflicts[i] > 1 ) + mpu_fprintf( verbose_file, + MPU_UCS2( "%d reduce/reduce conflicts" ), + RRconflicts[i] ); + mpu_fprintf( verbose_file, MPU_UCS2( ".\n" ) ); + + } + } /* End of for( i = 0; i < nstates; i++ ) */ + +} /******* End of log_conflicts( void ) **********************/ + + +void print_conflicts( int state ) +/*************************************************************** + + Description : print conflicts + + Concepts : + + Use Global Variable: char **symbol_name; | main.c + FILE *verbose_file; | main.c + action **parser; | mkpar.c + int final_state; | mkpar.c + + Use Functions : + + Parameters : int state + + Return : [void] + + ***************************************************************/ +{ + register int symbol = 0, act = 0, number = 0; + register action *p; + + symbol = -1; + for( p = parser[state]; p; p = p->next ) + { + if( p->suppressed == 2 ) continue; + + if( p->symbol != symbol ) + { + symbol = p->symbol; + number = p->number; + if( p->action_code == SHIFT ) act = SHIFT; + else act = REDUCE; + } + else + if( p->suppressed == 1 ) + { + if( state == final_state && symbol == 0 ) + { + mpu_fprintf( verbose_file, + MPU_UCS2( "%d: shift/reduce conflict (accept, reduce %d) on $end\n" ), + state, p->number - 2 ); + } + else + { + if( act == SHIFT ) + { + mpu_fprintf( verbose_file, + MPU_UCS2( "%d: shift/reduce conflict (shift %d, reduce %d) on %s\n" ), + state, number, p->number - 2, symbol_name[symbol] ); + } + + else + { + mpu_fprintf( verbose_file, + MPU_UCS2( "%d: reduce/reduce conflict (reduce %d, reduce %d) on %s\n" ), + state, number - 2, p->number - 2, symbol_name[symbol] ); + } + } + } /* End if( p->suppressed == 1 ) */ + } /* End of for( p = parser[state]; p; p = p->next ) */ + +} /******* End of print_conflicts( int state ) ***************/ + + +void print_core( int state ) +/*************************************************************** + + Description : print core + + Concepts : + + Use Global Variable: char **symbol_name; | main.c + int *ritem; | main.c + int *rrhs; | main.c + int *rlhs; | main.c + FILE *verbose_file; | main.c + core **state_table; | lalr.c + + Use Functions : + + Parameters : int state + + Return : [void] + + ***************************************************************/ +{ + register int i; + register int k; + register int rule; + register core *statep; + register int *sp; + register int *sp1; + + statep = state_table[state]; + k = statep->nitems; + + for( i = 0; i < k; i++ ) + { + sp1 = sp = ritem + statep->items[i]; + + while( *sp >= 0 ) ++sp; + rule = -(*sp); + mpu_fprintf( verbose_file, + MPU_UCS2( " %s : " ), symbol_name[rlhs[rule]] ); + + for( sp = ritem + rrhs[rule]; sp < sp1; sp++ ) + mpu_fprintf( verbose_file, MPU_UCS2( "%s " ), symbol_name[*sp] ); + + mpu_putc( '.', verbose_file ); + + while( *sp >= 0 ) + { + mpu_fprintf( verbose_file, MPU_UCS2( " %s" ), symbol_name[*sp] ); + sp++; + } + mpu_fprintf( verbose_file, MPU_UCS2( " (%d)\n" ), -2 - *sp ); + + } /* End of for( i = 0; i < k; i++ ) */ + +} /******* End of print_core( int state ) ********************/ + + +void print_nulls( int state ) +/*************************************************************** + + Description : print nulls + + Concepts : + + Use Global Variable: int *rrhs; | main.c + int *rlhs; | main.c + FILE *verbose_file; | main.c + action **parser; | mkpar.c + static int *null_rules; | this file + + Use Functions : + + Parameters : int state + + Return : [void] + + ***************************************************************/ +{ + register action *p; + register int i, j, k, nnulls; + + nnulls = 0; + for( p = parser[state]; p; p = p->next ) + { + if( p->action_code == REDUCE && + (p->suppressed == 0 || p->suppressed == 1) ) + { + i = p->number; + if( rrhs[i] + 1 == rrhs[i+1] ) + { + for( j = 0; j < nnulls && i > null_rules[j]; ++j ) + continue; + + if( j == nnulls ) + { + ++nnulls; + null_rules[j] = i; + } + else if( i != null_rules[j] ) + { + ++nnulls; + for( k = nnulls - 1; k > j; --k ) + null_rules[k] = null_rules[k-1]; + null_rules[j] = i; + } + } /* End if( rrhs[i] + 1 == rrhs[i+1] ) */ + } + } /* End of for( p = parser[state]; p; p = p->next ) */ + + for( i = 0; i < nnulls; ++i ) + { + j = null_rules[i]; + mpu_fprintf( verbose_file, MPU_UCS2( " %s : . (%d)\n" ), + symbol_name[rlhs[j]], j - 2 ); + } + mpu_fprintf( verbose_file, MPU_UCS2( "\n" ) ); + +} /******* End of print_nulls( int state ) *******************/ + + +void print_shifts( action *p ) +/*************************************************************** + + Description : print shifts + + Concepts : + + Use Global Variable: char **symbol_name; | main.c + FILE *verbose_file; | main.c + + Use Functions : + + Parameters : action *p + + Return : [void] + + ***************************************************************/ +{ + register int count; + register action *q; + + count = 0; + for( q = p; q; q = q->next ) + { + if( q->suppressed < 2 && q->action_code == SHIFT ) ++count; + } + + if( count > 0 ) + { + for( ; p; p = p->next ) + { + if( p->action_code == SHIFT && p->suppressed == 0 ) + mpu_fprintf( verbose_file, MPU_UCS2( " %s shift %d\n" ), + symbol_name[p->symbol], p->number ); + } + } + +} /******* End of print_shifts( action *p ) ******************/ + + +void print_reductions( action *p, int defred ) +/*************************************************************** + + Description : print reductions + + Concepts : + + Use Global Variable: char **symbol_name; | main.c + FILE *verbose_file; | main.c + + Use Functions : + + Parameters : action *p, int defred + + Return : [void] + + ***************************************************************/ +{ + register int k, anyreds; + register action *q; + + anyreds = 0; + for( q = p; q ; q = q->next ) + { + if( q->action_code == REDUCE && q->suppressed < 2 ) + { + anyreds = 1; + break; + } + } + + if( anyreds == 0 ) mpu_fprintf( verbose_file, MPU_UCS2( " . error\n" ) ); + else + { + for( ; p; p = p->next ) + { + if( p->action_code == REDUCE && p->number != defred ) + { + k = p->number - 2; + if( p->suppressed == 0 ) + mpu_fprintf( verbose_file, MPU_UCS2( " %s reduce %d\n" ), + symbol_name[p->symbol], k ); + } + } + + if( defred > 0 ) + mpu_fprintf( verbose_file, MPU_UCS2( " . reduce %d\n" ), + defred - 2 ); + } + +} /******* End of print_reductions( action *p, int defred ) **/ + + +void print_gotos( int stateno ) +/*************************************************************** + + Description : print gotos + + Concepts : + + Use Global Variable: char **symbol_name; | main.c + FILE *verbose_file; | main.c + shifts **shift_table; | lalr.c + int *accessing_symbol; | lalr.c + + Use Functions : + + Parameters : int stateno + + Return : [void] + + ***************************************************************/ +{ + register int i, k; + register int as; + register int *to_state; + register shifts *sp; + + mpu_putc( '\n', verbose_file ); + sp = shift_table[stateno]; + to_state = sp->shift; + for( i = 0; i < sp->nshifts; ++i ) + { + k = to_state[i]; + as = accessing_symbol[k]; + if( ISVAR(as) ) + mpu_fprintf( verbose_file, MPU_UCS2( " %s goto %d\n" ), + symbol_name[as], k ); + } + +} /******* End of print_gotos( int stateno ) *****************/ + + +void print_actions( int stateno ) +/*************************************************************** + + Description : print actions + + Concepts : + + Use Global Variable: FILE *verbose_file; | main.c + shifts **shift_table; | lalr.c + int *accessing_symbol; | lalr.c + action **parser; | mkpar.c + int *defred; | mkpar.c + int final_state; | mkpar.c + + Use Functions : + void print_shifts (action *p); | this file + void print_reductions (action *, int); | --/-- + void print_gotos (int stateno); | this file + + Parameters : int stateno + + Return : [void] + + ***************************************************************/ +{ + register action *p; + register shifts *sp; + register int as; + + if( stateno == final_state ) + mpu_fprintf( verbose_file, MPU_UCS2( " $end accept\n" ) ); + + p = parser[stateno]; + if( p ) + { + print_shifts( p ); + print_reductions( p, defred[stateno] ); + } + + sp = shift_table[stateno]; + if( sp && sp->nshifts > 0 ) + { + as = accessing_symbol[sp->shift[sp->nshifts - 1]]; + if( ISVAR(as) ) print_gotos( stateno ); + } + +} /******* End of print_actions( int stateno ) ***************/ + + +void print_state( int state ) +/*************************************************************** + + Description : print state + + Concepts : + + Use Global Variable: FILE *verbose_file; | main.c + int *SRconflicts; | mkpar.c + int *RRconflicts; | mkpar.c + + Use Functions : + void print_conflicts (int state); | this file + void print_core (int state); | this file + void print_nulls (int state); | this file + void print_actions (int stateno); | this file + + Parameters : int state + + Return : [void] + + ***************************************************************/ +{ + if( state ) mpu_fprintf( verbose_file, MPU_UCS2( "\n\n" ) ); + if( SRconflicts[state] || RRconflicts[state] ) + print_conflicts( state ); + mpu_fprintf( verbose_file, MPU_UCS2( "state %d\n" ), state ); + print_core( state ); + print_nulls( state ); + print_actions( state ); + +} /******* End of print_state( int state ) *******************/ + + +void verbose( void ) +/*************************************************************** + + Description : verbose + + Concepts : + + Use Global Variable: int ntokens | main.c + int nrules; | main.c + int nvars; | main.c + char vflag; | main.c + FILE *verbose_file; | main.c + int nstates; | lr0.c + int nunused; | mkpar.c + int SRtotal; | mkpar.c + int RRtotal; | mkpar.c + static int *null_rules; | this file + + Use Functions : void no_space (void); | error.c + void log_unused (void); | this file + void log_conflicts (void); | this file + void print_state (int state); | this file + + Parameters : [void] + + Return : [void] + + ***************************************************************/ +{ + register int i; + + if( !vflag ) return; + + null_rules = (int *)MALLOC( nrules*sizeof(int) ); + if( null_rules == 0 ) no_space(); + mpu_fprintf( verbose_file, MPU_UCS2( "\n\n" ) ); + for( i = 0; i < nstates; i++ ) print_state( i ); + FREE( null_rules ); + + if( nunused ) log_unused(); + if( SRtotal || RRtotal ) log_conflicts(); + + mpu_fprintf( verbose_file, + MPU_UCS2( "\n\n%d terminals, %d nonterminals\n" ), + ntokens, nvars ); + mpu_fprintf( verbose_file, + MPU_UCS2( "%d grammar rules, %d states\n" ), + nrules - 2, nstates ); + + mpu_fprintf( verbose_file, MPU_UCS2( "\n\ +/************************ End of File **************************/\n" ) + ); + +} /******* End of verbose( void ) ****************************/ + +#endif /* __NO_COMPILE */ + +/******************* END OF FILE VERBOSE.C *******************/ |
