gensmall.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 257 行
C
257 行
/****************************************************************************
*
* 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"
enum {
FITS_A_BYTE,
FITS_A_WORD
};
enum {
ACTION_AMBIGUOUS = 0x8000,
ACTION_SHIFT = 0x4000,
ACTION_REDUCE = 0x0000,
ACTION_STATE = 0x3fff,
};
typedef struct {
short token;
short action;
} a_entry;
static a_entry *table;
static unsigned used, table_size;
void dump_define( char *name, int i )
{
fprintf( actout, "#define\t%-20s\t%d\n", name, i );
}
static int tabcol;
static void begin_table( char *tipe, char *name )
{
fprintf( actout, "static const %s YYFAR %s[] = {", tipe, name );
tabcol = 0;
}
static void puttab( int fits, int i )
{
char *format;
unsigned mod;
if( fits == FITS_A_BYTE ) {
if(( i & 0x00ff ) != i ) {
msg( "value cannot fit into table! (%x)", i );
}
format = "%3d";
mod = 20;
} else {
format = "%5d";
mod = 13;
}
if( tabcol ) {
fprintf( actout, "," );
}
if( !(tabcol % mod) ) {
fprintf( actout, "\n" );
}
fprintf( actout, format, i );
++tabcol;
}
static void end_table( void )
{
fprintf( actout, "\n};\n" );
}
void add_table( short token, short action )
{
if( used == table_size ) {
table_size += 64;
table = REALLOC( table, table_size, a_entry );
}
table[ used ].token = token;
table[ used ].action = action;
++used;
}
void dump_reduction( a_reduce_action *rx, unsigned *base )
{
a_pro *pro;
short *p;
pro = rx->pro;
p = Members( rx->follow, setmembers );
while( --p >= setmembers ) {
add_table( *p, ACTION_REDUCE | pro->pidx );
++(*base);
}
}
void genobj( void )
{
int i;
int ntoken;
int this_token;
int any_token;
int action;
short *p;
a_pro *pro;
a_state *x;
a_reduce_action *rx;
a_reduce_action *default_reduction;
a_shift_action *tx;
a_sym *sym;
an_item *item;
unsigned max;
unsigned sum;
unsigned savings;
unsigned base;
unsigned rule_base;
short *state_base;
ntoken = 0;
for( i = 0; i < nterm; ++i ) {
this_token = symtab[i]->token;
if( this_token > ntoken ) {
ntoken = this_token;
}
}
for( i = nterm; i < nsym; ++i ) {
symtab[i]->token = ++ntoken;
}
any_token = ++ntoken;
state_base = CALLOC( nstate, short );
base = 0;
max = 0;
sum = 0;
for( i = 0; i < nstate; ++i ){
state_base[i] = base;
x = statetab[i];
for( tx = x->trans; sym = tx->sym; ++tx ) {
add_table( sym->idx, ACTION_SHIFT | tx->state->sidx );
++base;
}
default_reduction = NULL;
savings = 0;
for( rx = x->redun; rx->pro != NULL; ++rx ){
p = Members( rx->follow, setmembers );
if( p != setmembers ) {
if( p - setmembers > savings ) {
savings = p - setmembers;
if( default_reduction != NULL ) {
dump_reduction( default_reduction, &base );
}
default_reduction = rx;
} else {
dump_reduction( rx, &base );
}
}
}
if( default_reduction != NULL ) {
pro = default_reduction->pro;
action = ACTION_REDUCE | pro->pidx;
} else {
action = ACTION_SHIFT | 0;
}
add_table( any_token, action );
++base;
sum += base - state_base[i];
if( base - state_base[i] > max ) {
max = base - state_base[i];
}
}
printf( "avg: %u max: %u\n", sum / nstate, max );
dump_define( "YYANYTOKEN", any_token );
dump_define( "YYEOFTOKEN", eofsym->token );
dump_define( "YYSTART", startstate->sidx );
begin_table( "YYACTTYPE", "yybasetab" );
for( i = 0; i < nstate; ++i ) {
puttab( FITS_A_WORD, state_base[i] );
}
end_table();
begin_table( "YYCHKTYPE", "yychktab" );
for( i = 0; i < used; ++i ) {
puttab( FITS_A_BYTE, table[i].token );
}
end_table();
begin_table( "YYACTTYPE", "yyacttab" );
for( i = 0; i < used; ++i ) {
puttab( FITS_A_WORD, table[i].action );
}
end_table();
begin_table( "YYPLENTYPE", "yyplentab" );
for( i = 0; i < npro; ++i ) {
for( item = protab[i]->item; item->p.sym; ++item )
/* do nothing */;
puttab( FITS_A_BYTE, item - protab[i]->item );
}
end_table();
begin_table( "YYPLHSTYPE", "yyplhstab" );
for( i = 0; i < npro; ++i ) {
puttab( FITS_A_BYTE, protab[i]->sym->token );
}
end_table();
fprintf( actout, "#ifdef YYDEBUG\n" );
rule_base = 0;
begin_table( "unsigned short", "yyrulebase" );
for( i = 0; i < npro; ++i ) {
for( item = protab[i]->item; item->p.sym; ++item )
/* do nothing */;
puttab( FITS_A_WORD, rule_base );
rule_base += item - protab[i]->item;
}
end_table();
begin_table( "YYCHKTYPE", "yyrhstoks" );
for( i = 0; i < npro; ++i ) {
for( item = protab[i]->item; item->p.sym; ++item ) {
puttab( FITS_A_BYTE, item->p.sym->token );
}
}
end_table();
begin_table( "char YYFAR *", "yytoknames" );
fputc( '\n', actout );
for( i = 0; i < nsym; ++i ) {
fprintf( actout, "\"%s\",\n", symtab[ i ]->name );
}
fprintf( actout, "\"\"" );
end_table();
fprintf( actout, "#endif\n" );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?