ack/util/topgen/pattern.c

139 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);
}