1 /* Parser to read optimization patterns of the form:
2 op1 op2 ... test : action
5 and build a program to recognize then */
7 %token SFIT, UFIT, ROTATE, PSIZE, WSIZE, DWSIZE, DEFINED, UNDEFINED, SAMESIGN;
8 %token SAMEEXT, SAMENAM, OFFSET, LOGAND, LOGOR, BITAND, BITOR, XOR;
9 %token MINUS, PLUS, TIMES, DIV, MOD, EQ, NE, LT, LE, GT, GE, NOT, COMP;
10 %token LSHIFT, RSHIFT, COMMA, OPCODE, INT, UPLUS, UMINUS, PATARG;
16 static char rcsidp1[] = "$Id: parser.g,v 1.7 1994/06/24 11:14:30 ceriel Exp $";
23 struct state *states[MAXSTATES];
24 struct action *actions[MAXSTATES];
25 struct mnems patterns[MAXSTATES];
26 int numpatterns = 0; /* Number of patterns */
27 int higheststate = 0; /* Highest state yet allocated */
28 struct idf *ops; /* Chained list of all ops */
30 int maxreplacement = 0;
33 static int lencurrpatt;
34 static int lenthisrepl;
35 static int currentstate; /* Current state of dfa */
45 struct exp_node *restrictions;
46 struct exp_node *finaltest;
47 struct mnem_list *repllist;
51 startline=linenum; currentstate=0;
52 lencurrpatt=0; lenthisrepl=0;
54 patterns(&restrictions)
55 { finaltest = (struct exp_node *)NULL; }
64 addaction(startline,currentstate,restrictions,
70 patterns(struct exp_node **tests;)
72 struct mnem_list *list;
73 struct exp_node *onetest;
77 list = (struct mnem_list *)NULL;
78 *tests = (struct exp_node *)NULL;
83 if(++lencurrpatt>maxpattern)
84 maxpattern=lencurrpatt;
85 list = addelem(list,opval, (struct exp_node *)NULL);
88 opval->id_startpatt=1;
89 currentstate=dotransition(currentstate,opval,list,lencurrpatt);
92 restriction(opval->id_argfmt,&onetest)
94 *tests = combinetests(*tests,onetest);
100 restriction(int argtype; struct exp_node **test;)
102 struct exp_node *test1,*test2;
107 [ %if(argtype==CSTOPT)
108 [ optrelop(&relop) exp(1,test)
110 *test = mknode(relop,mkleaf(PATARG,lencurrpatt),*test);
114 *test = mkleaf(DEFINED,lencurrpatt);
118 *test = mkleaf(UNDEFINED,lencurrpatt);
124 *test=mknode(SAMEEXT,
125 mkleaf(PATARG,lencurrpatt),
132 { offsetop = MINUS; }
136 test2 = mknode(offsetop, test1, test2);
137 test2 = mknode(EQ, mkleaf(PATARG,lencurrpatt), test2);
138 *test = combinetests(
140 mkleaf(PATARG,lencurrpatt),
146 optrelop(&relop) exp(1,test)
148 *test = mknode(relop,mkleaf(PATARG,lencurrpatt),*test);
164 action(struct mnem_list **list;)
166 struct exp_node *test, *test2;
167 struct idf *keepopval;
171 { *list = (struct mnem_list *)NULL; }
175 if(++lenthisrepl>maxreplacement)
176 maxreplacement = lenthisrepl;
177 test= (struct exp_node *)NULL;
180 [ %if(keepopval->id_argfmt==EXT)
189 { offsetop = MINUS; }
193 test2 = mknode(offsetop,test,test2);
198 test = mknode(COMMA,test,test2);
203 *list = addelem(*list,keepopval,test);
208 exp(int level; struct exp_node **result;)
209 { struct exp_node *res1, *res2;
212 %if(level <= MAXPRIO)
214 [ %while (priority(LLsymb) >= level)
219 exp(priority(operator)+1,&res2)
221 res1 = mknode(operator,res1,res2);
227 | '(' exp(1,result) ')'
228 | unaryop(&operator) exp(priority(operator)+1,&res1)
230 *result = mknode(operator,res1,(struct exp_node *)NULL);
232 | SAMESIGN '(' exp(1,&res1) COMMA exp(1,&res2) ')'
234 *result = mknode(SAMESIGN,res1,res2);
236 | SFIT '(' exp(1,&res1) COMMA exp(1,&res2) ')'
238 *result = mknode(SFIT,res1,res2);
240 | UFIT '(' exp(1,&res1) COMMA exp(1,&res2) ')'
242 *result = mknode(UFIT,res1,res2);
244 | ROTATE '(' exp(1,&res1) COMMA exp(1,&res2) ')'
246 *result = mknode(ROTATE,res1,res2);
248 | SAMEEXT '(' patarg(&res1) COMMA patarg(&res2) ')'
250 *result = mknode(SAMEEXT,res1,res2);
252 | SAMENAM '(' patarg(&res1) COMMA patarg(&res2) ')'
254 *result = mknode(SAMENAM,res1,res2);
256 | OFFSET '(' patarg(&res1) ')'
263 *result = mkleaf(PSIZE,0);
267 *result = mkleaf(WSIZE,0);
271 *result = mkleaf(DWSIZE,0);
275 *result = mkleaf(INT,lastintval);
279 patarg(struct exp_node **result;)
281 : PATARG argno(&intval)
283 *result = mkleaf(PATARG,intval);
291 if(lastintval<0 || (lastintval>lencurrpatt)) {
292 fprintf(stderr ,"Illegal $%d on line %d\n",
299 unaryop(int *operator;)
300 : PLUS { *operator = UPLUS; }
301 | MINUS { *operator = UMINUS; }
302 | NOT { *operator = NOT; }
303 | COMP { *operator = COMP; }
329 addaction(startline, state, restrictions, finaltest, repllist)
332 struct exp_node *restrictions, *finaltest;
333 struct mnem_list *repllist;
335 struct action *p, *q;
336 p=(struct action *)Malloc(sizeof(struct action));
337 p->next = (struct action *)NULL;
338 p->linenum = startline;
339 p->test = combinetests(restrictions,finaltest);
340 p->replacement.m_len = lenthisrepl;
341 p->replacement.m_elems = constructlist(repllist,lenthisrepl);
342 /* chain new action to END of action chain */
343 if((q = actions[state])==(struct action *)NULL)
346 while(q->next != (struct action *)NULL)
353 constructlist(list,len)
354 struct mnem_list *list;
357 struct mnem_elem **p;
358 p = (struct mnem_elem **)
359 Malloc((unsigned)(len*sizeof(struct mnem_elem *)));
368 addelem(oldlist, mnem, test)
369 struct mnem_list *oldlist;
371 struct exp_node *test;
373 struct mnem_list *reslist;
374 struct mnem_elem *element;
375 element = (struct mnem_elem *)Malloc(sizeof(struct mnem_elem));
376 element->op_code = mnem;
378 reslist = (struct mnem_list *)Malloc(sizeof(struct mnem_list));
379 reslist->elem = element;
380 reslist->next = oldlist;
385 dotransition(state, mnem, mnem_list, lenlist)
388 struct mnem_list *mnem_list;
392 /* look for existing transition */
394 (p!=((struct state *)NULL)) && ((p->op)!=mnem);
397 if(p==(struct state *)NULL) {
398 /* none found so add a new state to dfa */
399 p=(struct state *)Malloc(sizeof(struct state));
401 if(++higheststate>MAXSTATES) {
402 fprintf(stderr,"Parser: More than %s states\n",MAXSTATES);
405 p->goto_state= higheststate;
406 p->next=states[currentstate];
407 states[currentstate]=p;
408 states[higheststate] = (struct state *)NULL;
409 actions[higheststate] = (struct action *)NULL;
410 patterns[higheststate].m_len = lencurrpatt;
411 patterns[higheststate].m_elems =
412 constructlist(mnem_list,lenlist);
413 return(higheststate);
415 else return(p->goto_state); /* already exists */
419 combinetests(test1, test2)
420 struct exp_node *test1, *test2;
422 if(test1==(struct exp_node *)NULL)
424 else if(test2==(struct exp_node *)NULL)
427 return(mknode(LOGAND,test1,test2));
430 priority(op) int op; {
432 case LOGOR: return(1);
433 case LOGAND: return(2);
434 case BITOR: return(3);
436 case BITAND: return(5);
444 case RSHIFT: return(8);
446 case PLUS: return(9);
449 case MOD: return(10);
453 case UMINUS: return(11);
455 fprintf(stderr,"Internal error: priority: - unrecognized operator\n");
460 mknode(op,left,right)
462 struct exp_node *left,*right;
465 p = (struct exp_node *)Malloc(sizeof(struct exp_node));
468 p->exp_right = right;
477 p = (struct exp_node *)Malloc(sizeof(struct exp_node));
483 LLmessage(insertedtok)
487 fprintf(stderr,"parser: syntax error on line %d: ",linenum);
489 fprintf(stderr,"Inserted token %d\n",insertedtok);
492 else fprintf(stderr,"Deleted token %d\n",LLsymb);
497 states[0] = (struct state *)NULL;
498 patterns[0].m_len = 0;
501 fprintf(stderr,"%d errors detected\n",nerrors);