parse.c

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

C
1,148
字号
            nrhs = 0;
            scanextra( 0, &precsym, &list_of_ambiguities );
            for(;;) {
                if( token != '{' && token != IDENTIFIER ) break;
                if( nrhs + 2 > maxrhs )
                    rhs = REALLOC( rhs, maxrhs *= 2, a_sym * );
                if( token == '{' ) {
                    i = bufused;
                    scanextra( bufused, &precsym, &list_of_ambiguities );
                    numacts++;
                    if( token == '{' || token == IDENTIFIER ) {
                        sprintf( buffer, "$pro%d", npro );
                        sym = addsym( buffer );
                        copyact( npro, sym, rhs, nrhs, nrhs );
                        addpro( sym, rhs, 0 );
                    } else {
                        copyact( npro, lhs, rhs, 0, nrhs );
                        action_defined = TRUE;
                        break;
                    }
                    memcpy( buf, &buf[i], bufused -= i );
                } else {
                    sym = addsym( buf );
                    if( value )
                        sym->token = value;
                    if( sym->token )
                        precsym = sym;
                    scanextra( 0, &precsym, &list_of_ambiguities );
                }
                rhs[nrhs++] = sym;
            }
            unit_production = FALSE;
            if( ! action_defined ) {
                if( nrhs > 0 ) {
                    /* { $$ = $1; } is default action */
                    if( defaultwarnflag ) {
                        char *type_lhs = type_name( lhs->type );
                        char *type_rhs = type_name( rhs[0]->type );
                        if( strcmp( type_rhs, type_lhs ) != 0 ) {
                            warn("default action would copy '%s <%s>' to '%s <%s>'\n",
                                rhs[0]->name, type_rhs, lhs->name, type_lhs );
                        }
                    }
                    if( nrhs == 1 ) {
                        unit_production = TRUE;
                    }
                } else {
                    if( sym_lineno == lineno && token == '|' ) {
                        warn( "unexpected epsilon reduction for '%s'?\n",
                            lhs->name );
                    }
                }
            }
            pro = addpro( lhs, rhs, nrhs );
            if( unit_production ) {
                pro->unit = TRUE;
            }
            if( precsym ) {
                pro->prec = precsym->prec;
            }
            if( list_of_ambiguities ) {
                for( am = list_of_ambiguities; am != NULL; am = am->next ) {
                    am->pro = pro;
                }
                pro->SR_conflicts = list_of_ambiguities;
            }
            if( token == ';' ) {
                scan( 0 );
            } else if( token != '|' ) {
                if( token == C_IDENTIFIER ) {
                    msg( "Missing ';'\n" );
                } else {
                    msg( "Incorrect syntax.\n" );
                }
            }
        } while( token == '|' );
    }
    free( rhs );

    not_token = FALSE;
    for( sym = symlist; sym; sym = sym->next ) {
        /* check for special symbols */
        if( sym == eofsym ) continue;
        if( denseflag ) {
            if( sym->token != 0 && sym->token < TOKEN_DENSE_BASE ) continue;
        } else {
            if( sym->token != 0 && sym->token < TOKEN_SPARSE_BASE ) continue;
        }
        if( !sym->pro && !sym->token ) {
            not_token = TRUE;
            warn( "%s not defined as '%%token'.\n", sym->name );
        }
    }
    if( not_token ) {
        msg( "cannot continue (because of %%token problems)\n" );
    }
    copyUniqueActions();
}

static void copyfile( void )
{
    do {
        fputc( ch, actout );
    } while( nextc() != EOF );
}

void tail( void )
{
    if( token == MARK )
        copyfile();
    else if( token != EOF )
        msg( "Expected end of file.\n" );
}

static void copycurl( void )
{
    do {
        while( ch != '%' && ch != EOF ) {
            fputc( ch, actout );
            nextc();
        }
    } while( nextc() != '}' && ch != EOF );
    nextc();
}

static char *checkAttrib( char *s, char **ptype, char *buff, int *errs,
                          a_sym *lhs, a_sym **rhs, unsigned base, unsigned n )
{
    char save;
    char *type;
    int err_count;
    int i;

    err_count = 0;
    ++s;
    if( *s == '<' ) {
        ++s;
        for( type = s; *s != '>'; ++s ) {
            if( *s == '\0' ) {
                ++err_count;
                msg( "Bad type specifier.\n" );
            }
        }
        save = *s;
        *s = '\0';
        type = strdup( type );
        *s = save;
        ++s;
    } else {
        type = NULL;
    }
    if( *s == '$' ) {
        strcpy( buff, "yyval" );
        if( type == NULL && lhs->type != NULL ) {
            type = strdup( lhs->type );
        }
        ++s;
    } else {
        i = n + 1;
        if( *s == '-' || isdigit( *s ) ) {
            i = strtol( s, &s, 10 );
        }
        if( i >= 0 && i > n ) {
            ++err_count;
            msg( "Invalid $ parameter (%d).\n", i );
        }
        i -= base + 1;
        sprintf( buff, "yyvp[%d]", i );
        if( type == NULL && i >= 0 && rhs[i]->type != NULL ) {
            type = strdup( rhs[i]->type );
        }
    }
    *ptype = type;
    *errs = err_count;
    return( s );
}

static a_pro *findPro( a_sym *lhs, unsigned pnum )
{
    a_pro *pro;

    for( pro = lhs->pro; pro != NULL; pro = pro->next ) {
        if( pro->pidx == pnum ) {
            return( pro );
        }
    }
    return( NULL );
}

static void copyUniqueActions( void )
{
    a_pro *pro;
    char *s;
    uniq_case *c;
    uniq_case *nc;
    rule_case *r;
    rule_case *nr;
    an_item *first_item;
    an_item *item;

    for( c = caseActions; c != NULL; c = nc ) {
        nc = c->next;
        for( r = c->rules; r != NULL; r = nr ) {
            nr = r->next;
            fprintf( actout, "case %d:\n", r->pnum );
            pro = findPro( r->lhs, r->pnum );
            fprintf( actout, "/* %s <-", pro->sym->name );
            first_item = pro->item;
            for( item = first_item; item->p.sym; ++item ) {
                fprintf( actout, " %s", item->p.sym->name );
            }
            fprintf( actout, " */\n" );
            free( r );
        }
        for( s = c->action; *s != '\0'; ++s ) {
            fputc( *s, actout );
        }
        fprintf( actout, "\nbreak;\n" );
        free( c->action );
        free( c );
    }
}

static void addRuleToUniqueCase( uniq_case *p, int pnum, a_sym *lhs )
{
    rule_case *r;

    r = MALLOC(1,rule_case);
    r->lhs = lhs;
    r->pnum = pnum;
    r->next = p->rules;
    p->rules = r;
}

static void insertUniqueAction( int pnum, char *buf, a_sym *lhs )
{
    uniq_case **p;
    uniq_case *c;
    uniq_case *n;

    p = &caseActions;
    for( c = *p; c != NULL; c = c->next ) {
        if( strcmp( c->action, buf ) == 0 ) {
            ++actionsCombined;
            addRuleToUniqueCase( c, pnum, lhs );
            /* promote to front */
            *p = c->next;
            c->next = caseActions;
            caseActions = c;
            free( buf );
            return;
        }
        p = &(c->next);
    }
    n = MALLOC(1,uniq_case);
    n->action = buf;
    n->rules = NULL;
    n->next = *p;
    *p = n;
    addRuleToUniqueCase( n, pnum, lhs );
}

static char *strpcpy( char *d, char *s )
{
    while( (*d = *s++) ) {
        ++d;
    }
    return( d );
}

static void copyact( int pnum, a_sym *lhs, a_sym **rhs, unsigned base, unsigned n )
{
    char *b;
    char *p;
    char *s;
    char *type;
    unsigned i;
    int errs;
    int total_errs;
    size_t total_len;
    char buff[80];

    if( ! lineflag ) {
        /* we don't need line numbers to correspond to the grammar */
        total_errs = 0;
        total_len = strlen( buf ) + 1;
        for( s = buf; *s != '\0'; ) {
            if( *s == '$' ) {
                s = checkAttrib( s, &type, buff, &errs, lhs, rhs, base, n );
                total_len += strlen( buff );
                if( type != NULL ) {
                    total_len += strlen( type ) + 1;
                }
                free( type );
                total_errs += errs;
            } else {
                ++s;
            }
        }
        if( total_errs == 0 ) {
            b = MALLOC(total_len,char);
            p = b;
            for( s = buf; *s != '\0'; ) {
                if( *s == '$' ) {
                    s = checkAttrib( s, &type, buff, &errs, lhs, rhs, base, n );
                    p = strpcpy( p, buff );
                    if( type != NULL ) {
                        *p++ = '.';
                        p = strpcpy( p, type );
                        free( type );
                    }
                } else {
                    *p++ = *s++;
                }
            }
            *p = '\0';
            insertUniqueAction( pnum, b, lhs );
        }
        return;
    }
    fprintf( actout, "case %d:\n", pnum );
    fprintf( actout, "/* %s <-", lhs->name );
    for( i = 0; i < n; ++i ) {
        fprintf( actout, " %s", rhs[i]->name );
    }
    fprintf( actout, " */\n" );
    lineinfo();
    for( s = buf; *s != '\0'; ) {
        if( *s == '$' ) {
            s = checkAttrib( s, &type, buff, &errs, lhs, rhs, base, n );
            fprintf( actout, "%s", buff );
            if( type != NULL ) {
                fprintf( actout, ".%s", type );
                free( type );
            }
        } else {
            fputc( *s++, actout );
        }
    }
    fprintf( actout, "\nbreak;\n" );
}

static void copybal( void )
{
    int depth;

    depth = 1;
    do {
        addbuf( ch );
        nextc();
        if( lastc() == '/' ) {
            if( ch == '*' ) {
                /* copy a C style comment */
                for(;;) {
                    addbuf( ch );
                    nextc();
                    if( ch == EOF ) break;
                    if( ch == '/' && lastc() == '*' ) {
                        addbuf( ch );
                        nextc();
                        break;
                    }
                }
            } else if( ch == '/' ) {
                /* copy a C++ style comment */
                for(;;) {
                    addbuf( ch );
                    nextc();
                    if( ch == EOF ) break;
                    if( ch == '\n' ) {
                        addbuf( ch );
                        nextc();
                        break;
                    }
                }
            }
        }
        if( ch == '"' ) {
            /* copy a string */
            addbuf( ch );
            for(;;) {
                nextc();
                if( ch == EOF ) break;

⌨️ 快捷键说明

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