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 + -
显示快捷键?