home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume6
/
yaccref2
< prev
next >
Wrap
Text File
|
1986-11-30
|
13KB
|
653 lines
/* Written 10:09 pm Jul 13, 1986 by cathy@comp.lancs.ac.uk in mirror:net.sources */
( Apologies for sending the wrong version here and to mod.sources a
few days ago. Correct version is listed below. All flames to above
address. )
The following source forms the xref program for syntactically correct
Yacc files and runs on UN*X 4.2. All tokens and non-terminals in the grammar
are located, together with a list of the line numbers at which they occur. The
output is a numbered listing of the Yacc grammar upto the second '%%' or EOF,
followed by an alphabetical listing of the xref table.
Should a syntax error occur before normal termination, the grammar
listing ends and as much of the table as has been constructed is printed. All
comments /* .. */ , %{ .. %} and actions { .. } are ignored, although they
appear in the listing. Overflow in any field of the data structure holding the
table information is reported as it occurs and execution terminates without
printing any xref information.
Table data is stored in "table[]", which holds MAXINTS terminal/non-
terminal names, each of length <= MAXCHARS. A total of MAXDEFS defining (rhs of
rule) occurances can be held, and a total of MAXOCCS lhs occurances. Each ident-
ifier which may be the start token has the message held in "start_maybe[]"
printed - likewise all possible tokens are accompanied by "token_maybe[]". All
defining occurances are printed following "declared_at_mark[]", and all
other occurances following "occurs_at_mark[]".
An example of the output is given below.
1 : %{
2 :
3 :
4 : %}
5 :
6 : /*******************************************************\
7 : * *
8 : * Trivial Yacc grammar. *
9 : * ~~~~~~~~~~~~~~~~~~~~~ *
10 : * *
11 : \*******************************************************/
12 :
13 : %token IDENTIFIER CHARACTER NUMBER
14 :
15 : %start start
16 :
17 : %%
18 :
19 : start
20 : : begin middle end
21 : ;
22 :
23 : begin
24 : : BEGIN
25 : ;
26 :
27 : middle
28 : :
29 : ;
30 :
31 : begin
32 : :
33 : | ALT_BEGIN
34 : ;
35 :
36 :
' ALT_BEGIN ' -
is not declared - token?? 1 occurances at lines , 33
' BEGIN ' -
is not declared - token?? 1 occurances at lines , 24
' begin ' -
*23 , *31 1 occurances at lines , 20
' end ' -
is not declared - token?? 1 occurances at lines , 20
' middle ' -
*27 1 occurances at lines , 20
' start ' -
*19 , never occurs on rhs of rule - start rule?
End of X-ref
~~~~~~~~~~~~
The text below should be stored in the file
pack.out
and can be converted from the single file to the three files
xref-grammar
xref-regular_expr
xref-line.h
by issuing the command
sh pack.out
Issue the commands
lex xref-regular_expr
yacc -vd xref-grammar
cc y.tab.c -o xref
to produce an executable version and use as any UN*X command.
<---------------------------------- Cut here ---------------------------------->
#!/bin/sh
echo 'Start of pack.out, part 01 of 01:'
echo 'x - xref-grammar'
sed 's/^X//' > xref-grammar << '/'
X%{
X
X# include <ctype.h>
X# include <stdio.h>
X
X
X /***************************************************************\
X * *
X * Error messages. *
X * *
X \***************************************************************/
X
Xchar *charroom = " MAXCHARS TOO SMALL - no room to store ";
Xchar *occroom = " MAXOCCS TOO SMALL - no room to store occurance of ";
Xchar *defroom = " MAXDEFS TOO SMALL - no room to store definition of ";
Xchar *idroom = " MAXIDENTS TOO SMALL - no space in table for new identifier ";
X
X%}
X
X
X /*******************************************************\
X * *
X * X_reference program for YACC files *
X * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
X * *
X * Cathy Taylor, *
X * c/o Department of Computing, *
X * University of Lancaster, *
X * Bailrigg, Lancaster, England. *
X * *
X * Date : Mon Jul 14 01:24:34 BST 1986 *
X * *
X \*******************************************************/
X
X
X /***********************************************\
X * *
X * Yacc Input Syntax *
X * ~~~~~~~~~~~~~~~~~ *
X * *
X * Adapted from the document *
X * 'YACC - Yet Another Compiler Compiler' *
X * by *
X * S. C. Johnson *
X * *
X * Date: Tue Jul 1 02:40:18 BST 1986 *
X * *
X \***********************************************/
X
X
X%token IDENTIFIER CHARACTER NUMBER
X%token LEFT RIGHT NONASSOC TOKEN PREC TYPE START UNION
X%token PER PERCURL ACT
X%token COLON SEMICOLON COMMA OR LESS GREATER
X
X%start spec
X
X%%
X
Xspec
X : defs PER rules tail
X {
X printf("\n\n");
X yyclearin;
X return(0);
X }
X ;
X
Xtail
X : /* empty */
X | PER
X ;
X
Xdefs
X : /* empty */
X | def_bk
X ;
X
Xdef_bk
X : def
X | def_bk def
X ;
X
Xdef
X : START IDENTIFIER
X | UNION
X | PERCURL
X | rword tag nlist
X ;
X
Xrword
X : TOKEN
X | LEFT
X | RIGHT
X | NONASSOC
X | TYPE
X ;
X
Xtag
X : /* empty */
X | LESS IDENTIFIER GREATER
X ;
X
Xnlist
X : nmno
X | nlist opt_comma nmno
X ;
X
Xopt_comma
X : /* empty */
X | COMMA
X ;
X
Xnmno
X : IDENTIFIER opt_num
X ;
X
Xopt_num
X : /* empty */
X | NUMBER
X ;
Xrules
X : rule
X | rules rule
X ;
X
Xrule
X : IDENTIFIER
X {
X yyaction(ON_C_IDENT,line);
X }
X COLON body SEMICOLON
X ;
X
Xbody
X : body_block
X | body OR body_block
X ;
X
Xbody_block
X : /* empty */
X | body_block body_entity
X ;
X
Xbody_entity
X : opt_prec id_ent
X | ACT
X ;
X
Xid_ent
X : IDENTIFIER
X {
X yyaction(ON_IDENT,line);
X }
X | CHARACTER
X ;
X
Xopt_prec
X : /* empty */
X | PREC
X ;
X
X
X%%
X
X# include <stdio.h>
X# include "lex.yy.c"
X# include "sto.h"
X
X#define ON_C_IDENT 000
X#define ON_IDENT 001
X
X#define MAXIDENTS 200
X#define MAXCHARS 50
X#define MAXDEFS 5
X#define MAXOCCS 80
X
Xstruct IREC {
X char symbol[MAXCHARS];
X int description[MAXDEFS];
X int next_d;
X int occurance[MAXOCCS];
X int next_o;
X } table[MAXIDENTS];
X
X
Xyyaction (action,ln)
Xint action;
Xint ln;
X{
X int id;
X
X id = 0;
X while ( strcmp(table[id].symbol,yytext) != 0 && strcmp(table[id].symbol,"") != 0 )
X {
X if (id== MAXIDENTS)
X {
X yyerror(strcat(idroom,yytext),ln);
X exit(3);
X }
X id++;
X }
X
X if ( strcmp(table[id].symbol, yytext) != 0 )
X {
X
X /*******************************************************\
X * *
X * New non-terminal to be stored. *
X * No distinction is made here between tokens *
X * and (non) terminals. *
X * *
X \*******************************************************/
X
X if (strlen(yytext) == MAXCHARS)
X {
X yyerror(strcat(charroom,yytext),ln);
X exit(3);
X } /* fi */
X strcpy(table[id].symbol,yytext);
X table[id].next_d = 0;
X table[id].next_o = 0;
X } /* fi */
X
X switch (action) {
X case ON_C_IDENT:
X
X /*******************************************************\
X * *
X * Add to list of definition lines. *
X * *
X \*******************************************************/
X
X if (table[id].next_d == MAXDEFS )
X {
X yyerror(strcat(defroom,yytext),ln);
X exit(3);
X } /* fi */
X table[id].description[table[id].next_d++] = ln;
X break;
X
X
X case ON_IDENT:
X
X /*******************************************************\
X * *
X * Add to list of occurance lines. *
X * *
X \*******************************************************/
X if (table[id].next_o == MAXOCCS )
X {
X yyerror(strcat(occroom,yytext),ln);
X exit(3);
X } /* fi */
X table[id].occurance[table[id].next_o++] = ln;
X break;
X
X default :
X fprintf (stdout, "yyaction: invalid action\n");
X return (-1);
X } /* hctiws */
X return (0);
X} /* corp */
X
Xnline(ln)
Xint ln;
X{
X printf("%4d :\t",ln);
X}
X
X
X char declared_at_mark[] = "*";
X char occurs_at_mark[] = "";
X char token_maybe[] = "is not declared - token??";
X char start_maybe[] = "never occurs on rhs of rule - start rule?";
X
X/*
X* Strings for output
X*/
X
Xmain ()
X{
X int ind,id,numids;
X int i, j, gap, temp;
X int pos[MAXIDENTS];
X
X strcpy(table[0].symbol,"");
X
X line = 0;
X nline(++line);
X
X yyparse ();
X
X id = 0;
X while ( strcmp(table[id].symbol,"") != 0 )
X pos[id] = id++;
X
X
X /***************************************************************\
X * *
X * Grubby sort. Pointers to records held in "pos[]". *
X * *
X \***************************************************************/
X
X numids = id;
X for (gap = numids/2; gap > 0; gap /= 2)
X for (i=gap; i<numids; i++)
X for (j=i-gap; j>=0; j-=gap)
X if (strcmp(table[pos[j]].symbol,table[pos[j+gap]].symbol) > 0)
X {
X temp = pos[j];
X pos[j] = pos[j+gap];
X pos[j+gap] = temp;
X }
X
X
X for ( i=0; i<numids; i++ )
X {
X id = pos[i];
X printf("\n' %s ' -\n\t\t\t",table[id].symbol);
X if (table[id].next_d == 0 )
X printf("%s",token_maybe);
X else
X {
X ind = 0;
X printf("%s%d ",declared_at_mark,table[id].description[ind++]);
X for ( ind=1; ind < table[id].next_d ; ind++)
X printf(", %s%d",declared_at_mark,table[id].description[ind]);
X }
X if (table[id].occurance[0] == 0)
X printf(", %s",start_maybe);
X else
X {
X printf(" %d occurances at lines ",table[id].next_o);
X for ( ind = 0; ind < table[id].next_o ; ind++ )
X printf(", %s%d",occurs_at_mark,table[id].occurance[ind]);
X }
X id++;
X }
X printf("\n\n\tEnd of X-ref\n\t~~~~~~~~~~~~\n");
X} /* niam */
X
Xyyerror(mess,errline)
Xchar *mess;
X{
X printf("\n\n\n\t%s at line %d\n",mess,errline);
X} /* corp */
/
echo 'x - xref-regular_expr'
sed 's/^X//' > xref-regular_expr << '/'
X
X /*******************************************************\
X * *
X * X_ref for YACC - LEX file *
X * ~~~~~~~~~~~~~~~~~~~~~~~~~ *
X * *
X * Date: Tue Jul 1 03:36:21 BST 1986 *
X * *
X \*******************************************************/
X
X%{
X
X# include <stdio.h>
X# include "sto.h"
X
X#define TRUE 1
X#define FALSE 0
X
Xint recognised;
Xchar c;
X
X%}
X
X /* abbreviations */
X
Xdigit [0-9]
Xu_case [A-Z]
Xl_case [a-z]
Xid_char [A-Za-z0-9_]
Xletter [A-Za-z]
Xwhite [\t ]
X
X
X%%
X
X"/*" {
X ECHO;
X recognised = FALSE;
X c = nextchar();
X while (recognised == FALSE)
X {
X while (c != '*')
X c = nextchar();
X c = nextchar();
X if (c == '\/')
X recognised = TRUE;
X }
X }
X"%{" {
X ECHO;
X recognised = FALSE;
X c = nextchar();
X while (recognised == FALSE)
X {
X while (c != '\%')
X c = nextchar();
X c = nextchar();
X if (c == '\}')
X recognised = TRUE;
X }
X return(PERCURL);
X }
X"{" {
X
X/*
X* Although LEX can cope with the full definition,
X* ( "{"[^\}]*"}" ) this may overrun the lex buffer (200 chars).
X* Thus this routine.
X*/
X
X ECHO;
X c = nextchar();
X while (c != '\}')
X c = nextchar();
X return(ACT);
X }
X{letter}{id_char}* {
X ECHO;
X return(IDENTIFIER);
X }
X"'"\\?[^']+"'" {
X ECHO;
X return(CHARACTER);
X }
X{white}+ {
X ECHO;
X }
X{digit}+ {
X ECHO;
X return(NUMBER);
X }
X"%"{white}*"left" {
X ECHO;
X return(LEFT);
X }
X"%"{white}*"right" {
X ECHO;
X return(RIGHT);
X }
X"%"{white}*"nonassoc" {
X ECHO;
X return(NONASSOC);
X }
X"%"{white}*"token" {
X ECHO;
X return(TOKEN);
X }
X"%"{white}*"prec" {
X ECHO;
X return(PREC);
X }
X"%"{white}*"type" {
X ECHO;
X return(TYPE);
X }
X"%"{white}*"start" {
X ECHO;
X return(START);
X }
X"%"{white}*"union" {
X ECHO;
X return(UNION);
X }
X"%%" {
X ECHO;
X return(PER);
X }
X":" {
X ECHO;
X return(COLON);
X }
X";" {
X ECHO;
X return(SEMICOLON);
X }
X"," {
X ECHO;
X return(COMMA);
X }
X"|" {
X ECHO;
X return(OR);
X }
X"<" {
X ECHO;
X return(LESS);
X }
X">" {
X ECHO;
X return(GREATER);
X }
X"\n" {
X ECHO;
X nline(++line);
X }
X
X%%
X
Xyywrap()
X{
X /* wrap-up procedure */
X return(1);
X}
X
Xnextchar()
X{
X char c;
X
X c = input();
X printf("%c",c);
X if (c == '\n')
X nline(++line);
X return(c);
X}
/
echo 'x - xref-line.h'
sed 's/^X//' > xref-line.h << '/'
X
X int line;
/
echo 'Part 01 of pack.out complete.'
exit
<---------------------------------- Cut here ---------------------------------->
--
- Marxist unite!
- Comrades unite!
- Bad-spellers of the world untie!
UUCP: ...!seismo!mcvax!ukc!dcl-cs!cathy
DARPA: cathy%lancs.comp@ucl-cs | Post: University of Lancaster,
JANET: cathy@uk.ac.lancs.comp | Department of Computing,
Phone: +44 524 65201 ext ???? | Bailrigg, Lancaster, LA1 4YR, UK.
/* End of text from mirror:net.sources */