ytabprty.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 425 行
C
425 行
/****************************************************************************
*
* 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 <stdlib.h>
#include <string.h>
#include <ctype.h>
char *prettyToken[1024] = {
"<end-of-file>",
"<impossible>",
"<error>",
};
unsigned max = 2;
char literal[1024];
unsigned value;
char buff[1024];
char *skipWhite( char *p ) {
while( *p && isspace( *p ) ) {
++p;
}
return( p );
}
char *skipText( char *p, char *text ) {
unsigned len = strlen( text );
if( memcmp( p, text, len ) == 0 ) {
p += len;
}
return( p );
}
char *skipLiteral( char *p ) {
char *q = literal;
while( *p && ! isspace( *p ) ) {
*q = *p;
++q;
++p;
}
*q = '\0';
return( p );
}
char *skipValue( char *p ) {
value = 0;
for(;;) {
int c = *p;
switch( c ) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value <<= 4;
value += c - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value <<= 4;
value += ( c - 'a' ) + 10;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
value <<= 4;
value += ( c - 'A' ) + 10;
break;
default:
return( p );
}
++p;
}
return( p );
}
int parseLine( void ) {
char *p = buff;
p = skipWhite( p );
if( *p != '#' ) {
return( 0 );
}
++p;
p = skipText( p, "define" );
p = skipWhite( p );
p = skipLiteral( p );
p = skipWhite( p );
if( p[0] != '0' || p[1] != 'x' ) {
return( 0 );
}
p += 2;
p = skipValue( p );
p = skipWhite( p );
if( *p != '\0' ) {
return( 0 );
}
return( 1 );
}
enum {
C_UPPER = 0x01,
C_LOWER = 0x02,
C_UNDERSCORE= 0x04,
C_UNKNOWN = 0x08,
C_NULL = 0x00
};
int category( void ) {
char *p;
int c;
c = C_NULL;
for( p = literal; *p; ++p ) {
if( isupper( *p ) ) {
c |= C_UPPER;
} else if( islower( *p ) ) {
c |= C_LOWER;
} else if( *p == '_' ) {
c |= C_UNDERSCORE;
} else {
c |= C_UNKNOWN;
}
}
return( c );
}
char *whatChar( char *p, char *w ) {
char *q;
q = skipText( p, "AND" );
if( q != p ) {
*w = '&';
return( q );
}
q = skipText( p, "EQUAL" );
if( q != p ) {
*w = '=';
return( q );
}
q = skipText( p, "COLON" );
if( q != p ) {
*w = ':';
return( q );
}
q = skipText( p, "COMMA" );
if( q != p ) {
*w = ',';
return( q );
}
q = skipText( p, "DIVIDE" );
if( q != p ) {
*w = '/';
return( q );
}
q = skipText( p, "DOT" );
if( q != p ) {
*w = '.';
return( q );
}
q = skipText( p, "EXCLAMATION" );
if( q != p ) {
*w = '!';
return( q );
}
q = skipText( p, "GT" );
if( q != p ) {
*w = '>';
return( q );
}
q = skipText( p, "LT" );
if( q != p ) {
*w = '<';
return( q );
}
q = skipText( p, "LBRACE" );
if( q != p ) {
*w = '{';
return( q );
}
q = skipText( p, "LPAREN" );
if( q != p ) {
*w = '(';
return( q );
}
q = skipText( p, "LSQUARE" );
if( q != p ) {
*w = '[';
return( q );
}
q = skipText( p, "RBRACE" );
if( q != p ) {
*w = '}';
return( q );
}
q = skipText( p, "RPAREN" );
if( q != p ) {
*w = ')';
return( q );
}
q = skipText( p, "RSQUARE" );
if( q != p ) {
*w = ']';
return( q );
}
q = skipText( p, "MINUS" );
if( q != p ) {
*w = '-';
return( q );
}
q = skipText( p, "OR" );
if( q != p ) {
*w = '|';
return( q );
}
q = skipText( p, "PERCENT" );
if( q != p ) {
*w = '%';
return( q );
}
q = skipText( p, "PLUS" );
if( q != p ) {
*w = '+';
return( q );
}
q = skipText( p, "QUESTION" );
if( q != p ) {
*w = '?';
return( q );
}
q = skipText( p, "SEMICOLON" );
if( q != p ) {
*w = ';';
return( q );
}
q = skipText( p, "TILDE" );
if( q != p ) {
*w = '~';
return( q );
}
q = skipText( p, "TIMES" );
if( q != p ) {
*w = '*';
return( q );
}
q = skipText( p, "XOR" );
if( q != p ) {
*w = '^';
return( q );
}
*w = '\0';
return( p );
}
void makeDelimiter() {
char *p = literal;
char *q;
char *r = buff;
char w;
for(;;) {
if( *p == '\0' ) break;
q = whatChar( p, &w );
if( w == '\0' ) {
printf( "could not translate '%s' into a character\n", p );
break;
}
*r++ = w;
p = q;
if( *p == '_' ) {
++p;
}
}
*r = '\0';
}
void makeLiteral() {
char *p = literal;
char *q = buff;
char prev = *p;
*q++ = '<';
while( *p ) {
if( isupper( *p ) ) {
if( islower( prev ) ) {
*q++ = '-';
}
*q++ = tolower( *p );
} else {
*q++ = *p;
}
prev = *p;
++p;
}
*q++ = '>';
*q = '\0';
}
char *makePretty( void ) {
int c;
if( literal[0] == 'Y' && literal[1] == '_' ) {
strcpy( &literal[0], &literal[2] );
}
c = category();
if( c & C_UNKNOWN ) {
printf( "literal '%s' contains an unknown character\n", literal );
return( NULL );
}
switch( c ) {
case C_UPPER | C_UNDERSCORE: // delimiter
case C_UPPER:
makeDelimiter();
break;
case C_LOWER: // keyword
strcpy( buff, literal );
break;
case C_UPPER | C_LOWER: // literal
makeLiteral();
break;
default:
printf( "literal '%s' contains unknown combination of chars\n", literal );
return( NULL );
}
return( buff );
}
int main( int argc, char **argv )
{
int errors;
FILE *fi, *fo;
char *check;
int i;
if( argc != 3 ) {
puts( "usage: ytabprty <ytab-gh> <ytab-pick-output-gh>" );
return( EXIT_FAILURE );
}
fi = fopen( argv[1], "r" );
if( !fi ) {
printf( "cannot open '%s' for input\n", argv[1] );
return( EXIT_FAILURE );
}
fo = fopen( argv[2], "w" );
if( !fo ) {
printf( "cannot open '%s' for output\n", argv[2] );
return( EXIT_FAILURE );
}
errors = 0;
for(;;) {
check = fgets( buff, sizeof( buff ), fi );
if( check == NULL ) break;
if( parseLine() ) {
if( value > max ) {
max = value;
}
prettyToken[ value ] = strdup( makePretty() );
if( prettyToken[ value ] == NULL ) {
printf( "couldn't produce pretty representation of '%s'\n", literal );
++errors;
}
}
}
for( i = 0; i <= max; ++i ) {
if( prettyToken[i] == NULL ) {
printf( "token value %u has no string\n", i );
++errors;
}
}
if( errors ) {
return( EXIT_FAILURE );
}
fprintf( fo, "char const * const yytokenname[] = {\n" );
for( i = 0; i <= max; ++i ) {
fprintf( fo, "\"%s\",\n", prettyToken[ i ] );
}
fprintf( fo, "};\n" );
fclose( fi );
fclose( fo );
return( EXIT_SUCCESS );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?