compute_states.cc
来自「This is a resource based on j2me embedde」· CC 代码 · 共 424 行
CC
424 行
/* * @(#)compute_states.cc 1.8 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */#include <stdio.h>#include <assert.h>#include "symbol.h"#include "rule.h"#include "state.h"#include "item.h"#include "transition.h"#include "debug.h"extern "C" { int malloc_verify(void); };extern "C" { extern int _lbound, _ubound; }; // from malloc.oextern int semantic_error;//// DEBUGGING RELATEDint state_to_trace = -1;extern void printstateinversion();// END DEBUGGING RELATED// /* * give terminals a state "transition" */unsigned staticinitialize_terminals(void){ symbollist_iterator s_i = all_symbols; symbol *sp; terminal_symbol *tsp; state * resultp; while ((sp = s_i.next() ) != 0){ if (sp->type() == symbol::terminal){ tsp = (terminal_symbol *)sp; resultp = state::combine( tsp ); if (DEBUG(COMBINE)){ if ( state_to_trace < 0 || state_to_trace == resultp->number ) printf("COMBINE( %s ): %d\n", tsp->name(), resultp->number ); } // link it up... tsp->transitions = leaf_transition::newtransition( tsp ); insert_stateno( tsp->transitions, resultp->number); } } return allstates.n();}void staticunary_closure_iteration( unary_symbol *usp ){ unary_transition *tp; state * resultp; int lstateno, oldn; int curn; if (usp->transitions == 0) usp->transitions = unary_transition::newtransition( usp ); tp = usp->transitions; oldn = tp->max_stateno(); curn = usp->lhs_map.max_mapping(); tp->grow(curn); // iterate through all new mapped states. for ( lstateno = oldn+1 ; lstateno <= curn ; lstateno ++ ){ resultp = state::combine( usp, lstateno ); insert_stateno( tp, lstateno, resultp->number); }}void staticbinary_closure_iteration( binary_symbol *bsp ){ binary_transition *tp; state * resultp; int oldrowmax, oldcolmax, colmin, rstateno, lstateno; int currowmax, curcolmax; if (bsp->transitions == 0) bsp->transitions = binary_transition::newtransition( bsp ); tp = bsp->transitions; oldrowmax = tp->row_max_stateno(); oldcolmax = tp->col_max_stateno(); currowmax = bsp->lhs_map.max_mapping(); curcolmax = bsp->rhs_map.max_mapping(); tp->grow( currowmax, curcolmax ); // iterate through all mapped states. for ( lstateno = 0; lstateno <= currowmax ; lstateno ++ ){ if ( lstateno <= oldrowmax ) colmin = oldcolmax+1; else colmin = 0; for ( rstateno = colmin ; rstateno <= curcolmax ; rstateno ++ ){ resultp = state::combine( bsp, lstateno, rstateno ); insert_stateno( tp, lstateno, rstateno, resultp->number ); } }}unsigned staticclosure_iteration( int nstates, int nnewstates ){ symbollist_iterator s_i = all_symbols; symbol * sp; int curno = allstates.n(); int old_nstates = nstates - nnewstates; /* * We only have to look at states that appeared in the previous * call to closure_iteration, or in initialize_terminals. * To expedite that process, we revv up an iterator to the * current state of the states, RELYING ON THE FACT THAT * ITERATION ORDER IS INSERTION ORDER, IS STATE NUMBER ORDER!! * And since list addition is incompatable with list iteration, * we make a copy to iterate over. */ assert( curno == nstates ); while ( (sp = s_i.next() ) != 0){ switch (sp->type()){ case symbol::unaryop: unary_closure_iteration( (unary_symbol *)sp ); break; case symbol::binaryop: binary_closure_iteration( (binary_symbol *)sp ); break; default: // don't care break; } } return allstates.n()- curno;}intcompute_parental_matchsets( int nstates, int nnewstates ){ /* * For each new state that's appeared in the last * iteration, determine which can interestingly appear * on the lhs and rhs of any non-leaf terminal, and * add to matchsets accordingly. * This precomputation speeds the binary closure_iterations * by (1) factoring cse's of binary state building, and * (2) allowing early detection of empty sets and consequently * uninteresting transitions. * Returns: * 0: no items were added to any cost set * non-0: something was added. */ statelist_iterator sl_i; state * st_p; symbol * sym_p; item_cost cost; item_costset itemset; register item_table * t; item this_item, parent_item; item_costset_iterator set_i; int did_something = 0; int did_something_binary = 0; symbollist_iterator sym_i; unsigned v, mapped_v; int min_state_this_time = nstates - nnewstates; int max_state_this_time = nstates - 1; // DEBUGGING RELATED int tracing; int something_new; // END DEBUGGING RELATED sl_i = allstates; while( (st_p = sl_i.next() ) != 0 ){ tracing = 0; if ( st_p->number < min_state_this_time ) continue; // done before. itemset = st_p->items; t = itemset.pattab(); set_i = itemset; // DEBUGGING RELATED if ( st_p->number == state_to_trace ){ printf("Compute-parental: tracing state #%d\n", st_p->number); tracing = 1; } // END DEBUGGING RELATED while( (this_item = set_i.next( &cost ) ) != item_none ){ switch( t->item_subpart( this_item ) ){ case item_table::leftpart: parent_item = t->item_parent(this_item); sym_p = t->item_subtree( parent_item )->node; something_new = sym_p->lhs_temp_sets.cost_add( st_p->number, parent_item, cost ); did_something += something_new; // DEBUGGING RELATED if ( tracing ){ printf( "...on left of %s: %d\n", sym_p->name(), something_new ); } // END DEBUGGING RELATED break; case item_table::rightpart: parent_item = t->item_parent(this_item); sym_p = t->item_subtree( parent_item )->node; something_new = sym_p->rhs_temp_sets.cost_add( st_p->number, parent_item, cost ); did_something += something_new; // DEBUGGING RELATED if ( tracing ){ printf( "...on right of %s: %d\n", sym_p->name(), something_new ); } // END DEBUGGING RELATED break; } } } if ( ! did_something ) return 0; /* * now, for all the non-leaf terminal symbols, * take the temp_sets and insert into them into the "real", * unique sets. This also gives us our mapping, which we note. * Don't forget to clean up after. */ sym_i = all_symbols; did_something = 0; while ( ( sym_p = sym_i.next() ) != 0 ){ switch (sym_p->type()){ case symbol::unaryop: sym_p->lhs_map.grow( max_state_this_time ); for ( v = min_state_this_time; v <= max_state_this_time; v++ ){ something_new = 0; itemset =sym_p->lhs_temp_sets.get( v ); // DEBUGGING RELATED if ( v == state_to_trace ){ printf("...on left of unary %s", sym_p->name() ); } // END DEBUGGING RELATED mapped_v = sym_p->lhs_sets.add_itemset( &itemset, &something_new ); sym_p->lhs_map.new_mapping( v, mapped_v ); did_something += something_new; // DEBUGGING RELATED if ( v == state_to_trace ){ printf(" maps to %d: %d\n", mapped_v, something_new ); } // END DEBUGGING RELATED } sym_p->lhs_temp_sets.destruct(); break; case symbol::binaryop: sym_p->lhs_map.grow( max_state_this_time ); sym_p->rhs_map.grow( max_state_this_time ); for ( v = min_state_this_time; v <= max_state_this_time; v++ ){ something_new = 0; itemset =sym_p->lhs_temp_sets.get( v ); // DEBUGGING RELATED if ( v == state_to_trace ){ printf("...on left of binary %s", sym_p->name() ); } // END DEBUGGING RELATED mapped_v = sym_p->lhs_sets.add_itemset( &itemset, &something_new ); sym_p->lhs_map.new_mapping( v, mapped_v ); did_something += something_new; // DEBUGGING RELATED if ( v == state_to_trace ){ printf(" maps to %d: %d\n", mapped_v, something_new ); } // END DEBUGGING RELATED something_new = 0; // DEBUGGING RELATED if ( v == state_to_trace ){ printf("...on right of binary %s", sym_p->name() ); } // END DEBUGGING RELATED itemset =sym_p->rhs_temp_sets.get( v ); mapped_v = sym_p->rhs_sets.add_itemset( &itemset, &something_new ); sym_p->rhs_map.new_mapping( v, mapped_v ); did_something += something_new; // DEBUGGING RELATED if ( v == state_to_trace ){ printf(" maps to %d: %d\n", mapped_v, something_new ); } // END DEBUGGING RELATED } sym_p->lhs_temp_sets.destruct(); sym_p->rhs_temp_sets.destruct(); break; default: break; // others are leaves. } } return did_something;}static voidresize_a_map( statemap * smp, int max_stateno ){ int stateno = smp->max_ordinate(); if ( max_stateno <= stateno ) return; smp->grow( max_stateno ); for( stateno +=1; stateno <= max_stateno; stateno ++ ) smp->new_mapping( stateno, 0 );}static voidresize_all_maps( int max_stateno ){ symbollist_iterator s_i = all_symbols; symbol * sp; /* * We have no more legal transformations to add, * but we should make sure to represent the illegal ones * without problem. */ while ( (sp = s_i.next() ) != 0){ switch (sp->type()){ case symbol::binaryop: resize_a_map( & sp->rhs_map, max_stateno ); // FALL THRU case symbol::unaryop: resize_a_map( & sp->lhs_map, max_stateno ); break; default: // don't care break; } }}voidcompute_states(void){ // boot with empty state and with terminals. // then do a small number of closure iterations; int nstates; int nnewstates; int niters; state * sp; int parental_sets_augmented; // this must be first!! sp = state::null_state( &all_items ); nstates = initialize_terminals(); nnewstates = nstates; for (niters=1; niters<10; niters +=1){ parental_sets_augmented = compute_parental_matchsets( nstates, nnewstates ); if ( ! parental_sets_augmented ){ /* * none of the states recently added had any * effect on the transition matricies for any of * the non-leaf terminals. So don't even bother * doing another closure, because there will be * no new legal transitions. However, we should * make sure that all our state maps are long enough * to represent the illegal transitions that may * occur. */ resize_all_maps( nstates-1 ); return; } nnewstates = closure_iteration( nstates, nnewstates ); if (nnewstates == 0){ // we've iterated till done. we're done. return; } nstates += nnewstates; } printf("\n\nITERATION TIMEOUT\n"); semantic_error += 1; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?