diff options
| author | kx <kx@radix-linux.su> | 2026-09-30 21:14:58 +0300 |
|---|---|---|
| committer | kx <kx@radix-linux.su> | 2026-09-30 21:14:58 +0300 |
| commit | 5b1c65152f77e03a4800fceae32d16efe2dadc9c (patch) | |
| tree | caffe4b2235503cccfedfb772dc266cb311840b3 /src/mkpar.c | |
| parent | 8b354d2b9f2640d90705abd324a413a0d8fa3867 (diff) | |
| download | zubr-trunk.tar.xz | |
Diffstat (limited to 'src/mkpar.c')
| -rw-r--r-- | src/mkpar.c | 619 |
1 files changed, 619 insertions, 0 deletions
diff --git a/src/mkpar.c b/src/mkpar.c new file mode 100644 index 0000000..bfa2fe2 --- /dev/null +++ b/src/mkpar.c @@ -0,0 +1,619 @@ + +/*************************************************************** + 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 <defs.h> + +#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 ****************/ |
