invert.cc
来自「This is a resource based on j2me embedde」· CC 代码 · 共 236 行
CC
236 行
/* * @(#)invert.cc 1.7 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 <stdlib.h>#include "rule.h"#include "state.h"#include "wordlist.h"#include "symbol.h"#include "transition.h"// @(#)invert.cc 1.8 93/10/25static void invert_substate( const state * sp, wordlist * wlp, int depth );static state ** state_array = 0;static int n_state = 0;static int MAXDEPTH = 6;/* * Invert state transition tables * to produce a wordlist representation of a tree * having the given state labeling its top node. * Prefer leaf nodes to operators whenever possible. */static intis_terminal_state( stateno sno ){ return ( state_array[sno]->symp->type() == symbol::terminal );}static voidinit_state_array(){ int cur_n_states = allstates.n(); statelist_iterator sli = allstates; state * sp; if ( state_array != 0 ) free( (char *)state_array ); state_array = (state **) malloc( cur_n_states * sizeof (state*) ); while( ( sp = sli.next() ) != 0 ){ if ( sp->is_active() ) state_array[ sp->number ] = sp; } n_state = cur_n_states;}/* not static */voiddelete_inversion_info(){ // could have been called "clear_state_array". // delete cached info, so that state renumbering doesn't goof // us up too much. if ( state_array != 0 ){ free( (char *)state_array ); state_array = 0; } n_state = 0;}wordlistinvert_state( const state * sp ){ wordlist w; if (n_state < allstates.n() ) init_state_array(); invert_substate( sp, & w, 0 ); return w;}static voidinvert_binary_transition( binary_symbol * bsyp, register stateno target, stateno * lp, stateno * rp ){ register binary_transition * bsp = bsyp->transitions; register stateno *row; register statemap * lmap = &bsyp->lhs_map; register statemap * rmap = &bsyp->rhs_map; stateno l_save =0; stateno r_save =0; stateno a, b, amax, bmax; stateno l, r, lmax, rmax; int l_is_terminal, r_is_terminal; amax = bsp->row_max_stateno(); bmax = bsp->col_max_stateno(); lmax = lmap->max_ordinate(); rmax = rmap->max_ordinate(); for( a = 0; a <= amax ; a++ ){ row = bsp->state[a].state; for ( b = 0; b <= bmax ; b++ ){ if ( row[b] != target ) continue; // found a target transition. // use brute fource to find state pairs that map here. // Prefer terminal states. for ( l = 0; l <= lmax ; l++){ if ( (*lmap)[l] != a ) continue; l_is_terminal = is_terminal_state(l); for ( r = 0; r <= rmax; r++ ){ if ( (*rmap)[r] != b ) continue; // found one. r_is_terminal = is_terminal_state(r); switch( l_is_terminal + r_is_terminal ){ case 2: // both terminal: we done. *lp = l; *rp = r; return; case 1: // save in case we get no // better offer. l_save = l; r_save = r; break; default: // well, at least we tried. if ( (l_save == 0) || ( l < l_save ) || ( (l==l_save) && (r < r_save) ) ){ l_save = l; r_save = r; } } } } } } // // didn't find anything with 2 terminal substates. // return whatever we did find. *lp = l_save; *rp = r_save;}static voidinvert_unary_transition( unary_symbol * usyp, stateno target, stateno * lp ){ register unary_transition * usp = usyp->transitions; register stateno * row; register statemap * lmap = &usyp->lhs_map; stateno l_save =0; stateno a, amax; stateno l, lmax; amax = usp->max_stateno(); lmax = lmap->max_ordinate(); row = usp->state; for( a = 0; a <= amax ; a++ ){ if ( row[a] != target )continue; // found a target transition. // use brute fource to find state numbers that map here. // Prefer terminal states. for ( l = 0; l <= lmax ; l++){ if ( (*lmap)[l] != a ) continue; // found one. if( is_terminal_state(l)){ // terminal: we done. *lp = l; return; } else { // save in case we get no // better offer. if ( l_save == 0 || l < l_save ) l_save = l; } } } // // didn't find anything with terminal substate. // return whatever we did find. *lp = l_save;}static voidinvert_substate( const state * sp, wordlist * wlp, int depth ){ const symbol * ssp = sp->symp; if ( ssp == 0 ){ // null state here. return; } if ( depth > MAXDEPTH ){ wlp->add( "..." ); return; } wlp->add( ssp->name() ); switch( ssp->type() ){ case symbol::terminal: // we're done. There are no subtrees. return; case symbol::unaryop: stateno substate; invert_unary_transition( (unary_symbol *)ssp, sp->number, &substate ); invert_substate( state_array[ substate ], wlp, depth+1 ); return; case symbol::binaryop: stateno l_substate; stateno r_substate; invert_binary_transition( (binary_symbol *)ssp, sp->number, &l_substate , &r_substate ); invert_substate( state_array[ l_substate ], wlp, depth+1 ); invert_substate( state_array[ r_substate ], wlp, depth+1 ); return; default: fprintf(stderr,"invert_substate: illegal symbol type\n"); return; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?