parse.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,148 行 · 第 1/3 页
C
1,148 行
if( ch == '\n' ) {
msg( "string literal was not terminated by \" before end of line\n" );
break;
}
if( ch == '\\' ) {
addbuf( ch );
nextc();
addbuf( ch );
} else {
if( ch == '"' ) break;
addbuf( ch );
}
}
}
if( ch == '\'' ) {
/* copy a character constant */
addbuf( ch );
for(;;) {
nextc();
if( ch == EOF ) break;
if( ch == '\n' ) {
msg( "character literal was not terminated by \" before end of line\n" );
break;
}
if( ch == '\\' ) {
addbuf( ch );
nextc();
addbuf( ch );
} else {
if( ch == '\'' ) break;
addbuf( ch );
}
}
}
if( ch == '{' ) {
++depth;
} else if( ch == '}' ) {
--depth;
}
} while( depth > 0 && ch != EOF );
addbuf( ch );
addbuf( '\0' );
nextc();
}
static void lineinfo( void )
{
if( lineflag )
fprintf( actout, "\n#line %d \"%s\"\n", lineno, srcname );
}
static void addstr( char *p ) {
while( *p ) {
addbuf( *p );
++p;
}
}
typedef struct xlat_entry {
int c;
char *x;
} xlat_entry;
static xlat_entry xlat[] = {
{ '~', "TILDE" },
{ '`', "BACKQUOTE" },
{ '!', "EXCLAMATION" },
{ '@', "AT" },
{ '#', "SHARP" },
{ '$', "DOLLAR" },
{ '%', "PERCENT" },
{ '^', "XOR" },
{ '&', "AND" },
{ '*', "TIMES" },
{ '(', "LPAREN" },
{ ')', "RPAREN" },
{ '-', "MINUS" },
{ '+', "PLUS" },
{ '=', "EQUAL" },
{ '[', "LSQUARE" },
{ ']', "RSQUARE" },
{ '{', "LBRACE" },
{ '}', "RBRACE" },
{ '\\', "BACKSLASH" },
{ '|', "OR" },
{ ':', "COLON" },
{ ';', "SEMICOLON" },
{ '\'', "QUOTE" },
{ '"', "DQUOTE" },
{ '<', "LT" },
{ '>', "GT" },
{ '.', "DOT" },
{ ',', "COMMA" },
{ '/', "DIVIDE" },
{ '?', "QUESTION" },
{ '\0', NULL }
};
static int xlat_char( int special, int c ) {
xlat_entry *t;
auto char buff[16];
if( isalpha( c ) || isdigit( c ) || c == '_' ) {
if( special ) {
addbuf( '_' );
}
addbuf( c );
return( FALSE );
}
/* NYI: add %translate 'c' XXXX in case user doesn't like our name */
addbuf( '_' );
for( t = xlat; t->x != NULL; ++t ) {
if( t->c == c ) {
addstr( t->x );
return( TRUE );
}
}
warn( "'x' token contains unknown character '%c' (\\x%x)\n", c, c );
addbuf( 'X' );
sprintf( buff, "%x", c );
addstr( buff );
return( TRUE );
}
static void xlat_token( void )
{
int special;
addbuf( 'Y' );
special = TRUE;
for(;;) {
nextc();
if( ch == EOF || ch == '\n' ) {
msg( "invalid 'x' token" );
break;
}
if( ch == '\'' ) break;
if( ch == '\\' ) {
special = xlat_char( special, ch );
nextc();
}
special = xlat_char( special, ch );
}
addbuf( '\0' );
value = 0;
token = IDENTIFIER;
}
static int scan( unsigned used )
{
bufused = used;
eatcrud();
if( isalpha( ch ) ) {
for(;;) {
addbuf( ch );
nextc();
if( isalpha( ch ) ) continue;
if( isdigit( ch ) ) continue;
if( ch == '_' ) continue;
if( ch == '.' ) continue;
if( ch == '-' ) continue;
break;
}
addbuf( '\0' );
if( eatcrud() == ':' ) {
nextc();
token = C_IDENTIFIER;
} else {
token = IDENTIFIER;
}
value = 0;
} else if( isdigit( ch ) || ch == '-' ) {
do {
addbuf( ch );
} while( isdigit( nextc() ) );
addbuf( '\0' );
token = NUMBER;
value = atoi( buf );
} else {
switch( ch ) {
case '\'':
if( denseflag && ! translateflag ) {
msg( "cannot use '+' style of tokens with the dense option\n" );
}
if( ! translateflag ) {
addbuf( '\'' );
nextc();
addbuf( ch );
if( ch == '\\' ) {
nextc();
addbuf( ch );
switch( ch ) {
case 'n': ch = '\n'; break;
case 'r': ch = '\r'; break;
case 't': ch = '\t'; break;
case 'b': ch = '\b'; break;
case 'f': ch = '\f'; break;
case '\\': ch = '\\'; break;
case '\'': ch = '\''; break;
}
}
addbuf( '\'' );
value = ch;
token = IDENTIFIER;
need( "'" );
} else {
xlat_token();
}
break;
case '{':
token = ch;
copybal();
break;
case '<': case '>': case '|': case ';': case ',':
case EOF:
token = ch;
break;
case '%':
switch( nextc() ) {
case '%':
token = MARK;
break;
case '{':
token = LCURL;
break;
case '}':
token = RCURL;
break;
case 'a':
need( "mbig" );
token = AMBIG;
break;
case 'k':
need( "eyword_id" );
token = KEYWORD_ID;
break;
case 'l':
need( "eft" );
token = LEFT;
value = L_ASSOC;
break;
case 'n':
need( "onassoc" );
token = NONASSOC;
value = NON_ASSOC;
break;
case 'p':
need( "rec" );
token = PREC;
break;
case 'r':
need( "ight" );
token = RIGHT;
value = R_ASSOC;
break;
case 's':
need( "tart" );
token = START;
break;
case 't':
nextc();
if( ch == 'o' ) {
need( "ken" );
token = TOKEN;
} else if( ch == 'y' ) {
need( "pe" );
token = TYPE;
} else {
msg( "Expecting %%token or %%type.\n" );
}
break;
case 'u':
need( "nion" );
token = UNION;
break;
default:
msg( "Unrecognized %% token.\n" );
}
break;
default:
msg( "Bad token.\n" );
}
addbuf( '\0' );
nextc();
}
return( token );
}
static void need( char *pat )
{
while( *pat ) {
if( nextc() != *pat++ ) {
msg( "Expected '%c'\n", pat[-1] );
}
}
}
static int eatcrud( void )
{
int prev;
for(;;) {
switch( ch ) {
case ' ':
case '\t':
case '\r':
case '\n':
case '\f':
nextc();
break;
case '/':
if( nextc() != '*' ) {
if( ch == '\n' ) {
--lineno;
}
ungetc( ch, yaccin );
ch = '/';
return( ch );
}
prev = '\0';
for(;;) {
if( nextc() == '/' && prev == '*' ) {
break;
}
if( ch == EOF ) {
return( EOF );
}
prev = ch;
}
nextc();
break;
default:
return( ch );
}
}
}
static int nextc( void )
{
if( (ch = fgetc( yaccin )) == '\r' ) {
ch = fgetc( yaccin );
}
if( ch == '\n' ) {
++lineno;
}
return( ch );
}
static int lastc( void )
{
if( bufused > 1 ) {
return( buf[bufused-1] );
}
return( '\0' );
}
static void addbuf( int ch )
{
if( bufused == bufmax ) {
bufmax += BUF_INCR;
if( buf )
buf = REALLOC( buf, bufmax, char );
else
buf = MALLOC( bufmax, char );
}
buf[bufused++] = ch;
}
static char *dupbuf( void )
{
char *str;
str = MALLOC( bufused, char );
memcpy( str, buf, bufused );
bufused = 0;
return( str );
}
void parsestats( void )
{
dumpstatistic( "actions combined", actionsCombined );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?