[net.sources] Xref again

cathy@comp.lancs.ac.uk (Cathy) (10/28/86)

	Due to the large number of flames concerning the xref bugs in "union"
	statements, here is a version which caters for them. All "{" "}" inside
	print statements in actions are also handled. Many thanks to all flamers
	especially:  "Robert O. Domitz" <rod@uucp.pecnos> for his patience.
<-----------------------------CUT HERE----------------------------------------->
#!/bin/sh
echo 'Start of pack.out, part 01 of 01:'
echo 'x - xref.lex'
sed 's/^X//' > xref.lex << '/'
X
X	/*******************************************************\
X	*							*
X	*	X_ref for YACC - LEX file			*
X	*	~~~~~~~~~~~~~~~~~~~~~~~~~			*
X	*							*
X	*	Date: Sat Sep 13 19:13:12 BST 1986		*
X	*	Cathy Taylor,					*
X	*	c/o Department of Computing,			*
X	*	University of Lancaster,			*
X	*	Bailrigg, Lancaster, England.			*
X	*							*
X	\*******************************************************/
X
X%{
X# include	<stdio.h>
X# include	"xref.line.h"
X# define	TRUE 1
X# define 	FALSE 0
X
Xint	recognised,depth,quoted;
Xchar	c,oldc;
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				ECHO;
X				recognised = FALSE;
X				c = nextc();
X				while (recognised == FALSE)
X				{
X					while (c != '*')
X						c = nextc();
X					c = nextc();
X					if (c == '\/')
X						recognised = TRUE;
X				}
X			}
X"%{"			{
X				ECHO;
X				recognised = FALSE;
X				c = nextc();
X				while (recognised == FALSE)
X				{
X					while (c != '\%')
X						c = nextc();
X					c = nextc();
X					if (c == '\}')
X						recognised = TRUE;
X				}
X				return(PERCURL);
X			}
X"{"			{
X
X/*
X*	This definition handles nested {} and braces inside print statements.
X*/
X
X				ECHO;
X				depth=1;
X				oldc = '\0';
X				quoted = FALSE;
X				while (depth != 0)
X				{
X				    c = nextc();
X				    while (c != '\}')
X				    {
X					if (( c == '\{' ) && (quoted == FALSE) && (oldc != '\\'))
X					    depth++;
X					if ((c == '\"') && (oldc != '\\'))
X					   quoted = (quoted+1) % 2;
X					oldc = c;
X					c = nextc();
X				    }
X				    oldc = c;
X				    if ((quoted == FALSE) && (oldc != '\\'))
X					depth--;
X				}
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
Xnextc()
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;
X
/
echo 'x - xref.yacc'
sed 's/^X//' > xref.yacc << '/'
X%{
X# include <ctype.h>
X# include <stdio.h>
X%}
X
X	/*******************************************************\
X	*							*
X	*	X_reference program for YACC files		*
X	*	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~		*
X	*	Cathy Taylor,					*
X	*	c/o Department of Computing,			*
X	*	University of Lancaster,			*
X	*	Bailrigg, Lancaster, England.			*
X	*							*
X	*	Date : Sat Sep 13 19:14:26 BST 1986		*
X	*							*
X	\*******************************************************/
X
X	/***********************************************\
X	*						*
X	*	Yacc Input Syntax			*
X	*	~~~~~~~~~~~~~~~~~			*
X	*	Adapted from the document		*
X	*	'YACC - Yet Another Compiler Compiler'	*
X	*		by				*
X	*	   S. C. Johnson			*
X	*	   *************			*
X	*						*
X	*	Date: Tue Jul  1 02:40:18 BST 1986	*
X	*						*
X	\***********************************************/
X
X%token	IDENTIFIER CHARACTER NUMBER PER PERCURL ACT
X%token	LEFT RIGHT NONASSOC TOKEN PREC TYPE START UNION
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 ACT
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,yytext);
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,yytext);
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	"xref.line.h"
X
X# define	ON_C_IDENT	000
X# define	ON_IDENT	001
X
Xstruct	llist {
X			int	line;
X		struct	llist	*next;
X		} ;
X
Xstruct	table {
X			char	*symbol;
X		struct	llist	*desc;
X		struct	llist	*occ;
X		struct	table	*left;
X		struct	table	*right;
X		} *table = NULL;
X
Xextern	char	*malloc();
X
Xchar	*nocore[] = "No more core left";
X
Xyyerror(mess)
Xchar	*mess;
X{
X	printf("\n\n\n\t%s\n");
X}
X
Xchar	*m_alloc(nbytes)
Xunsigned	nbytes;
X{
X	char	*p;
X
X	if ((p=malloc(nbytes)) != NULL)
X	    return(p);
X	yyerror(nocore);
X	exit(3);
X}
X
Xstruct	llist	*save_ln(ln,ptr)
X	int	ln;
Xstruct	llist	*ptr;
X{
X	struct	llist	*q;
X
X	ptr -> line = ln;
X	q = (struct llist *) m_alloc(sizeof(struct llist) + 1);
X	q -> next = ptr;
X	return(q);
X}
X
Xchar	*strsave(s)
Xchar	*s;
X{
X	char	*p;
X
X	p = m_alloc(strlen(s)+1);
X	strcpy(p,s);
X	return(p);
X}
X
X	char	*mess = "Case bound error";
X
Xstruct	table	*save_symbol(action,ln,text,ptr)
X	int	action;
X	int	ln;
X	char	*text;
Xstruct	table	*ptr;
X{
X	if (ptr == NULL) /* create new definition */
X	{
X	    ptr = (struct table *) m_alloc(sizeof(struct table)+1);
X	    ptr -> symbol = strsave(text);
X	    ptr -> left = ptr -> right = NULL;
X	    ptr -> desc = (struct llist *) m_alloc(sizeof(struct llist)+1);
X	    ptr -> occ = (struct llist *) m_alloc(sizeof(struct llist)+1);
X	}
X	else if ((strcmp(ptr -> symbol,text)) < 0)
X	{
X	    ptr -> left = save_symbol(action,ln,text,ptr -> left);
X	    return(ptr);
X	}
X	else if ((strcmp(ptr -> symbol,text)) > 0)
X	{
X	    ptr -> right = save_symbol(action,ln,text,ptr -> right);
X	    return(ptr);
X	}
X	switch (action)
X	{   case ON_C_IDENT :	/* Add to list of definition lines */
X	    {
X		ptr -> desc = save_ln(ln,ptr -> desc);
X		return(ptr);
X	    }
X	    case ON_IDENT :	/* Add to list of occurance lines */
X	    {
X		ptr -> occ = save_ln(ln,ptr -> occ);
X		return(ptr);
X	    }
X	    default :
X	    {
X		yyerror(mess);
X		exit(3);
X	    }
X	}
X}
X
Xyyaction (action,ln,text)
X	int	action;
X	int	ln;
X	char	*text;
X{
X	table = save_symbol(action,ln,text,table);
X}
X
Xlist_lines(ptr,comment)
Xstruct	llist	*ptr;
X	char	*comment;
X{
X	fprintf(stdout,"%s%d",comment,ptr -> line);
X	if (ptr -> next == NULL)
X	{
X	    fprintf(stdout," ; ");
X	    return(0);
X	}
X	fprintf(stdout,", ");
X	list_lines(ptr -> next,comment);
X}
X
X/*******************************\
X*				*
X*	Fprint strings.		*
X*				*
X\*******************************/
X
X	char	pre_decl_list_mark[] = "";
X	char	pre_occ_list_mark[] = " occurs at line(s) ";
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
Xlist_xref(root)
Xstruct	table	*root;
X{
X	if (root == NULL)
X	    return(0);
X	list_xref(root -> right);
X/*
X*	List info for current string.
X*/
X	{
X	    fprintf(stdout,"\n' %s ' -\n\t\t\t",root -> symbol);
X	    if (root -> desc -> next == NULL)
X	        fprintf(stdout,"%s",token_maybe);
X	    else
X		list_lines(root -> desc -> next,declared_at_mark);
X	    if (root -> occ -> next == NULL)
X	        fprintf(stdout,", %s",start_maybe);
X	    else
X	    {
X	        fprintf(stdout,"%s",pre_occ_list_mark);
X	        list_lines(root -> occ -> next,occurs_at_mark);
X	    }
X	}
X
X	list_xref(root -> left);
X}
X
Xnline(ln)
Xint	ln;
X{
X	printf("%4d :\t",ln);
X}
X
Xmain ()
X{
X
X	line = 0; nline(++line);
X	yyparse ();
X	list_xref(table);
X	fprintf(stdout,"\n\n\tEnd of X-ref\n\t~~~~~~~~~~~~\n");
X}
/
echo 'Part 01 of pack.out complete.'
exit
<-----------------------------CUT HERE----------------------------------------->

	 .... just parsing through ...
  
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: None			|	Bailrigg, Lancaster, LA1 4YR, UK.