summaryrefslogtreecommitdiff
path: root/src/verbose.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/verbose.c')
-rw-r--r--src/verbose.c584
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 *******************/