summaryrefslogtreecommitdiff
path: root/src/mkpar.c
diff options
context:
space:
mode:
authorkx <kx@radix-linux.su>2026-09-30 21:14:58 +0300
committerkx <kx@radix-linux.su>2026-09-30 21:14:58 +0300
commit5b1c65152f77e03a4800fceae32d16efe2dadc9c (patch)
treecaffe4b2235503cccfedfb772dc266cb311840b3 /src/mkpar.c
parent8b354d2b9f2640d90705abd324a413a0d8fa3867 (diff)
downloadzubr-trunk.tar.xz
Version 4.1.0HEAD4.1.0trunk
Diffstat (limited to 'src/mkpar.c')
-rw-r--r--src/mkpar.c619
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 ****************/