/*************************************************************** MKPAR.C This file containts MAKE PARSER routines of ZUBR. PART OF : ZUBR - Parsers generator for multiple syntax language compilers . COMPILE : . Copyright (C) 1995 - 2026 by Andrey V.Kosteltsev. All Rights Reserved. ***************************************************************/ /* This file contant RUSSIAN letters( code-page: UTF-8 ) ***************************************************************/ #include #ifndef __NO_COMPILE action **parser; int SRtotal; int RRtotal; int *SRconflicts; int *RRconflicts; int *defred; int *rules_used; int nunused; int final_state; static int SRcount; static int RRcount; action *add_reduce( action *actions, int ruleno, int symbol ) /*************************************************************** Description : add_reduce Concepts : Use Global Variable: int *rprec; | main.c char *rassoc; | main.c Use Functions : Parameters : action *actions, int ruleno, int symbol Return : action * ***************************************************************/ { register action *temp, *prev, *next; prev = 0; for( next = actions; next && next->symbol < symbol; next = next->next ) prev = next; while( next && next->symbol == symbol && next->action_code == SHIFT ) { prev = next; next = next->next; } while( next && next->symbol == symbol && next->action_code == REDUCE && next->number < ruleno ) { prev = next; next = next->next; } temp = NEW( action ); temp->next = next; temp->symbol = symbol; temp->number = ruleno; temp->prec = rprec[ruleno]; temp->action_code = REDUCE; temp->assoc = rassoc[ruleno]; if( prev ) prev->next = temp; else actions = temp; return( actions ); } /******* End of add_reduce( action *, int, int ) ***********/ int sole_reduction( int stateno ) /*************************************************************** Description : sole_reduction Concepts : Use Global Variable: action **parser; | this file Use Functions : Parameters : int stateno Return : int ***************************************************************/ { register int count, ruleno; register action *p; count = 0; ruleno = 0; for( p = parser[stateno]; p; p = p->next ) { if( p->action_code == SHIFT && p->suppressed == 0 ) return( 0 ); else if( p->action_code == REDUCE && p->suppressed == 0 ) { if( ruleno > 0 && p->number != ruleno ) return( 0 ); if( p->symbol != 1 ) ++count; ruleno = p->number; } } if( count == 0 ) return( 0 ); return( ruleno ); } /******* End of sole_reduction( int stateno ) **************/ action *add_reductions( int stateno, action *actions ) /*************************************************************** Description : add_reductions Concepts : Use Global Variable: int *lookaheads; | lalr.c int *LAruleno; | lalr.c int ntokens; | main.c Use Functions : action * add_reduce (action *, int, int); | this file Parameters : int stateno, action *actions Return : action * ***************************************************************/ { register int i, j, m, n; register int ruleno, tokensetsize; register unsigned *rowp; tokensetsize = SIZE_IN_INT( ntokens ); m = lookaheads[stateno]; n = lookaheads[stateno + 1]; for( i = m; i < n; i++ ) { ruleno = LAruleno[i]; rowp = LA + i * tokensetsize; for( j = ntokens - 1; j >= 0; j-- ) { if( BIT(rowp, j) ) actions = add_reduce( actions, ruleno, j ); } } return( actions ); } /******* End of add_reductions( int, action * ) ************/ action *get_shifts (int stateno) /*************************************************************** Description : get_shifts Concepts : Use Global Variable: int *accessing_symbol; | lalr.c shifts **shift_table; | lalr.c int *symbol_prec; | main.c char *symbol_assoc; | main.c Use Functions : Parameters : int stateno Return : action * ***************************************************************/ { register action *actions, *temp; register shifts *sp; register int *to_state; register int i, k; register int symbol; actions = 0; sp = shift_table[stateno]; if( sp ) { to_state = sp->shift; for( i = sp->nshifts - 1; i >= 0; i-- ) { k = to_state[i]; symbol = accessing_symbol[k]; if( ISTOKEN(symbol) ) { temp = NEW( action ); temp->next = actions; temp->symbol = symbol; temp->number = k; temp->prec = symbol_prec[symbol]; temp->action_code = SHIFT; temp->assoc = symbol_assoc[symbol]; actions = temp; } } } return( actions ); } /******* End of get_shifts( int stateno ) ******************/ void defreds( void ) /*************************************************************** Description : defreds Concepts : Use Global Variable: int *defred; | this file int nstates; | lr0.c Use Functions : int sole_reduction (int); | this file Parameters : [void] Return : [void] ***************************************************************/ { register int i; defred = NEW2( nstates, int ); for( i = 0; i < nstates; i++ ) defred[i] = sole_reduction( i ); } /******* End of defreds( void ) ****************************/ void total_conflicts( void ) /*************************************************************** Description : total_conflicts Concepts : Use Global Variable: int SRtotal; | this file int RRtotal; | this file Use Functions : Parameters : [void] Return : [void] ***************************************************************/ { mpu_fprintf( mpu_stderr, MPU_UCS2( "%s: " ), myname ); if( SRtotal == 1 ) mpu_fprintf( mpu_stderr, MPU_UCS2( "1 shift/reduce conflict" ) ); else if( SRtotal > 1 ) mpu_fprintf( mpu_stderr, MPU_UCS2( "%d shift/reduce conflicts" ), SRtotal ); if( SRtotal && RRtotal ) mpu_fprintf( mpu_stderr, MPU_UCS2( ", u" ) ); if( RRtotal == 1 ) mpu_fprintf( mpu_stderr, MPU_UCS2( "1 reduce/reduce conflict" ) ); else if( RRtotal > 1 ) mpu_fprintf( mpu_stderr, MPU_UCS2( "%d reduce/reduce conflicts" ), RRtotal ); mpu_fprintf( mpu_stderr, MPU_UCS2( ".\n" ) ); } /******* End of total_conflicts( void ) ********************/ void unused_rules( void ) /*************************************************************** Description : unused_rules Concepts : Use Global Variable: action **parser; | this file int *rules_used; | this file int nunused; | this file char *myname; | main.c int nrules; | main.c int nstates; | lr0.c Use Functions : Parameters : [void] Return : [void] ***************************************************************/ { register int i; register action *p; rules_used = (int *)MALLOC( nrules*sizeof(int) ); if( rules_used == 0 ) no_space(); for( i = 0; i < nrules; ++i ) rules_used[i] = 0; for( i = 0; i < nstates; ++i ) { for( p = parser[i]; p; p = p->next ) { if( p->action_code == REDUCE && p->suppressed == 0 ) rules_used[p->number] = 1; } } nunused = 0; for( i = 3; i < nrules; ++i ) if( !rules_used[i] ) ++nunused; if( nunused ) { if( nunused == 1 ) mpu_fprintf( mpu_stderr, MPU_UCS2( "%s: 1 rule never reduced\n" ), myname ); else mpu_fprintf( mpu_stderr, MPU_UCS2( "%s: %d rules never reduced\n" ), myname, nunused ); } } /******* End of unused_rules( void ) ***********************/ void remove_conflicts( void ) /*************************************************************** Description : remove_conflicts Concepts : Use Global Variable: action **parser; | this file int SRtotal; | this file int RRtotal; | this file int *SRconflicts; | this file int *RRconflicts; | this file int final_state; | this file static int SRcount; | this file static int RRcount; | this file int nstates; | lr0.c Use Functions : Parameters : [void] Return : [void] ***************************************************************/ { register int i; register int symbol; register action *p, *pref = NULL; SRtotal = 0; RRtotal = 0; SRconflicts = NEW2( nstates, int ); RRconflicts = NEW2( nstates, int ); for( i = 0; i < nstates; i++ ) { SRcount = 0; RRcount = 0; symbol = -1; for( p = parser[i]; p; p = p->next ) { if( p->symbol != symbol ) { pref = p; symbol = p->symbol; } else if( i == final_state && symbol == 0 ) { SRcount++; p->suppressed = 1; } else if( pref->action_code == SHIFT ) { if( pref->prec > 0 && p->prec > 0 ) { if( pref->prec < p->prec ) { pref->suppressed = 2; pref = p; } else if( pref->prec > p->prec ) { p->suppressed = 2; } else if( pref->assoc == LEFT ) { pref->suppressed = 2; pref = p; } else if( pref->assoc == RIGHT ) { p->suppressed = 2; } else { pref->suppressed = 2; p->suppressed = 2; } } /* End if( pref->prec > 0 && p->prec > 0 ) */ else { SRcount++; p->suppressed = 1; } } /* End if( pref->action_code == SHIFT ) */ else { RRcount++; p->suppressed = 1; } } /* End of for( p = parser[i]; p; p = p->next ) */ SRtotal += SRcount; RRtotal += RRcount; SRconflicts[i] = SRcount; RRconflicts[i] = RRcount; } /* End of for( i = 0; i < nstates; i++ ) */ } /******* End of remove_conflicts( void ) *******************/ void find_final_state( void ) /*************************************************************** Description : find_final_state Concepts : Use Global Variable: int final_state; | this file int *ritem; | main.c int *accessing_symbol; | lalr.c shifts **shift_table; | lalr.c Use Functions : Parameters : [void] Return : [void] ***************************************************************/ { register int goal, i; register int *to_state; register shifts *p; p = shift_table[0]; to_state = p->shift; goal = ritem[1]; for( i = p->nshifts - 1; i >= 0; --i ) { final_state = to_state[i]; if( accessing_symbol[final_state] == goal ) break; } } /******* End of find_final_state( void ) *******************/ action *parse_actions( int stateno ) /*************************************************************** Description : parse_actions Concepts : Use Global Variable: Use Functions : action * add_reductions (int, action *); action * get_shifts (int); | this file Parameters : int stateno Return : action * ***************************************************************/ { register action *actions; actions = get_shifts( stateno ); actions = add_reductions( stateno, actions ); return( actions ); } /******* End of parse_actions( int stateno ) ***************/ void make_parser( void ) /*************************************************************** Description : make_parser Concepts : Use Global Variable: action **parser; | this file int SRtotal; | this file int RRtotal; | this file int nstates; | lr0.c Use Functions : void defreds (void); | this file void total_conflicts (void); | this file void remove_conflicts (void); | this file void unused_rules (void); | this file void find_final_state (void); | this file action * parse_actions (int); | this file Parameters : [void] Return : [void] ***************************************************************/ { register int i; parser = NEW2( nstates, action * ); for( i = 0; i < nstates; i++ ) parser[i] = parse_actions( i ); find_final_state(); remove_conflicts(); unused_rules(); if( SRtotal + RRtotal > 0 ) total_conflicts(); defreds(); } /******* End of make_parser( void ) ************************/ /****************** this functions use in output.c ***********/ void free_action_row( action *p ) /*************************************************************** Description : free_action_row Concepts : Use Global Variable: Use Functions : Parameters : action *p Return : [void] ***************************************************************/ { register action *q; while( p ) { q = p->next; FREE (p); p = q; } } /******* End of free_action_row( action *p ) ***************/ void free_parser( void ) /*************************************************************** Description : free_parser Concepts : Use Global Variable: action **parser; | this file int nstates; | lr0.c Use Functions : void free_action_row (action *); | this file Parameters : [void] Return : [void] ***************************************************************/ { register int i; for( i = 0; i < nstates; i++ ) free_action_row( parser[i] ); FREE( parser ); } /******* End of free_parser( void ) ************************/ #endif /* __NO_COMPILE */ /************************ END OF FILE MKPAR.C ****************/