1 /* $NetBSD: llparse.c,v 1.13 2009/03/14 15:36:24 dsl Exp $ */
4 * ************************* NOTICE *******************************
5 * This code is in the public domain. It cannot be copyrighted.
6 * This ll parser was originally written by Keith Thompson for the
7 * University of Wisconsin Crystal project.
8 * It was based on an FMQ lr parser written by Jon Mauney at the
9 * University of Wisconsin.
10 * It was subsequently modified very slightly by Nancy Hall at the
11 * University of Wisconsin for the Crystal project.
12 * ****************************************************************
15 #include <sys/cdefs.h>
16 __KERNEL_RCSID(0, "$NetBSD: llparse.c,v 1.13 2009/03/14 15:36:24 dsl Exp $");
25 #define LLMINACTION -LLINF
27 short llparsestack
[STACKSIZE
];
36 register int havetoken
= false;
38 register LLtoken
*t
= &lltoken
;
39 register int parseaction
;
40 register int accepted
= false;
42 llpushprod(llnprods
-1); /* $$$ ::= <start symbol> */
45 sym
= llparsestack
[llstackptr
];
47 printf("llparse() top of loop, llstackptr=%d, sym=%d\n",
53 if(sym
<= LLMINACTION
) {
54 for(;sym
<=LLMINACTION
;sym
++) {
55 llaction(1, t
); /* calls llfinprod */
59 } else { llaction(-sym
, t
);
67 /* it's a terminal symbol */
74 if(sym
== t
->llterm
) {
75 llpushattr(t
->llattrib
);
77 llstackptr
--; /* pop terminal */
78 if(t
->llterm
== llnterms
-1) { /* end symbol $$$ */
84 llparsererror(t
); /* wrong terminal on input */
97 /* consult parse table for new production */
98 parseaction
= llfindaction(sym
, t
->llterm
);
100 if(parseaction
== 0) {
107 if(llepsilon
[parseaction
]) {
108 /* epsilon production */
109 if(llepsilonok(t
->llterm
)) {
110 llstackptr
--; /* pop nonterminal */
111 llpushprod(parseaction
); /* push rhs of production */
117 llstackptr
--; /* pop nonterminal */
118 llpushprod(parseaction
); /* push rhs of production */
126 llpushprod(prod
) /* recognize production prod - push rhs on stack */
133 start
= llprodindex
[prod
].llprodstart
;
134 length
= llprodindex
[prod
].llprodlength
;
137 printf("llpushprod(%d) llstackptr=0x%x(%d), length = 0x%x(%d)\n",
138 prod
, llstackptr
, llstackptr
, length
, length
);
143 if(llstackptr
+length
>= STACKSIZE
) {
144 fprintf(stderr
,"Parse stack overflow. llstackptr=0x%x, length=0x%x\n",
150 llsetattr(llprodindex
[prod
].llprodtlen
);
152 /* put a marker on the stack to mark beginning of production */
153 if(llparsestack
[llstackptr
] <= LLMINACTION
) {
154 (llparsestack
[llstackptr
]) --; /* if there's already one there, don't
155 put another on; just let it represent all of
156 the adjacent markers */
160 llparsestack
[llstackptr
] = LLMINACTION
;
163 for(count
=0; count
<length
; count
++) {
165 llparsestack
[llstackptr
] = llproductions
[start
++];
167 if(llstackptr
> STACKSIZE
) {
168 fprintf(stderr
, "PARSE STACK OVERFLOW! \n"); Exit(-1);
174 llepsilonok(int term
)
183 printf("llepsilonok() enter\n");
190 sym
= llparsestack
[ptr
];
204 pact
= llfindaction(sym
, term
);
212 if(llepsilon
[pact
] == true) {
227 llfindaction(int sym
, int term
)
232 printf("llfindaction(sym=%d, term=%d) enter \n", sym
, term
);
234 index
= llparseindex
[sym
];
236 while(llparsetable
[index
].llterm
!= 0) {
237 if(llparsetable
[index
].llterm
== term
) {
238 return(llparsetable
[index
].llprod
);
246 llparsererror(LLtoken
*token
)
249 fprintf(stderr
,"llparsererror() enter\n");
253 fprintf(stderr
, "Syntax error: ");
260 llgettoken(LLtoken
*token
)
263 token
->llstate
= NORMAL
;
265 printf("llgettoken(): ");
271 /******************************************************************************
273 Attribute support routines
275 ******************************************************************************/
279 ** AttrStack = stack of record
280 ** values : array of values;
286 LLattrib llattributes
[LLMAXATTR
];
289 struct llattr llattrdesc
[LLMAXDESC
];
296 register struct llattr
*ptr
;
299 printf("llsetattr(%d) enter\n",n
);
301 if(lldescindex
>= LLMAXDESC
) {
302 fprintf(stdout
, "llattribute stack overflow: desc\n");
304 "lldescindex=0x%x, llattrtop=0x%x\n",lldescindex
, llattrtop
);
307 ptr
= &llattrdesc
[lldescindex
];
308 ptr
->llabase
= &llattributes
[llattrtop
];
309 ptr
->lloldtop
= ++llattrtop
;
311 ptr
->llacnt
= n
+1; /* the lhs ALWAYS uses an attr; it remains on the
312 stack when the production is recognized */
317 llpushattr(LLattrib attr
)
322 printf("llpushattr() enter\n");
324 if(llattrtop
+ 1 > LLMAXATTR
) {
325 fprintf(stderr
, "ATTRIBUTE STACK OVERFLOW!\n");
328 a
= &llattrdesc
[lldescindex
-1];
329 llattributes
[llattrtop
++] = attr
;
330 a
->llaindex
++; /* inc count of attrs on the stack for this prod */
337 printf("llfinprod() enter\n");
340 llattrtop
= llattrdesc
[lldescindex
].lloldtop
;
341 llattrdesc
[lldescindex
-1].llaindex
++; /* lhs-of-prod.attr stays on
342 the stack; it is now one of the rhs attrs of the now-top production
349 dump_parse_stack(void)
353 printf("PARSE STACK:\n");
354 for(ind
=llstackptr
; ind
>=0; ind
--) {
355 printf("%d\t%d\t%s\n",
356 ind
, llparsestack
[ind
],
357 llparsestack
[ind
]<0? "Action symbol" : llstrings
[llparsestack
[ind
]]);
365 prt_token(LLtoken
*t
)
367 fprintf(stdout
, "t at %p\n", t
);
368 fprintf(stdout
, "t->llterm=0x%x\n", t
->llterm
); (void) fflush(stdout
);
369 fprintf(stdout
, "TOK: %s\n", llstrings
[t
->llterm
]);
370 (void) fflush(stdout
);
372 /* to make lint shut up */
373 fprintf(stdout
, "", llnterms
, llnsyms
, llnprods
, llinfinite
);