home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
OS2-YACC.ZIP
/
PREP2.C
< prev
next >
Wrap
Text File
|
1986-02-06
|
9KB
|
469 lines
/*
HEADER: CUG nnn.nn;
TITLE: PREP - Preprocessor for YACC
VERSION: 1.0 for IBM-PC
DATE: JAN 28, 1985
DESCRIPTION: Preprocessor for YACC Programs
KEYWORDS: Preprocessor IBM YACC LEX UNIX
SYSTEM: IBM-PC and Compatiables
FILENAME: PREP2.C
WARNINGS: This program is not for the casual user. It will
be useful primarily to expert developers.
CRC: N/A
SEE-ALSO: LEX and YACC
AUTHORS: Scott Guthery 11100 leafwood lane Austin, TX 78750
COMPILERS: DESMET-C
REFERENCES: UNIX Systems Manuals
*/
#include <stdio.h>
#include "prep.h"
/*
*
* J van Katwijk
* Delft University of Technology,
* Department of Mathematics,
* 132 Julianalaan
* Delft, The Netherlands
*
* See for a functional description:
*
* SIGPLAN NOTICES
* October 1983, 18 (10) pp 12 .. 16
*/
/*
* scanning/copying routines for YACC preprocessor
*
* j van katwijk
*
*/
static char c;
static int is_digit (x)
register char x;
{
return '0' <= x && x <= '9';
}
static int is_letter(x)
register char x;
{
return ('A' <= x && x <= 'Z') || ('a' <= x && x <= 'z');
}
int is_namelem (x)
register int x;
{
return (islower(x) ||
isupper(x) ||
c == '_' ||
c == '.' ||
c == '$' );
}
int gettok ()
{
register int i, base;
static int peekline;
register int match, reserve;
/* :
*/
begin:
reserve = 0;
lineno += peekline;
peekline = 0;
c = unix_getc (finput);
while (0 <= c && c <= ' ')
{ if (c == '\n')
lineno++;
c = unix_getc (finput);
}
if (c == '/') /* go for comment */
{ lineno += skipcom ();
goto begin;
}
switch (c)
{
case -1: /* EOF */
return ENDFILE;
case ':':
return COLON;
case ';':
return SEMI;
case '|':
return BAR;
case '{':
uungetc (c, finput);
return (EQ_SYMB);
/* action .... */
case '<': /* only for the sake of YACC */
i = 0;
while ( (c = unix_getc (finput)) != '>' && c >= 0 && c != '\n')
{ tokname [i] = c;
if (++i >= NAMESIZE) --i;
}
if (c!= '>')
error (FATAL, "unterminated <...> clause");
tokname [i] = '\0';
return (IDENT);
case ',':
return COMMA;
case '^':
return OUTPUT;
case '=':
return EQ_SYMB;
case '(':
return LPAR;
case ')':
return RPAR;
case '"':
case '\'':
match = c;
tokname [0] = ' ';
i = 1;
for (;;)
{ c = unix_getc (finput);
if (c == '\n' || c == EOF)
error (FATAL, "illegal or missing %c", match);
if (c == '\\')
{ c = unix_getc (finput);
tokname [i] = '\\';
if (++i >= NAMESIZE) --i;
}
else
if (c == match)
break;
tokname [i] = c;
if (++i >= NAMESIZE) --i;
}
break;
case '%':
case '\\':
switch (c = unix_getc (finput))
{
case '0': return TERM;
case '<': return LEFT;
case '2': return (BINARY);
case '>': return (RIGHT);
case '%':
case '\\': return (MARK);
case '=': return (PREC);
case '{': return (LCURL);
default: reserve = 1;
}
/* bah, johnson falls through, we follow here:
*/
default:
if (isdigit(c))
{ i = 0;
while (isdigit(c))
{ tokname [i] = c;
if (++i >= NAMESIZE) --i;
c = unix_getc (finput);
}
uungetc (c, finput);
return (NUMBER);
}
else
if (is_namelem (c))
{ i = 0;
while (is_namelem (c) || is_digit (c))
{ tokname [i] = c;
if (reserve && isupper(c))
tokname [i] += 'a' - 'A';
if (++i >= NAMESIZE) --i;
c = unix_getc (finput);
}
}
else
return c;
uungetc (c, finput);
}
/* look for reserved words */
tokname [i] = '\0';
if (reserve)
{
if (!strcmp (tokname, "term")) return TERM;
if (!strcmp (tokname, "token")) return TERM;
if (!strcmp (tokname, "left")) return LEFT;
if (!strcmp (tokname, "nonassoc")) return BINARY;
if (!strcmp (tokname, "binary")) return BINARY;
if (!strcmp (tokname, "right")) return RIGHT;
if (!strcmp (tokname, "prec")) return RIGHT;
if (!strcmp (tokname, "start")) return START;
if (!strcmp (tokname, "type")) return TYPE;
if (!strcmp (tokname, "union")) return UNION;
if (!strcmp (tokname, "attributes")) return ATTR_DEF;
if (!strcmp (tokname, "attribute")) return ATTR_DEF;
error (FATAL, "non recognized keyword %s", tokname);
}
return (IDENT);
}
/*
* copy the union
*
*/
cpyunion ()
{
int level, c;
fprintf (foutput, "\n# line %d \"%s\"\n", lineno, infile);
fprintf (foutput, "%%union");
level = 0;
for (;;)
{ if ((c = unix_getc (finput)) <0 )
error (FATAL, "EOF when parsing %%union");
fprintf (foutput, "%c", c);
switch (c)
{
case '\n':
++lineno; break;
case '{':
++level;
break;
case '}':
level--;
if (level == 0)
return;
}
}
}
cpycode () /* copies code between { and } */
{
register int c;
c = unix_getc (finput);
if (c == '\n')
{ c = unix_getc (finput);
lineno ++;
}
fprintf (foutput, "\\{");
while (c >= 0)
{
if (c == '\\')
if ( (c = unix_getc (finput)) == '}')
{ fprintf (foutput, "\\}");
return;
}
else
fprintf (foutput, "\\");
if (c == '%')
if ( (c = unix_getc (finput)) == '}')
{ fprintf (foutput, "%}");
return;
}
else
fprintf (foutput, "%");
fprintf (foutput, "%c", c);
if (c == '\n') lineno ++;
c = unix_getc (finput);
}
error (FATAL, "error before %%}");
}
skipcom () /* guess what */
{
register int c;
register int i = 0; /* number of lines skipped */
if (unix_getc (finput) != '*')
error (FATAL, "illegal comment");
c = unix_getc (finput);
while (c != EOF)
{
while (c == '*')
if ( (c = unix_getc (finput)) == '/') return i;
if (c == '\n') i++;
c = unix_getc (finput);
}
error (FATAL, "error EOF within comment");
}
cpyact () /* copy C action to closing ; or } */
{
int brac, c, match, j, s, tok;
pref_stackadjust ();
brac = 0;
loop:
c = unix_getc (finput);
swt:
switch (c)
{
case ';':
if (brac == 0)
{ post_adjuststack ();
fprintf (foutput, "%c", c);
return;
}
goto lcopy;
case '{':
brac++;
goto lcopy;
case '$':
s = 1;
tok = -1;
c = unix_getc (finput);
if (c == '<') /* type description */
{ uungetc (c, finput);
if (gettok () != IDENT)
error (FATAL, "bad syntax on $<..> clause");
fprintf (foutput, "<%s>", tokname);
c = unix_getc (finput);
}
if (c == '$')
{ fprintf (foutput, "$$");
goto loop;
}
if (c == '-')
{ s = -s;
c = unix_getc (finput);
}
if (isdigit(c))
{ j = 0;
while (isdigit(c))
{ j = j * 10 + c - '0';
c = unix_getc (finput);
}
j = j * s;
fprintf (foutput, "$%d", j);
goto swt;
}
if (is_letter (c))
{ uungetc (c, finput);
tok = gettok ();
if (tok != IDENT)
error (FATAL, "illegal $construct");
fprintf (foutput, "%s", address_of(tokname));
goto loop;
}
fprintf (foutput, "$");
if (s < 0)
fprintf (foutput, "-");
goto swt;
case '}':
if (--brac > 0)
goto lcopy;
post_adjuststack ();
fprintf (foutput, "%c", c);
return;
case '/':
/* look for comment */
fprintf (foutput, "%c", c);
c = unix_getc (finput);
if (c != '*') goto swt;
while (c != EOF)
{
while (c == '*')
{
fprintf (foutput, "%c", c);
if ( (c = unix_getc (finput)) == '/')
goto lcopy;
}
fprintf (foutput, "%c", c);
if (c == '\n') lineno++;
c = unix_getc (finput);
}
error (FATAL, "EOF within comment");
case '\'':
match = '\'';
goto string;
case '"':
match = '"';
string:
fprintf (foutput, "%c", c);
while ( (c = unix_getc (finput)) != EOF)
{
if (c == '\\')
{
fprintf (foutput, "%c", c);
c = unix_getc (finput);
if (c == '\n') lineno ++;
}
else
if (c == match) goto lcopy;
else
if (c == '\n')
error (FATAL, "newline in string or char const");
fprintf (foutput, "%c", c);
}
error (FATAL, "EOF in string or character constant");
case -1: /* EOF */
error ("action does not terminate");
case '\n':
lineno++;
goto lcopy;
}
lcopy:
fprintf (foutput, "%c", c);
goto loop;
}