yydriver.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,128 行 · 第 1/5 页

C
2,128
字号
/*
YYDRIVER: driver code to make use of YACC generated parser tables and support

00002 - increment to force compile
*/

#include "plusplus.h"
#include "errdefns.h"
#include "ytab.gh"
#include "preproc.h"
#include "fnbody.h"
#include "ptree.h"
#include "enum.h"
#include "class.h"
#include "ring.h"
#include "stack.h"
#include "decl.h"
#include "carve.h"
#include "rewrite.h"
#include "toggle.h"
#include "ppops.h"
#include "gstack.h"
#include "vstk.h"
#include "yydriver.h"
#include "initdefs.h"
#include "pcheader.h"
#include "stats.h"
#include "codegen.h"
#include "namspace.h"
#include "memmgr.h"
#ifndef NDEBUG
#include "pragdefn.h"
#endif

ExtraRptCtr( lookup_lexical );
ExtraRptCtr( lookup_other );
ExtraRptCtr( found_type );
ExtraRptCtr( found_template );
ExtraRptCtr( found_namespace );
ExtraRptCtr( found_id );

// YY* definitions
#define YYFAR
#ifndef NDEBUG
    #define YYDEBUG
#endif

typedef uint_16         YYACTIONBASETYPE;
typedef uint_16         YYACTIONTYPE;
typedef uint_16         YYBITBASETYPE;
typedef uint_8          YYBITTYPE;
typedef uint_8          YYPLENTYPE;
typedef uint_16         YYPLHSTYPE;

typedef unsigned        YYTOKENTYPE;

typedef union {
    unsigned                    flags;
    YYTOKENTYPE                 token;
    TYPE                        type;
    BASE_CLASS                  *base;
    DECL_SPEC                   *dspec;
    DECL_INFO                   *dinfo;
    REWRITE                     *rewrite;
    SYMBOL_NAME                 sym;
    PTREE                       tree;
} YYSTYPE;

enum {
    RAW_REDUCTION       = 0x8000,
    RAW_UNIT_REDUCTION  = 0x4000,
    RAW_MASK            = 0x3fff,
};

#define STACK_DEPTH     256

#define BLOCK_RESTART_PARSE     8
#define BLOCK_VALUE_STACK       4
#define BLOCK_STATE_STACK       4
#define BLOCK_LOCATION_STACK    4

static carve_t carveRESTART_PARSE;
static carve_t carveVALUE_STACK;
static carve_t carveSTATE_STACK;
static carve_t carveLOCATION_STACK;

typedef struct restart_parse RESTART_PARSE;
typedef struct parse_stack PARSE_STACK;
struct restart_parse {
    RESTART_PARSE       *next;
    PARSE_STACK         *state;
    YYACTIONTYPE        *ssp;
    GLOBAL_STACK        *gstack;
    SCOPE               reset_scope;
};

struct parse_stack {
    PARSE_STACK         *next;
    RESTART_PARSE       *restart;
    TOKEN_LOCN          *lsp;
    TOKEN_LOCN          *lstack;
    YYSTYPE             *vsp;
    YYSTYPE             *vstack;
    YYACTIONTYPE        *ssp;
    YYACTIONTYPE        *sstack;
    YYACTIONTYPE        *exhaust;
    GLOBAL_STACK        *gstack;
    void                *qualifications;
    SCOPE               reset_scope;
    TYPE                class_colon;
    VSTK_CTL            look_ahead_storage;
    unsigned            look_ahead_count;
    unsigned            look_ahead_index;
    TOKEN_LOCN          template_record_locn;
    REWRITE             *template_record_tokens;
    VSTK_CTL            angle_stack;
    unsigned            no_super_tokens : 1;
    unsigned            use_saved_tokens : 1;
    unsigned            favour_reduce : 1;
    unsigned            favour_shift : 1;
    unsigned            look_ahead_stack : 1;
    unsigned            look_ahead_active : 1;
    unsigned            template_decl : 1;
    unsigned            template_class_inst_defer : 1;
    unsigned            special_colon_colon : 1;
    unsigned            special_gt_gt : 1;
};

typedef struct {
    YYSTYPE             yylval;
    TOKEN_LOCN          yylocation;
    YYTOKENTYPE         yytok;
} look_ahead_storage;

typedef struct {
    unsigned            paren_depth;
} angle_bracket_stack;

static YYSTYPE yylval;
static TOKEN_LOCN yylocation;
static YYTOKENTYPE currToken;
static PARSE_STACK *currParseStack;
static SUICIDE_CALLBACK parserSuicide;

typedef enum {
    P_RELEX,            /* an external parse has occurred; so resynchronize */
    P_SHIFT,            /* automaton shifted a token */
    P_ACCEPT,           /* parse is completed */
    P_SPECIAL,          /* special actions follow ... */
    P_CLASS_TEMPLATE,   /* class template member found */
    P_DEFER_DEFN,       /* don't want to fully define the class instantiation */
    P_ERROR,            /* parse errors follow ... */
    P_SYNTAX,           /* parse cannot continue due to syntax error */
    P_OVERFLOW,         /* parse cannot continue due to parser stack overflow */
    P_DIAGNOSED,        /* parse cannot continue due to diagnosed errors */
    P_NULL
} p_action;

typedef enum {          /* lookahead actions */
    LA_UNDERFLOW,       /* reduce popped off the triggering context */
    LA_DISAMBIGUATE,    /* lookahead requires another disambiguation */
    LA_SYNTAX,          /* found a syntax error */
    LA_NULL,
    LA_MAX
} la_action;

#define LK_DEFS                                 /* lookup return value */ \
    LKDEF( LK_ID,       ID )                    /* identifier */ \
    LKDEF( LK_TYPE,     TYPE_NAME )             /* type name */ \
    LKDEF( LK_TEMPLATE, TEMPLATE_NAME )         /* template name */ \
    LKDEF( LK_NAMESPACE,NAMESPACE_NAME )        /* namespace name */

typedef enum {          /* lookup return value */
    #define LKDEF( e, t )       e,
    LK_DEFS
    #undef LKDEF
} lk_result;

typedef enum {
    LK_LEXICAL  = 0x01, /* lexical lookup required */
    LK_LT_AHEAD = 0x02, /* '<' token is after 'id' */
    LK_NULL     = 0
} lk_control;

enum {
    CH_ALREADY_STARTED  = 0x01,         /* C:: chain has already been started */
    CH_NULL             = 0x00
};

static const unsigned lookupToken[] = {
    #define LKDEF( e, t )       Y_##t,
    LK_DEFS
    #undef LKDEF
};

static const unsigned globalLookupToken[] = {
    #define LKDEF( e, t )       Y_GLOBAL_##t,
    LK_DEFS
    #undef LKDEF
};



#define LA_SHIFT_TOKEN                  Y_SHIFT_SPECIAL
#define LA_REDUCE_TOKEN                 Y_REDUCE_SPECIAL

#define YYACTION_IS_SHIFT( x )          ( (x) < YYUSED )

#define YYACTION_SHIFT_STATE( x )       (x)
#define YYACTION_REDUCE_RULE( x )       ( (x) + YYUSED )

#include "yylex.gh"

#ifndef NDEBUG
static void dump_rule( unsigned rule )
{
    unsigned i;
    const YYTOKENTYPE YYFAR *tok;
    const char YYFAR *p;

    for( p = yytoknames[ yyplhstab[ rule ] ]; *p; ++p ) {
        putchar( *p );
    }
    putchar( ' ' );
    putchar( '<' );
    putchar( '-' );
    tok = &yyrhstoks[ yyrulebase[ rule ] ];
    for( i = yyplentab[ rule ]; i != 0; --i ) {
        putchar( ' ' );
        for( p = yytoknames[ *tok ]; *p; ++p ) {
            putchar( *p );
        }
        ++tok;
    }
    putchar( '\n' );
}

static void dump_state_stack(const char * label, PARSE_STACK * stack)
{
    static PARSE_STACK * last_stack = NULL;

    if(stack != last_stack)
    {
        printf("===============================================================================\n");
        printf("*** PARSE STACK CHANGE *** New: 0x%.08X Old: 0x%.08X\n", stack, last_stack);
        printf("===============================================================================\n");
        last_stack = stack;
    }    
    
    if(NULL == stack)
    {
        printf("dump_state_stack: NULL stack\n");
    }
    else
    {
        YYACTIONTYPE *  the_ssp = stack->ssp;
        YYACTIONTYPE *  the_sstack = stack->sstack;
        unsigned        index;
        
        printf("dump_state_stack \"%s\" (0x%.08X):\n", label, the_sstack);
        /*
        //  ensure we dump the top of stack (test &(ssp[1]))
        */
#if 0
        for(index = 0; &(the_sstack[index]) < &(the_ssp[1]); index++)
        {
              YYACTIONTYPE x = the_sstack[index];
              printf("  Index: %03d State: %04u\n", index, x);
        }
#else
        printf(" State(s):");
        for(index = 0; &(the_sstack[index]) < &(the_ssp[1]); index++)
        {
              YYACTIONTYPE x = the_sstack[index];
              printf(" %03u", x);
        }
        printf("\n");
#endif
    }
    fflush(stdout);
}

#endif

static void deleteStack( PARSE_STACK * );

static void parserSuicideHandler( void )
{
    while( currParseStack != NULL ) {
        deleteStack( currParseStack );
    }
}

static void parseInit(          // PARSER INITIALIZATION
    INITFINI* defn )            // - definition
{
    defn = defn;
    carveRESTART_PARSE = CarveCreate( sizeof( RESTART_PARSE ),
                                    BLOCK_RESTART_PARSE );
    carveVALUE_STACK = CarveCreate( STACK_DEPTH * sizeof( YYSTYPE ),
                                    BLOCK_VALUE_STACK );
    carveSTATE_STACK = CarveCreate( STACK_DEPTH * sizeof( YYACTIONTYPE ),
                                    BLOCK_STATE_STACK );
    carveLOCATION_STACK = CarveCreate( STACK_DEPTH * sizeof( TOKEN_LOCN ),
                                    BLOCK_LOCATION_STACK );
    currToken = Y_IMPOSSIBLE;
    parserSuicide.call_back = parserSuicideHandler;
    RegisterSuicideCallback( &parserSuicide );
    ExtraRptRegisterCtr( &lookup_lexical, "parser: lexical lookups" );
    ExtraRptRegisterCtr( &lookup_other, "parser: other lookups" );
    ExtraRptRegisterCtr( &found_type, "parser lookup: found type" );
    ExtraRptRegisterCtr( &found_id, "parser lookup: found id" );
    ExtraRptRegisterCtr( &found_template, "parser lookup: found template" );
    ExtraRptRegisterCtr( &found_namespace, "parser lookup: found namespace" );
}

static void parseFini(          // PARSER INITIALIZATION
    INITFINI* defn )            // - definition
{
    defn = defn;
    ParseFlush();
#ifndef NDEBUG
    CarveVerifyAllGone( carveRESTART_PARSE, "RESTART_PARSE" );
    CarveVerifyAllGone( carveVALUE_STACK, "VALUE_STACK" );
    CarveVerifyAllGone( carveSTATE_STACK, "STATE_STACK" );
    CarveVerifyAllGone( carveLOCATION_STACK, "LOCATION_STACK" );
#endif
    CarveDestroy( carveRESTART_PARSE );
    CarveDestroy( carveVALUE_STACK );
    CarveDestroy( carveSTATE_STACK );
    CarveDestroy( carveLOCATION_STACK );
}

INITDEFN( parser, parseInit, parseFini )

static void syncLocation( void )
{
    if( currToken == Y_IMPOSSIBLE ) {
        SrcFileGetTokenLocn( &yylocation );
    }
}

static void fatalParserError( void )
{
    CErr1( ERR_PARSER_DIED );
    CSuicide();
}

static boolean doFnbodyRewrite( void )
{
    switch( ScopeId( GetCurrScope() ) ) {
    case SCOPE_CLASS:
    case SCOPE_TEMPLATE_DECL:
        return( TRUE );
    }
    return( FALSE );
}

static PTREE setLocation( PTREE tree, TOKEN_LOCN *spot )
{
    tree->locn.src_file = spot->src_file;
    tree->locn.line = spot->line;
    tree->locn.column = spot->column;
    return( tree );
}

static PTREE makeUnary( CGOP op, PTREE t )
{
    t = PTreeUnary( op, t );
    setLocation( t, &yylocation );
    return( t );
}

static PTREE makeBinary( CGOP op, PTREE t1, PTREE t2 )
{
    t1 = PTreeBinary( op, t1, t2 );
    setLocation( t1, &yylocation );
    return( t1 );
}

static PTREE currBinary( CGOP op, PTREE t1, PTREE t2 )
{
    TOKEN_LOCN location;

    t1 = PTreeBinary( op, t1, t2 );
    SrcFileGetTokenLocn( &location );
    setLocation( t1, &location );
    return( t1 );
}

static PTREE makeId( void )
{
    PTREE t;

    t = PTreeId( SavedId );
    setLocation( t, &yylocation );
    return( t );
}

static lk_result lexCategory( SCOPE scope, PTREE id, lk_control control,
                              SYMBOL_NAME *psym_name )
{
    char *name;
    SYMBOL_NAME sym_name;
    SYMBOL sym;
    TYPE type;
    TYPE class_type;

    name = id->u.id.name;
    if( control & LK_LEXICAL ) {
        ExtraRptIncrementCtr( lookup_lexical );
        sym_name = ScopeYYLexical( scope, name );
    } else {
        ExtraRptIncrementCtr( lookup_other );
        sym_name = ScopeYYMember( scope, name );
    }
    if( psym_name != NULL ) {
        *psym_name = sym_name;
    }
    if( sym_name != NULL ) {
        if( sym_name->name_syms == NULL ) {
            sym = sym_name->name_type;
            switch( sym->id ) {
            case SC_CLASS_TEMPLATE:
                ExtraRptIncrementCtr( found_template );
                return( LK_TEMPLATE );

⌨️ 快捷键说明

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