예제 #1
0
static void performShift( traceback **h, a_sym *sym )
{
    a_state     *state;

    state = findNewShiftState( (*h)->state, sym );
    pushTrace( h, state, sym );
}
예제 #2
0
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 );
}
예제 #3
0
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 );
}
예제 #4
0
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;
                }
            }
        }
    }
}
예제 #5
0
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 );
}