summaryrefslogtreecommitdiff
path: root/src/lr0.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lr0.c')
-rw-r--r--src/lr0.c1035
1 files changed, 1035 insertions, 0 deletions
diff --git a/src/lr0.c b/src/lr0.c
new file mode 100644
index 0000000..d99ae9f
--- /dev/null
+++ b/src/lr0.c
@@ -0,0 +1,1035 @@
+
+/***************************************************************
+ LR0.C
+
+ This file containts LR0 routines of ZUBR.
+
+ PART OF : ZUBR - Parsers generator for multiple syntax
+ language compilers .
+
+ COMPILE : .
+
+ NOTE : Use macro _DEBUG, TRACE for out additional
+ info into mpu_stdout, mpu_stderr.
+
+ 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
+
+
+extern int *itemset; /* define in CLOSURE.C */
+extern int *itemsetend; /* define in CLOSURE.C */
+extern unsigned *ruleset; /* define in CLOSURE.C */
+
+int nstates;
+core *first_state;
+shifts *first_shift;
+reductions *first_reduction;
+
+static core **state_set;
+static core *this_state;
+static core *last_state;
+static shifts *last_shift;
+static reductions *last_reduction;
+
+static int nshifts;
+static int *shift_symbol;
+
+static int *redset;
+static int *shiftset;
+
+static int **kernel_base;
+static int **kernel_end;
+static int *kernel_items;
+
+
+/************* Start of functions for debuging ***************/
+#ifdef _DEBUG
+
+void show_cores( void )
+/***************************************************************
+
+ Description : show cores
+
+ Concepts : show_cores() is used for debugging
+
+ Use Global Variable: char **symbol_name; | main.c
+ int *ritem; | main.c
+ int *rrhs; | main.c
+ int *rlhs; | main.c
+ core *first_state; | this file
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ core *p;
+ int i, j, k, n;
+ int itemno;
+
+ k = 0;
+ for( p = first_state; p; ++k, p = p->next )
+ {
+ if( k ) mpu_fprintf( mpu_stdout, MPU_UCS2( "\n" ) );
+ mpu_fprintf( mpu_stdout,
+ MPU_UCS2( "state %d, number = %d, accessing symbol = %s\n" ),
+ k, p->number, symbol_name[p->accessing_symbol] );
+ n = p->nitems;
+ for( i = 0; i < n; ++i )
+ {
+ itemno = p->items[i];
+ mpu_fprintf( mpu_stdout, MPU_UCS2( "%4d " ), itemno );
+ j = itemno;
+ while( ritem[j] >= 0 ) ++j;
+ mpu_fprintf( mpu_stdout,
+ MPU_UCS2( "%s :" ), symbol_name[rlhs[-ritem[j]]] );
+ j = rrhs[-ritem[j]];
+ while( j < itemno ) mpu_fprintf( mpu_stdout,
+ MPU_UCS2( " %s" ),
+ symbol_name[ritem[j++]] );
+ mpu_fprintf( mpu_stdout, MPU_UCS2( " ." ) );
+ while( ritem[j] >= 0 )
+ mpu_fprintf( mpu_stdout, MPU_UCS2( " %s" ),
+ symbol_name[ritem[j++]] );
+ mpu_fprintf( mpu_stdout, MPU_UCS2( "\n" ) );
+ mpu_fflush( mpu_stdout ); /* stdio.h */
+
+ } /* End of for( i = 0; i < n; ++i ) */
+ } /* End of for( p = first_state; p; ++k, p = p->next ) */
+
+} /******* End of show_cores( void ) **************************/
+
+
+void show_ritems( void )
+/***************************************************************
+
+ Description : show ritems
+
+ Concepts : show_ritems() is used for debugging
+
+ Use Global Variable: int nitems; | main.c
+ int *ritem; | main.c
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ int i;
+
+ for( i = 0; i < nitems; ++i )
+ mpu_fprintf( mpu_stdout,
+ MPU_UCS2( "ritem[%d] = %d\n" ), i, ritem[i] );
+
+} /******* End of show_ritems( void ) ************************/
+
+
+void show_rrhs( void )
+/***************************************************************
+
+ Description : show rrhs
+
+ Concepts : show_rrhs() is used for debugging
+
+ Use Global Variable: int nrules; | main.c
+ int *rrhs; | main.c
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ int i;
+
+ for( i = 0; i < nrules; ++i )
+ mpu_fprintf( mpu_stdout,
+ MPU_UCS2( "rrhs[%d] = %d\n" ), i, rrhs[i] );
+
+} /******* End of show_rrhs( void ) **************************/
+
+
+void show_shifts( void )
+/***************************************************************
+
+ Description : show shifts
+
+ Concepts : show_shifts() is used for debugging
+
+ Use Global Variable: shifts *first_shift; | this file
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ shifts *p;
+ int i, j, k;
+
+ k = 0;
+ for( p = first_shift; p; ++k, p = p->next )
+ {
+ if( k ) mpu_fprintf( mpu_stdout, MPU_UCS2( "\n" ) );
+ mpu_fprintf( mpu_stdout,
+ MPU_UCS2( "shift %d, number = %d, nshifts = %d\n" ),
+ k, p->number, p->nshifts );
+ j = p->nshifts;
+ for( i = 0; i < j; ++i )
+ mpu_fprintf( mpu_stdout,
+ MPU_UCS2( "\t%d\n" ), p->shift[i] );
+ }
+
+} /******* End of show_shifts( void ) ************************/
+
+
+void print_derives( void )
+/***************************************************************
+
+ Description : print derives
+
+ Concepts : print_derives() is used for debugging
+
+ Use Global Variable: int nsyms; | main.c
+ int start_symbol; | main.c
+ char **symbol_name; | main.c
+ int **derives; | main.c
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ register int i;
+ register int *sp;
+
+ mpu_fprintf( mpu_stdout, MPU_UCS2( "\nDERIVES\n\n" ) );
+
+ for( i = start_symbol; i < nsyms; i++ )
+ {
+ mpu_fprintf( mpu_stdout,
+ MPU_UCS2( "%s derives " ), symbol_name[i] );
+ for( sp = derives[i]; *sp >= 0; sp++ )
+ {
+ mpu_fprintf( mpu_stdout, MPU_UCS2( " %d" ), *sp );
+ }
+ mpu_putc( '\n', mpu_stdout );
+ }
+ mpu_putc( '\n', mpu_stdout );
+
+} /******* End of print_derives( void ) **********************/
+
+#endif
+/***************** End of functions for debuging ***************/
+
+
+
+void allocate_itemsets( void )
+/***************************************************************
+
+ Description : allocate itemsets
+
+ Concepts :
+
+ Use Global Variable: int nsyms; | main.c
+ int nitems; | main.c
+ int *ritem; | main.c
+ static int *shift_symbol; | this file
+ static int **kernel_base; | this file
+ static int **kernel_end; | this file
+ static int *kernel_items; | this file
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ register int *itemp;
+ register int *item_end;
+ register int symbol;
+ register int i;
+ register int count;
+ register int max;
+ register int *symbol_count;
+
+ count = 0;
+ symbol_count = NEW2( nsyms, int );
+
+ item_end = ritem + nitems;
+ for( itemp = ritem; itemp < item_end; itemp++ )
+ {
+ symbol = *itemp;
+ if( symbol >= 0 )
+ {
+ count++;
+ symbol_count[symbol]++;
+ }
+ }
+
+ kernel_base = NEW2( nsyms, int * );
+ kernel_items = NEW2( count, int );
+
+ count = 0;
+ max = 0;
+ for( i = 0; i < nsyms; i++ )
+ {
+ kernel_base[i] = kernel_items + count;
+ count += symbol_count[i];
+ if( max < symbol_count[i] ) max = symbol_count[i];
+ }
+
+ shift_symbol = symbol_count;
+ kernel_end = NEW2( nsyms, int * );
+
+} /******* End of allocate_itemsets( void ) ******************/
+
+
+void allocate_storage( void )
+/***************************************************************
+
+ Description : allocate storage
+
+ Concepts :
+
+ Use Global Variable: int nsyms; | main.c
+ int nitems; | main.c
+ int nrules; | main.c
+ static core **state_set; | this file
+ static int *redset; | this file
+ static int *shiftset; | this file
+
+ Use Functions : void allocate_itemsets (void); | this file
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ allocate_itemsets();
+
+ shiftset = NEW2( nsyms, int );
+ redset = NEW2( nrules + 1, int );
+ state_set = NEW2( nitems, core * );
+
+} /******* End of allocate_storage( void ) *******************/
+
+
+void free_storage( void )
+/***************************************************************
+
+ Description : free storage
+
+ Concepts :
+
+ Use Global Variable: static core **state_set; | this file
+ static int *redset; | this file
+ static int *shiftset; | this file
+ static int *shift_symbol; | this file
+ static int **kernel_base; | this file
+ static int **kernel_end; | this file
+ static int *kernel_items; | this file
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ FREE( shift_symbol );
+ FREE( redset );
+ FREE( shiftset );
+ FREE( kernel_base );
+ FREE( kernel_end );
+ FREE( kernel_items );
+ FREE( state_set );
+
+} /******* End of free_storage( void ) ***********************/
+
+
+core * new_state( int symbol )
+/***************************************************************
+
+ Description : new state
+
+ Concepts :
+
+ Use Global Variable: int nstates; | this file
+ static core *last_state; | this file
+ static int **kernel_base; | this file
+ static int **kernel_end; | this file
+
+ Use Functions : char *allocate (unsigned n); | main.c
+ void fatal (char *); | error.c
+
+ Parameters : int symbol
+
+ Return : core *p
+
+ ***************************************************************/
+{
+ register int n;
+ register core *p;
+ register int *isp1, *isp2;
+ register int *iend;
+
+#ifdef TRACE
+ mpu_fprintf( mpu_stderr,
+ MPU_UCS2( "Entering new_state(%d)\n" ), symbol);
+#endif
+
+ if( nstates >= MAXWORD ) fatal( (__mpu_char16_t *)MPU_UCS2( "Too many states" ) );
+
+ isp1 = kernel_base[symbol];
+ iend = kernel_end[symbol];
+ n = iend - isp1;
+
+ p = (core *)
+ allocate( (unsigned)(sizeof(core) + (n - 1) * sizeof(int)) );
+ p->accessing_symbol = symbol;
+ p->number = nstates;
+ p->nitems = n;
+
+ isp2 = p->items;
+ while( isp1 < iend ) *isp2++ = *isp1++;
+
+ last_state->next = p;
+ last_state = p;
+
+ nstates++;
+
+ return( p );
+
+} /******* End of new_state( int symbol ) ********************/
+
+
+int get_state( int symbol )
+/***************************************************************
+
+ Description : get state
+
+ Concepts :
+
+ Use Global Variable: static core **state_set; | this file
+ static int **kernel_base; | this file
+ static int **kernel_end; | this file
+
+ Use Functions : core * new_state (int symbol); | this file
+
+ Parameters : int
+
+ Return : int
+
+ ***************************************************************/
+{
+ register int key;
+ register int *isp1;
+ register int *isp2;
+ register int *iend;
+ register core *sp;
+ register int found;
+ register int n;
+
+#ifdef TRACE
+ mpu_fprintf( mpu_stderr,
+ MPU_UCS2( "Entering get_state(%d)\n" ), symbol );
+#endif
+
+ isp1 = kernel_base[symbol];
+ iend = kernel_end[symbol];
+ n = iend - isp1;
+ key = *isp1;
+
+ if( 0 > key || key >= nitems )
+ {
+ done( 2 );
+ }
+ sp = state_set[key];
+ if( sp )
+ {
+ found = 0;
+ while( !found )
+ {
+ if( sp->nitems == n )
+ {
+ found = 1;
+ isp1 = kernel_base[symbol];
+ isp2 = sp->items;
+
+ while( found && isp1 < iend )
+ {
+ if( *isp1++ != *isp2++ ) found = 0;
+ }
+ }
+
+ if( !found )
+ {
+ if( sp->link )
+ {
+ sp = sp->link;
+ }
+ else
+ {
+ sp = sp->link = new_state( symbol );
+ found = 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ state_set[key] = sp = new_state( symbol );
+ }
+ return( sp->number );
+
+} /******* End of get_state( int symbol ) ********************/
+
+
+void append_states( void )
+/***************************************************************
+
+ Description : append states
+
+ Concepts :
+
+ Use Global Variable: static int nshifts; | this file
+ static int *shiftset; | this file
+ static int *shift_symbol; | this file
+
+ Use Functions : int get_state (int symbol); | this file
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ register int i;
+ register int j;
+ register int symbol;
+
+#ifdef TRACE
+ mpu_fprintf( mpu_stderr,
+ MPU_UCS2( "Entering append_states()\n" ) );
+#endif
+ for( i = 1; i < nshifts; i++ )
+ {
+ symbol = shift_symbol[i];
+ j = i;
+ while( j > 0 && shift_symbol[j - 1] > symbol )
+ {
+ shift_symbol[j] = shift_symbol[j - 1];
+ j--;
+ }
+ shift_symbol[j] = symbol;
+ }
+
+ for( i = 0; i < nshifts; i++ )
+ {
+ symbol = shift_symbol[i];
+ shiftset[i] = get_state (symbol);
+ }
+
+} /******* End of append_states( void ) **********************/
+
+
+void initialize_states( void )
+/***************************************************************
+
+ Description : initialize states
+
+ Concepts :
+
+ Use Global Variable: int start_symbol; | main.c
+ int **derives; | main.c
+ int *rrhs; | main.c
+ core *first_state; | this file
+ static core *this_state; | this file
+ static core *last_state; | this file
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ register int i;
+ register int *start_derives;
+ register core *p;
+
+ start_derives = derives[start_symbol];
+ for( i = 0; start_derives[i] >= 0; ++i ) continue;
+
+ p = (core *)MALLOC( sizeof(core) + i*sizeof(int) );
+ if( p == 0 ) no_space();
+
+ p->next = 0;
+ p->link = 0;
+ p->number = 0;
+ p->accessing_symbol = 0;
+ p->nitems = i;
+
+ for( i = 0; start_derives[i] >= 0; ++i )
+ p->items[i] = rrhs[start_derives[i]];
+
+ first_state = last_state = this_state = p;
+ nstates = 1;
+
+} /******* End of initialize_states( void ) ******************/
+
+
+void new_itemsets( void )
+/***************************************************************
+
+ Description : new itensets
+
+ Concepts :
+
+ Use Global Variable: int nsyms; | main.c
+ int *ritem; | main.c
+ int *itemset; | closure.c
+ int *itemsetend; | closure.c
+ static int nshifts; | this file
+ static int *shift_symbol; | this file
+ static int **kernel_base; | this file
+ static int **kernel_end; | this file
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ register int i;
+ register int shiftcount;
+ register int *isp;
+ register int *ksp;
+ register int symbol;
+
+ for( i = 0; i < nsyms; i++ ) kernel_end[i] = 0;
+
+ shiftcount = 0;
+ isp = itemset;
+ while( isp < itemsetend )
+ {
+ i = *isp++;
+ symbol = ritem[i];
+ if( symbol > 0 )
+ {
+ ksp = kernel_end[symbol];
+ if( !ksp )
+ {
+ shift_symbol[shiftcount++] = symbol;
+ ksp = kernel_base[symbol];
+ }
+ *ksp++ = i + 1;
+ kernel_end[symbol] = ksp;
+ }
+ }
+ nshifts = shiftcount;
+
+} /******* End of new_itemsets( void ) ***********************/
+
+
+void save_shifts( void )
+/***************************************************************
+
+ Description : save shifts
+
+ Concepts :
+
+ Use Global Variable: static int nshifts; | this file
+ static core *this_state; | this file
+ static int *shiftset; | this file
+
+ Use Functions : char * allocate (unsigned u); | main.c
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ register shifts *p;
+ register int *sp1;
+ register int *sp2;
+ register int *send;
+
+ p = (shifts *)allocate( (unsigned)(sizeof (shifts) +
+ (nshifts - 1) * sizeof(int)) );
+
+ p->number = this_state->number;
+ p->nshifts = nshifts;
+
+ sp1 = shiftset;
+ sp2 = p->shift;
+ send = shiftset + nshifts;
+
+ while( sp1 < send ) *sp2++ = *sp1++;
+
+ if( last_shift )
+ {
+ last_shift->next = p;
+ last_shift = p;
+ }
+ else
+ {
+ first_shift = p;
+ last_shift = p;
+ }
+
+} /******* End of save_shifts( void ) ************************/
+
+
+void save_reductions( void )
+/***************************************************************
+
+ Description : save reduction
+
+ Concepts :
+
+ Use Global Variable: int *ritem; | main.c
+ int *itemset; | closure.c
+ int *itemsetend; | closure.c
+ static core *this_state; | this file
+ reductions *first_reduction; | this file
+ static reductions *last_reduction; | this file
+ static int *redset; | this file
+
+ Use Functions : char * allocate (unsigned u); | main.c
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ register int *isp;
+ register int *rp1;
+ register int *rp2;
+ register int item;
+ register int count;
+ register reductions *p;
+ register int *rend;
+
+ count = 0;
+ for( isp = itemset; isp < itemsetend; isp++ )
+ {
+ item = ritem[*isp];
+ if( item < 0 )
+ {
+ redset[count++] = -item;
+ }
+ }
+
+ if( count )
+ {
+ p = (reductions *)allocate( (unsigned)(sizeof (reductions) +
+ (count - 1) * sizeof(int)) );
+
+ p->number = this_state->number;
+ p->nreds = count;
+ rp1 = redset;
+ rp2 = p->rules;
+ rend = rp1 + count;
+
+ while( rp1 < rend ) *rp2++ = *rp1++;
+
+ if( last_reduction )
+ {
+ last_reduction->next = p;
+ last_reduction = p;
+ }
+ else
+ {
+ first_reduction = p;
+ last_reduction = p;
+ }
+ }
+
+} /******* End of save_reductions( void ) ********************/
+
+
+void set_derives( void )
+/***************************************************************
+
+ Description : set derives
+
+ Concepts :
+
+ Use Global Variable: int nsyms; | main.c
+ int nvars; | main.c
+ int nrules; | main.c
+ int start_symbol; | main.c
+ int **derives; | main.c
+ int *rlhs; | main.c
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ register int i, k;
+ register int lhs;
+ register int *rules;
+
+ derives = NEW2( nsyms, int * );
+ rules = NEW2( nvars + nrules, int );
+
+ k = 0;
+ for( lhs = start_symbol; lhs < nsyms; lhs++ )
+ {
+ derives[lhs] = rules + k;
+ for( i = 0; i < nrules; i++ )
+ {
+ if( rlhs[i] == lhs )
+ {
+ rules[k] = i;
+ k++;
+ }
+ }
+ rules[k] = -1;
+ k++;
+ }
+
+#ifdef _DEBUG
+ print_derives();
+#endif
+
+} /******* End of set_derives( void ) ************************/
+
+
+void set_nullable( void )
+/***************************************************************
+
+ Description : set nullable
+
+ Concepts :
+
+ Use Global Variable: int nsyms; | main.c
+ int nitems; | main.c
+ char **symbol_name; | main.c
+ int *ritem; | main.c
+ int *rlhs; | main.c
+
+ Use Functions : void no_space (void); | error.c
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ register int i, j;
+ register int empty;
+ int done;
+
+ nullable = (char *)MALLOC( nsyms );
+ if( nullable == 0 ) no_space();
+
+ for( i = 0; i < nsyms; ++i ) nullable[i] = 0;
+
+ done = 0;
+ while( !done )
+ {
+ done = 1;
+ for( i = 1; i < nitems; i++ )
+ {
+ empty = 1;
+ while( (j = ritem[i]) >= 0 )
+ {
+ if( !nullable[j] ) empty = 0;
+ ++i;
+ }
+ if( empty )
+ {
+ j = rlhs[-j];
+ if( !nullable[j] )
+ {
+ nullable[j] = 1;
+ done = 0;
+ }
+ }
+ }
+ }
+
+
+#ifdef _DEBUG
+ for( i = 0; i < nsyms; i++ )
+ {
+ if( nullable[i] )
+ mpu_fprintf( mpu_stdout,
+ MPU_UCS2( "%s is nullable\n" ), symbol_name[i] );
+ else
+ mpu_fprintf( mpu_stdout,
+ MPU_UCS2( "%s is not nullable\n" ), symbol_name[i] );
+ }
+#endif
+
+} /******* End of set_nullable (void) ************************/
+
+
+void generate_states( void )
+/***************************************************************
+
+ Description : generate states
+
+ Concepts :
+
+ Use Global Variable: int nitems; | main.c
+ int *itemset; | closure.c
+ unsigned *ruleset; | closure.c
+ static core *this_state; | this file
+
+ Use Functions : void allocate_storage (void); | this file
+ void free_storage (void); | this file
+ void save_reductions (void); | this file
+ void new_itemsets (void); | this file
+ void append_states (void); | this file
+ void save_shifts (void); | this file
+ void initialize_states (void); | this file
+ void set_first_derives (void); | closure.c
+ void closure (int *, int); | closure.c
+ void finalize_closure (void); | closure.c
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ allocate_storage();
+ itemset = NEW2( nitems, int );
+ ruleset = NEW2( SIZE_IN_INT( nrules ), unsigned );
+ set_first_derives();
+ initialize_states();
+
+ while( this_state )
+ {
+ closure( this_state->items, this_state->nitems );
+ save_reductions();
+ new_itemsets();
+ append_states();
+
+ if( nshifts > 0 ) save_shifts();
+
+ this_state = this_state->next;
+ }
+
+ finalize_closure();
+ free_storage();
+
+} /******* Enf of generate_states( void ) ********************/
+
+
+void lr0( void )
+/***************************************************************
+
+ Description : lr0
+
+ Concepts :
+
+ Use Global Variable:
+
+ Use Functions : void set_derives (void); | this file
+ void set_nullable (void); | this file
+ void generate_states (void); | this file
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ set_derives();
+ set_nullable();
+ generate_states();
+
+} /******* End of lr0( void ) ********************************/
+
+
+
+/********** this functions is not use of this file **********/
+/********** this functions is use in main.c: done() **********/
+
+void free_nullable( void )
+/***************************************************************
+
+ Description : free nullable
+
+ Concepts :
+
+ Use Global Variable: char *nullable; | main.c
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ FREE( nullable );
+
+} /******* End of free_nullable( void ) **********************/
+
+
+void free_derives( void )
+/***************************************************************
+
+ Description : free derives
+
+ Concepts :
+
+ Use Global Variable: int start_symbol; | main.c
+ int **derives; | main.c
+
+ Use Functions :
+
+ Parameters : [void]
+
+ Return : [void]
+
+ ***************************************************************/
+{
+ FREE( derives[start_symbol] );
+ FREE( derives );
+
+} /******* Enf of free_derives( void ) ***********************/
+
+#endif /* __NO_COMPILE */
+
+/******************** END OF FILE LR0.C **********************/