138 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* $Id$ */
 | |
| /*
 | |
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | |
|  * See the copyright notice in the ACK home directory, in the file "Copyright".
 | |
|  */
 | |
| /* p a t t e r n . c
 | |
|  *
 | |
|  * Deals with the pattern stuff.
 | |
|  * it maintains a table of information about the patterns
 | |
|  * Functions : addpattern() and printpatterns()
 | |
|  */
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| #include <ctype.h>
 | |
| #include "misc.h"
 | |
| #include "symtab.h"
 | |
| 
 | |
| struct pattern {
 | |
|     char *p_constraint;			/* constraint of this pattern */
 | |
|     int p_lineno, 			/* line number of constraint */
 | |
|         p_npat, 			/* # of instructions in pattern */
 | |
|         p_nrepl;			/* # of instructions in replacement */
 | |
| };
 | |
| 
 | |
| static struct pattern *pattable,	/* ptr to pattern array */
 | |
| 		      *current,		/* ptr to first unoccupied el of
 | |
| 					 * pattern array
 | |
| 					 */
 | |
| 		      *maxpat;		/* if beyond this, new space must
 | |
| 					 * be allocated
 | |
| 					 */
 | |
| 
 | |
| addpattern(str,l,np,nr) char *str; {
 | |
|     /*
 | |
|      * Just add a pattern to the list.
 | |
|      * "str" is the constraint, "l" is the line number,
 | |
|      * "np" is the number of instructions in the pattern,
 | |
|      * "nr" is the number of instructions in the replacement
 | |
|      * Space is allocated in chunks of 50
 | |
|      */
 | |
|     register struct pattern *p;
 | |
| 
 | |
|     if (!pattable) {		/* No space allocated yet */
 | |
| 	pattable = (struct pattern *) malloc(50 * sizeof *pattable);
 | |
| 	current = pattable;
 | |
| 	maxpat = pattable + 50;
 | |
|     }
 | |
|     if (current >= maxpat) {	/* Allocate some new space */
 | |
| 	p = pattable;
 | |
| 	pattable = (struct pattern *) realloc(
 | |
| 		(char *) pattable,
 | |
| 		(unsigned) (sizeof *pattable * (50 + (maxpat - pattable))));
 | |
| 	current = pattable + (current - p);
 | |
| 	maxpat = pattable + (maxpat - p) + 50;
 | |
|     }
 | |
|     p = current++;
 | |
|     p->p_constraint = str;
 | |
|     p->p_lineno = l;
 | |
|     p->p_npat = np;
 | |
|     p->p_nrepl = nr;
 | |
| }
 | |
| 
 | |
| static
 | |
| prconstraint(str) char *str; {
 | |
|     /*
 | |
|      * prints a constraint, with variable names replaced
 | |
|      */
 | |
|     char c;
 | |
|     register char *p, *q;
 | |
|     struct symtab *name;
 | |
| 
 | |
|     p = str;
 | |
|     while (*p) {
 | |
| 	if (isupper(*p) || islower(*p) || *p == '_') {
 | |
| 	    /*
 | |
| 	     * Start of identifier
 | |
| 	     */
 | |
| 	    q = p + 1;
 | |
| 	    while (*q && (
 | |
| 		   isupper(*q) || islower(*q) || isdigit(*q) || *q == '_')) {
 | |
| 		q++;
 | |
| 	    }
 | |
| 	    c = *q;
 | |
| 	    *q = '\0';
 | |
| 	    /* Temporarily let it end with null byte */
 | |
| 	    name = findident(p,LOOKING,&idtable);
 | |
| 	    if (name) {		/* yeah, it was a variable */
 | |
| 		fprintf(genc,"var[%d].value", name->s_num);
 | |
| 	    }
 | |
| 	    else if (!strcmp(p, "ANY")) {
 | |
| 		fputs("ANY.value", genc);
 | |
| 	    }
 | |
| 	    else fputs(p,genc);
 | |
| 	    /* Now replace null byte with whatever used to be there */
 | |
| 	    *q = c;
 | |
| 	    p = q;
 | |
| 	}
 | |
| 	else {
 | |
| 	    putc(*p,genc);
 | |
| 	    p++;
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| printpatterns() {
 | |
|     /*
 | |
|      * Prints the pattern_descr table and generates the routine
 | |
|      * "check_constraint"
 | |
|      */
 | |
|     register struct pattern *p;
 | |
|     register i;
 | |
| 
 | |
|     p = pattable;
 | |
|     i = 1;
 | |
|     fputs("struct pattern_descr patterns[] = {\n", genc);
 | |
|     while (p != current) {
 | |
| 	fprintf(genc," {%d,pat%d,%d,rep%d,},\n",
 | |
| 			p->p_npat, i, p->p_nrepl, i);
 | |
| 	p++;
 | |
| 	i++;
 | |
|     }
 | |
|     fputs("};\n", genc);
 | |
|     fputs("int\ncheck_constraint(patno){\n\tint r;\n\tswitch(patno){\n",genc);
 | |
|     p = pattable;
 | |
|     while (p < current) {
 | |
| 	if (p->p_constraint) {
 | |
| 	    /* The pattern has a constraint */	
 | |
| 	    fprintf(genc,"\tcase %d :\n",p - pattable);
 | |
| 	    fprintf(genc,linedir,p->p_lineno,inpfile);	/* linedirective */
 | |
| 	    fputs("\tr = (",genc);
 | |
| 	    prconstraint(p->p_constraint);
 | |
| 	    fputs("); break;\n",genc);
 | |
| 	}
 | |
| 	p++;
 | |
|     }
 | |
|     fputs("\tdefault :\n\t\tr = 1;\n\t}\n\treturn r;\n}\n\n",genc);
 | |
| }
 |