lr0.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 240 行

C
240
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stdlib.h>
#include <string.h>
#include "yacc.h"
#include "alloc.h"

index_t nbstate;
index_t nstate;
index_t nvtrans;
index_t nredun;

a_state **statetab, *statelist, **statetail, *startstate, *errstate;

static a_state *addState(
    a_state **enter,
    an_item **s,
    an_item **q,
    a_state *parent )
{
    a_parent *add_parent;
    an_item **p, **t;
    int kersize;

    for( p = s; p != q; ++p ) {
         Mark( **p );
    }
    kersize = q - s;
    for( ; *enter; enter = &(*enter)->same_enter_sym ){
         if( (*enter)->kersize == kersize ){
             p = (*enter)->name.item;
             for( t = p + kersize; p != t; ++p ) {
                 if( !IsMarked( **p ) ) {
                     goto contin;
                 }
             }
             break;
         }
         contin:;
    }
    for( p = s; p != q; ++p ) {
         Unmark( **p );
     }
    if( !*enter ){
        *enter = CALLOC( 1, a_state );
        State( **enter );
        *statetail = *enter;
        statetail = &(*enter)->next;
        (*enter)->kersize = kersize;
        (*enter)->name.item = CALLOC( kersize + 1, an_item * );
        memcpy( (*enter)->name.name, s, kersize*sizeof(an_item *) );
        (*enter)->sidx = nstate++;
    }
    if( parent != NULL ) {
        add_parent = CALLOC( 1, a_parent );
        add_parent->state = parent;
        add_parent->next = (*enter)->parents;
        (*enter)->parents = add_parent;
    }
    return( *enter );
}

/*  Heap Sort.  Reference:  Knuth, Vol. 3, pages 146, 147. */
static void Sort( void **vec, int n, bool (*lt)( void *, void *) )
{
    int i, j, l, r;
    void *k;

    if( n > 1 ){
        l = n/2;  r = n - 1;
        while( TRUE ) {
            if( l > 0 )
                k = vec[--l];
            else {
                k = vec[r];
                vec[r] = vec[0];
                if( --r <= 0 ){
                    vec[0] = k;
                    return;
                }
            }
            j = l;
            while( TRUE ) {
                i = j;  j = 2*j + 1;
                if( j > r )
                    break;
                if( j < r && (*lt)( vec[j], vec[j+1] ) )
                    ++j;
                if( !(*lt)( k, vec[j] ) )
                    break;
                vec[i] = vec[j];
            }
            vec[i] = k;
        }
    }
}

static bool itemlt( void *_a, void *_b )
{
    an_item *a = _a;
    an_item *b = _b;

    if( a->p.sym )
        return( b->p.sym && a[0].p.sym > b[0].p.sym );
    else
        return( b->p.sym || a[1].p.pro > b[1].p.pro );
}

static void Complete( a_state *x, an_item **s )
{
    an_item **p, **q;
    a_reduce_action *rx;
    a_shift_action *tx;
    a_pro *pro;
    int n;
    q = s;
    for( p = x->name.item; *p; ++p ){
        Mark( **p );
        *q++ = *p;
    }
    for( p = s; p < q; ++p ) {
        if( (*p)->p.sym ) {
            for( pro = (*p)->p.sym->pro; pro; pro = pro->next ) {
                if( !IsMarked( *pro->item ) ){
                    Mark( *pro->item );
                    *q++ = pro->item;
                }
            }
          }
    }
    for( p = s; p < q; ++p ) {
        Unmark( **p );
    }
    Sort( (void **)s, q - s, itemlt );
    for( p = s; p < q && !(*p)->p.sym; ++p )
          /* do nothing */;
    nredun += (n = p - s);
    rx = x->redun = CALLOC( n + 1, a_reduce_action );
    for( p = s; p < q && !(*p)->p.sym; ++p ) {
        (rx++)->pro = (*p)[1].p.pro;
    }
    if( p == q ) {
        x->trans = CALLOC( 1, a_shift_action );
    } else {
        n = 1;
        s = p;
        while( ++p < q ) {
            n += (p[-1]->p.sym != p[0]->p.sym);
        }
        tx = x->trans = CALLOC( n + 1, a_shift_action );
        do {
            tx->sym = (*s)->p.sym;
            if( tx->sym->pro ) {
                ++nvtrans;
            }
            for( p = s; p < q && (*p)->p.sym == tx->sym; ++p ) {
                ++*p;
            }
            tx->state = addState( &tx->sym->enter, s, p, x );
            s = p;
            ++tx;
        } while( s < q );
    }
}

void lr0( void )
{
    a_state *x;
    an_item **s;

    s = CALLOC( nitem, an_item * );
    statetail = &statelist;
    *s = startsym->pro->item;
    startstate = addState( &startsym->enter, s, s + 1, NULL );
    for( x = statelist; x; x = x->next ) {
        Complete( x, s );
    }
    Complete( errstate = addState( &errsym->enter, s, s, NULL ), s );
    free( s );
}

void SetupStateTable( void )
{
    a_state *x;

    free( statetab );
    statetab = CALLOC( nstate, a_state * );
    for( x = statelist; x; x = x->next ) {
        statetab[ x->sidx ] = x;
    }
}

void RemoveDeadStates( void )
{
    int i;
    int j;
    a_state *x;

    j = 0;
    for( i = 0; i < nstate; ++i ) {
        x = statetab[i];
        if( ! IsDead( *x ) ) {
            x->sidx = j;
            statetab[j] = x;
            ++j;
        }
    }
    nstate = j;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?