genobj.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 197 行
C
197 行
/****************************************************************************
*
* 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 <stdio.h>
#include <ctype.h>
#include "yacc.h"
#include "yaccins.h"
#include "alloc.h"
#define PROENTRY(i) ((i)+1)
#define ACCEPT (-1)
#define DEFAULT 0
#define VBLENTRY(i) (3*(i)+1+npro)
#define TOKENTRY(i) (3*(i)+2+npro)
#define OPTENTRY(i) (3*(i)+3+npro)
static int label;
extern void emitins( unsigned, unsigned );
extern void writeobj( int );
void genobj( void )
{
short int *symbol, *target;
short int *p, *q, *r;
short int action;
a_sym *sym;
a_pro *pro;
an_item *item;
a_state *x;
a_shift_action *tx;
a_reduce_action *rx;
int i, j, savings;
for( i = nterm; i < nsym; ++i )
symtab[i]->token = i - nterm;
label = OPTENTRY( nstate - 1 );
emitins( JMP, TOKENTRY( startstate->sidx ) );
target = CALLOC( nsym, short int );
for( i = 0; i < nsym; ++i )
target[i] = DEFAULT;
symbol = CALLOC( nsym, short int );
for( i = 0; i < nstate; ++i ){
x = statetab[i];
q = symbol;
for( tx = x->trans; sym = tx->sym; ++tx ){
if( sym == eofsym )
action = ACCEPT;
else if( sym->idx < nterm )
action = TOKENTRY(tx->state->sidx);
else
action = OPTENTRY(tx->state->sidx);
target[*q++ = sym->idx] = action;
}
savings = 0;
for( rx = x->redun; pro = rx->pro; ++rx ){
action = PROENTRY( pro->pidx );
p = Members( rx->follow, setmembers );
if( p - setmembers > savings ){
savings = p - setmembers;
r = q;
}
while( --p >= setmembers )
target[*q++ = *p] = action;
}
action = DEFAULT;
if( savings ){
action = target[*r];
p = r;
while( --savings >= 0 )
target[*p++] = DEFAULT;
}
emitins( LBL, TOKENTRY( x->sidx ) );
emitins( SCAN, 0 );
emitins( LBL, OPTENTRY( x->sidx ) );
emitins( CALL, VBLENTRY( x->sidx ) );
q = symbol;
for( j = nterm; j < nsym; ++j )
if( target[j] != DEFAULT )
*q++ = j;
if( q != symbol ){
emitv( symbol, target, q - symbol );
for( p = symbol; p < q; ++p )
target[*p] = DEFAULT;
}
emitins( LBL, VBLENTRY( x->sidx ) );
q = symbol;
for( j = 0; j < nterm; ++j )
if( target[j] != DEFAULT )
*q++ = j;
emitt( symbol, target, q - symbol, action );
for( p = symbol; p < q; ++p )
target[*p] = DEFAULT;
}
free( target );
free( symbol );
for( i = 0; i < npro; ++i ){
pro = protab[i];
if( pro != startpro ){
for( item = pro->item; item->p.sym; ++item );
emitins( LBL, PROENTRY( pro->pidx ) );
emitins( ACTION, PROPACK( item - pro->item, i ) );
emitins( REDUCE, PROPACK( item - pro->item, pro->sym->token ) );
}
}
writeobj( label + 1 );
}
static emitt( symbol, target, n, redun )
short int *symbol, *target, redun;
unsigned n;
{
unsigned i, j;
for( i = 0; i < n; ++i ){
emitins( TCMP, symtab[j = symbol[i]]->token );
emitins( JEQ, target[j] );
}
emitins( JMP, redun );
}
static emitv( symbol, target, n )
short int *symbol, *target;
unsigned n;
{
unsigned m;
int l1, l2;
if( n == 1 )
emitins( JMP, target[symbol[0]] );
else if( n != 0 ){
m = n/2; n -= m+1;
emitins( VCMP, symtab[symbol[m]]->token );
if( m == 1 )
emitins( JLT, target[symbol[0]] );
else if( m != 0 )
emitins( JLT, l1 = newlabel() );
if( n == 1 )
emitins( JGT, target[symbol[m+1]] );
else if( n != 0 )
emitins( JGT, l2 = newlabel() );
emitins( JMP, target[symbol[m]] );
if( m > 1 ){
emitins( LBL, l1 );
emitv( symbol, target, m );
}
if( n > 1 ){
emitins( LBL, l2 );
emitv( &symbol[m+1], target, n );
}
}
}
static int newlabel()
{
return( ++label );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?