static void performShift( traceback **h, a_sym *sym ) { a_state *state; state = findNewShiftState( (*h)->state, sym ); pushTrace( h, state, sym ); }
static int shiftToSingleReduce( a_state *state, a_shift_action *saction ) { a_state *sub_state; a_sym *new_lhs; int made_change; /* requirements: (1) state (s1) must have a shift on token (t) into a state (s2) that only has one action and it must be a reduction by an unit production (after which state (s1) will shift into state (s3)) action: change shift action for token (t) to shift into state (s3) */ made_change = 0; for( sub_state = saction->state; (new_lhs = onlyOneReduction( sub_state )) != NULL; sub_state = saction->state ) { saction->state = findNewShiftState( state, new_lhs ); removeParent( sub_state, state ); made_change = 1; ++changeOccurred; } saction->units_checked = true; return( made_change ); }
static a_pro *analyseParents( a_state *state, a_pro *pro, a_word *reduce_set ) { a_pro *test_pro; a_pro *new_pro; a_sym *old_lhs; a_state *parent_state; a_state *new_state; a_parent *parent; a_parent *split_parent; a_reduce_action *raction; split_parent = NULL; new_pro = NULL; old_lhs = pro->sym; for( parent = state->parents; parent != NULL; parent = parent->next ) { parent_state = parent->state; new_state = findNewShiftState( parent_state, old_lhs ); if( new_state == NULL ) { printf( "error! %u %s %u\n", state->sidx, old_lhs->name, parent_state->sidx ); exit(1); } for( raction = new_state->redun; (test_pro = raction->pro) != NULL; ++raction ) { if( !test_pro->unit ) { continue; } if( EmptyIntersection( reduce_set, raction->follow ) ) { continue; } if( new_pro == NULL ) { new_pro = test_pro; } else if( new_pro != test_pro ) { new_pro = NULL; break; } /* we have a reduce of a unit rule on similar tokens */ Intersection( reduce_set, raction->follow ); break; } if( new_pro == NULL || test_pro == NULL ) { split_parent = parent; } } if( Empty( reduce_set ) || split_parent != NULL ) { new_pro = NULL; } return( new_pro ); }
static void doRunUntilShift( traceback **h, a_sym *sym, traceback **ht, unsigned count ) { index_t sidx; a_sym *chk_sym; a_state *state; a_state *top; a_reduce_action *raction; for( ;; ) { if( *h == NULL ) break; top = (*h)->state; if( top == NULL ) { flushStack( h ); break; } state = findNewShiftState( top, sym ); if( state != NULL ) { pushTrace( h, state, sym ); pushTrace( ht, NULL, sym ); if( sym == eofsym ) { break; } for( ;; ) { if( *h == NULL ) break; top = (*h)->state; if( top->redun->pro == NULL ) break; performReduce( h, top->redun->pro ); } break; } sidx = sym->idx; for( raction = top->redun; raction->pro != NULL; ++raction ) { if( IsBitSet( raction->follow, sidx ) ) { performReduce( h, raction->pro ); break; } } if( raction->pro == NULL ) { if( sym != eofsym ) { /* a syntax error will result */ flushStack( h ); break; } if( top->redun->pro != NULL ) { performReduce( h, top->redun->pro ); } else { if( count ) { --count; chk_sym = findNewShiftSym( top, ht ); } else { chk_sym = NULL; } if( chk_sym != NULL ) { doRunUntilShift( h, chk_sym, ht, count ); } else { /* a syntax error will result */ flushStack( h ); break; } } } } }
static int immediateShift( a_state *state, a_reduce_action *raction, a_pro *pro ) { a_sym *unit_lhs; a_sym *term_sym; a_state *after_lhs_state; a_state *final_state; a_state *check_state; a_parent *parent; a_word *follow; set_size *mp; int change_occurred; /* requirements: (1) state must have a reduction by a unit production (L1 <- r1) on a set of tokens (s) (2) all parents must shift to a state where a shift on a terminal in s ends up in a new state that is the same for all parents action: add shift on terminal to common parent shift state */ // dumpInternalState( state ); follow = raction->follow; unit_lhs = pro->sym; change_occurred = 0; for( mp = Members( follow ); mp != setmembers; ) { --mp; term_sym = symtab[*mp]; check_state = NULL; for( parent = state->parents; parent != NULL; parent = parent->next ) { after_lhs_state = findNewShiftState( parent->state, unit_lhs ); after_lhs_state = onlyShiftsOnTerminals( after_lhs_state ); if( after_lhs_state == NULL ) { check_state = NULL; break; } final_state = findNewShiftState( after_lhs_state, term_sym ); if( final_state == NULL ) { check_state = NULL; break; } if( check_state != NULL && check_state != final_state ) { check_state = NULL; break; } check_state = final_state; } if( check_state != NULL ) { /* all shifts in *terminal ended up in the same state! */ state->trans = addShiftAction( term_sym, check_state, state->trans ); ClearBit( follow, *mp ); change_occurred = 1; ++changeOccurred; } } if( Empty( follow ) ) { state->redun = removeReduceAction( raction, state->redun ); change_occurred = 1; } return( change_occurred ); }