Initial revision
This commit is contained in:
		
							parent
							
								
									6cbb37051b
								
							
						
					
					
						commit
						a21f936651
					
				
					 14 changed files with 1788 additions and 0 deletions
				
			
		
							
								
								
									
										12
									
								
								util/LLgen/lib/incl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								util/LLgen/lib/incl
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| #define LLin(x) (LLsets[(x)+LLi]&LLb) | ||||
| 
 | ||||
| extern short *LLptr; | ||||
| extern char LLsets[]; | ||||
| extern int LLi, LLb; | ||||
| extern int LLsymb; | ||||
| extern int LLcsymb; | ||||
| extern int LLscd; | ||||
| 
 | ||||
| # include "Lpars.h" | ||||
							
								
								
									
										215
									
								
								util/LLgen/lib/rec
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								util/LLgen/lib/rec
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,215 @@ | |||
| /*  | ||||
|  * Some grammar independent code. | ||||
|  * This file is copied into Lpars.c. | ||||
|  */ | ||||
| 
 | ||||
| static char *rcsid = "$Header$"; | ||||
| 
 | ||||
| #define LLSTSIZ	1024 | ||||
| static short	LLstack[LLSTSIZ];		/* Recovery stack */ | ||||
| short *		LLptr;				/* ptr in it */ | ||||
| #define		LLmax (&LLstack[LLSTSIZ-1])	/* if beyond this, overflow */ | ||||
| int		LLscd;				/* lookahead done or not? */ | ||||
| int		LLb,LLi; | ||||
| int		LLsymb; | ||||
| int		LLcsymb; | ||||
| static int	LLlevel; | ||||
| static short *	LLbase; | ||||
| 
 | ||||
| static struct LLsaved { | ||||
| 	int LLs_i, LLs_b, LLs_s, LLs_c, LLs_t; | ||||
| 	short *LLs_p, *LLs_x; | ||||
| } LLsaved[LL_MAX]; | ||||
| 
 | ||||
| /* In this file are defined: */ | ||||
| extern		LLcheck(); | ||||
| extern		LLscan(); | ||||
| extern		LLpush(); | ||||
| extern		LLlpush(); | ||||
| extern int	LLpop(); | ||||
| extern int	LLsskip(); | ||||
| static		LLerror(); | ||||
| extern		LLnewlevel(); | ||||
| extern		LLoldlevel(); | ||||
| 
 | ||||
| LLcheck() { | ||||
| 	register c; | ||||
| 	/*  | ||||
| 	 * The symbol to be checked is on the stack. | ||||
| 	 */ | ||||
| 	if (!LLscd) { | ||||
| 		if ((c = LL_LEXI()) <= 0) c = EOFILE; | ||||
| 		LLsymb = c; | ||||
| 	} | ||||
| 	else LLscd = 0; | ||||
| 	if (LLsymb == *--LLptr) return; | ||||
| 	/*  | ||||
| 	 * If we come here, an error has been detected. | ||||
| 	 * LLpop will try and recover | ||||
| 	 */ | ||||
| 	LLptr++; | ||||
| 	while (LLindex[LLsymb] < 0) { | ||||
| 		LLerror(0); | ||||
| 		if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE; | ||||
| 	} | ||||
| 	LLcsymb = LLindex[LLsymb]; | ||||
| 	LLb = LLbyte[LLcsymb]; | ||||
| 	LLi = LLcsymb>>3; | ||||
| 	LLscd = 1; | ||||
| 	if (!LLpop()) LLerror(*LLptr); | ||||
| 	LLscd = 0; | ||||
| } | ||||
| 
 | ||||
| LLscan(t) { | ||||
| 	/* | ||||
| 	 * Check if the next symbol is equal to the parameter | ||||
| 	 */ | ||||
| 	if (!LLscd) { | ||||
| 		if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE; | ||||
| 	} | ||||
| 	else LLscd = 0; | ||||
| 	if (LLsymb == t) return; | ||||
| 	/* | ||||
| 	 * If we come here, an error has been detected | ||||
| 	 */ | ||||
| 	LLpush(t); | ||||
| 	LLscd = 1; | ||||
| 	while (LLindex[LLsymb] < 0) { | ||||
| 		LLerror(0); | ||||
| 		if ((LLsymb = LL_LEXI()) <= 0) LLsymb = EOFILE; | ||||
| 	} | ||||
| 	LLcsymb = LLindex[LLsymb]; | ||||
| 	LLb = LLbyte[LLcsymb]; | ||||
| 	LLi = LLcsymb>>3; | ||||
| 	if (!LLpop()) LLerror(t); | ||||
| 	LLscd = 0; | ||||
| } | ||||
| 
 | ||||
| LLpush(t) { | ||||
| 	if (LLptr == LLmax) { | ||||
| 		LLerror(-1); | ||||
| 	} 	 | ||||
| 	*LLptr++ = t; | ||||
| } | ||||
| 
 | ||||
| LLlpush(d) { | ||||
| 	register i; | ||||
| 	register short *p; | ||||
| 	 | ||||
| 	p = &LLlists[d]; | ||||
| 	i = *p++; | ||||
| 	while(i--) { | ||||
| 		if (LLptr == LLmax) { | ||||
| 			LLerror(-1); | ||||
| 		} | ||||
| 		*LLptr++ = *p++; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| LLsskip() { | ||||
| 	/* | ||||
| 	 * Error recovery, and not only that! | ||||
| 	 * Skip symbols until one is found that is on the stack. | ||||
| 	 * Return 1 if it is on top of the stack | ||||
| 	 */ | ||||
| 	register short *t; | ||||
| 	register i; | ||||
| 
 | ||||
| 	for (;;) { | ||||
| 		if (!LLscd) { | ||||
| lab: | ||||
| 			if ((i = LL_LEXI()) <= 0) i = EOFILE; | ||||
| 			LLsymb = i; | ||||
| 			if ((i = LLindex[i]) < 0) { | ||||
| 				LLerror(0); | ||||
| 				goto lab; | ||||
| 				/* | ||||
| 				 * Ugly, but we want speed | ||||
| 			 	 * on possibly correct symbols !! | ||||
| 			 	 * So, no breaks out of "for (;;)" | ||||
| 			 	 */ | ||||
| 			} | ||||
| 			LLcsymb = i; | ||||
| 			LLb = LLbyte[i]; | ||||
| 			LLi = (i>>3); | ||||
| 			LLscd = 1; | ||||
| 		} | ||||
| 		t = LLptr-1; | ||||
| 		i = *t; | ||||
| 		if (!((i<=0 && LLsets[LLi-i]&LLb)||i==LLsymb)) { | ||||
| 			while (--t >= LLbase) { | ||||
| 				/* | ||||
| 			 	 * If the element on the stack is negative, | ||||
| 			 	 * its opposite is an index in the setarray, | ||||
| 			 	 * otherwise it is a terminal symbol | ||||
| 			 	 */ | ||||
| 				i = *t; | ||||
| 				if ((i<=0&&LLsets[LLi-i]&LLb)||i==LLsymb){ | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (t >= LLbase) break; | ||||
| 			LLerror(0); | ||||
| 			LLscd = 0; | ||||
| 		} | ||||
| 		else { | ||||
| 			return 1; | ||||
| 		} | ||||
| 	} | ||||
| 	return t == LLptr - 1; | ||||
| } | ||||
| 
 | ||||
| LLpop() { | ||||
| 	register i; | ||||
| 
 | ||||
| 	i = LLsskip(); | ||||
| 	LLptr--; | ||||
| 	return i; | ||||
| } | ||||
| 
 | ||||
| static | ||||
| LLerror(d) { | ||||
| 
 | ||||
| 	LLmessage(d); | ||||
| 	if (d < 0) exit(1); | ||||
| } | ||||
| 
 | ||||
| LLnewlevel() { | ||||
| 	register struct LLsaved *p; | ||||
| 
 | ||||
| 	if (!LLlevel++) { | ||||
| 		LLptr = LLstack; | ||||
| 		LLbase = LLstack; | ||||
| 		LLpush(EOFILE); | ||||
| 	} | ||||
| 	else { | ||||
| 		if (LLlevel > LL_MAX) LLerror(-1); | ||||
| 		p = &LLsaved[LLlevel - 2]; | ||||
| 		p->LLs_p = LLptr; | ||||
| 		p->LLs_i = LLi; | ||||
| 		p->LLs_b = LLb; | ||||
| 		p->LLs_s = LLsymb; | ||||
| 		p->LLs_t = LLcsymb; | ||||
| 		p->LLs_c = LLscd; | ||||
| 		p->LLs_x = LLbase; | ||||
| 		LLbase = LLptr; | ||||
| 		LLpush(EOFILE); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| LLoldlevel() { | ||||
| 	register struct LLsaved *p; | ||||
| 
 | ||||
| 	LLcheck(); | ||||
| 	if (--LLlevel) { | ||||
| 		p = &LLsaved[LLlevel-1];  | ||||
| 		LLptr = p->LLs_p; | ||||
| 		LLi = p->LLs_i; | ||||
| 		LLb = p->LLs_b; | ||||
| 		LLsymb = p->LLs_s; | ||||
| 		LLcsymb = p->LLs_t; | ||||
| 		LLbase = p->LLs_x; | ||||
| 		LLscd = p->LLs_c; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										54
									
								
								util/LLgen/src/alloc.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								util/LLgen/src/alloc.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * alloc.c | ||||
|  * Interface to malloc() and realloc() | ||||
|  */ | ||||
| 
 | ||||
| # include "types.h" | ||||
| # include "extern.h" | ||||
| 
 | ||||
| static string rcsid = "$Header$"; | ||||
| 
 | ||||
| static string e_nomem = "Out of memory"; | ||||
| 
 | ||||
| p_mem | ||||
| alloc(size) unsigned size; { | ||||
| 	register p_mem	p; | ||||
| 	p_mem		malloc(); | ||||
| 
 | ||||
| 	if ((p = malloc(size)) == 0) fatal(linecount,e_nomem); | ||||
| 	return p; | ||||
| } | ||||
| 
 | ||||
| p_mem | ||||
| ralloc(p,size) p_mem p; unsigned size; { | ||||
| 	register p_mem	q; | ||||
| 	p_mem		realloc(); | ||||
| 
 | ||||
| 	if ((q = realloc(p,size)) == 0) fatal(linecount,e_nomem); | ||||
| 	return q; | ||||
| } | ||||
							
								
								
									
										35
									
								
								util/LLgen/src/assert.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								util/LLgen/src/assert.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * assert.h $Header$ | ||||
|  * an assertion macro | ||||
|  */ | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| #define assert(x) if(!(x)) badassertion("x",__FILE__,__LINE__) | ||||
| #else | ||||
| #define assert(x)	/* nothing */ | ||||
| #endif | ||||
							
								
								
									
										86
									
								
								util/LLgen/src/extern.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								util/LLgen/src/extern.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * extern.h $Header$ | ||||
|  * Miscellanious constants and | ||||
|  * some variables that are visible in more than one file | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * options for the identifier search routine | ||||
|  */ | ||||
| # define JUSTLOOKING	0 | ||||
| # define ENTERING	1 | ||||
| # define BOTH		2 | ||||
| 
 | ||||
| /*
 | ||||
|  * Now for some	declarations | ||||
|  */ | ||||
| 
 | ||||
| extern char	ltext[];	/* input buffer	*/ | ||||
| extern int	nnonterms;	/* number of nonterminals */ | ||||
| extern int	nterminals;	/* number of terminals */ | ||||
| extern p_start	start;		/* will	contain	startsymbols */ | ||||
| extern int	linecount;	/* line number */ | ||||
| extern int	assval;		/* to create difference	between	literals
 | ||||
| 				 * and other terminals | ||||
| 				 */ | ||||
| extern t_nont	nonterms[];	/* the nonterminal array */ | ||||
| extern p_nont	maxnt;		/* is filled up until here */ | ||||
| extern int	order[];	/* order of nonterminals in the grammar,
 | ||||
| 				 * important because actions are copied to | ||||
| 				 * a temporary file in the order in which they | ||||
| 				 * were read | ||||
| 				 */ | ||||
| extern int	*maxorder;	/* will contain &order[nnonterms] */ | ||||
| extern t_entry	h_entry[];	/* terminal and nonterminal entrys,
 | ||||
| 				 * first NTERMINAL entrys reserved | ||||
| 				 * for terminals | ||||
| 				 */ | ||||
| extern p_entry	max_t_ent;	/* will contain &h_entry[nterminals] */ | ||||
| # define	min_nt_ent	&h_entry[NTERMINALS] | ||||
| extern string	pentry[];	/* pointers to various allocated things */ | ||||
| extern string	e_noopen;	/* Error message string used often */ | ||||
| extern int	verbose;	/* Level of verbosity */ | ||||
| extern string	lexical;	/* name of lexical analyser */ | ||||
| extern int	ntneeded;	/* ntneeded = 1 if nonterminals are included
 | ||||
| 				 * in the sets. | ||||
| 				 */ | ||||
| extern int	ntprint;	/* ntprint = 1 if they must be printed too in
 | ||||
| 				 * the LL.output file (-x option) | ||||
| 				 */ | ||||
| # ifndef NDEBUG | ||||
| extern int	debug; | ||||
| # endif not NDEBUG | ||||
| extern p_file	files,pfile;	/* pointers to file structure.
 | ||||
| 				 * "files" points to the start of the | ||||
| 				 * list */ | ||||
| extern string	LLgenid;	/* LLgen identification string */ | ||||
| extern t_token	lextoken;	/* the current token */ | ||||
| extern int	nerrors; | ||||
| extern int	fflag;		/* Enable compiler to generate jump tables
 | ||||
| 				 * for switches? | ||||
| 				 */ | ||||
							
								
								
									
										71
									
								
								util/LLgen/src/global.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								util/LLgen/src/global.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * global.c | ||||
|  * Contains declarations visible in several other source files | ||||
|  */ | ||||
| 
 | ||||
| # include "types.h" | ||||
| # include "io.h" | ||||
| # include "tunable.h" | ||||
| 
 | ||||
| static string rcsid = "$Header$"; | ||||
| 
 | ||||
| char	ltext[LTEXTSZ]; | ||||
| t_entry	h_entry[NTERMINALS+NNONTERMS+1]; | ||||
| p_entry	max_t_ent; | ||||
| t_nont	nonterms[NNONTERMS+1]; | ||||
| int	nnonterms; | ||||
| int	nterminals; | ||||
| int	order[NNONTERMS+1]; | ||||
| int	*maxorder; | ||||
| p_start	start; | ||||
| int	linecount; | ||||
| int	assval; | ||||
| string	pentry[ENTSIZ]; | ||||
| FILE	*fout; | ||||
| FILE	*fpars; | ||||
| FILE	*finput; | ||||
| FILE	*fact; | ||||
| p_nont	maxnt; | ||||
| string	f_pars = PARSERFILE; | ||||
| string	f_out = OUTFILE; | ||||
| string	f_temp = ACTFILE; | ||||
| string	f_input; | ||||
| string	e_noopen = "Cannot open %s"; | ||||
| int	verbose; | ||||
| string	lexical; | ||||
| int	ntneeded; | ||||
| int	ntprint; | ||||
| # ifndef NDEBUG | ||||
| int	debug; | ||||
| # endif not NDEBUG | ||||
| p_file	files; | ||||
| p_file	pfile; | ||||
| string	LLgenid = "/* LLgen generated code from source %s */\n"; | ||||
| t_token lextoken; | ||||
| int	nerrors; | ||||
| int	fflag; | ||||
							
								
								
									
										49
									
								
								util/LLgen/src/io.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								util/LLgen/src/io.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * io.h $Header$ | ||||
|  * Some important file names and variables | ||||
|  */ | ||||
| 
 | ||||
| # include <stdio.h> | ||||
| # include <ctype.h> | ||||
| 
 | ||||
| /* FILES */ | ||||
| 
 | ||||
| # define OUTFILE	"LL.output"	/* -v option */ | ||||
| # define PARSERFILE	"LL.xxx"	/* This is what we want */ | ||||
| # define ACTFILE	"LL.temp"	/* temporary file to save actions */ | ||||
| # define HFILE		"Lpars.h"	/* file for "#define's " */ | ||||
| # define RFILE		"Lpars.c"	/* Error recovery */ | ||||
| 
 | ||||
| extern FILE *finput; | ||||
| extern FILE *fpars; | ||||
| extern FILE *fact; | ||||
| extern FILE *fout; | ||||
| extern string	f_pars; | ||||
| extern string	f_temp; | ||||
| extern string	f_out; | ||||
| extern string	f_input; | ||||
							
								
								
									
										58
									
								
								util/LLgen/src/machdep.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								util/LLgen/src/machdep.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * machdep.c | ||||
|  * Machine dependant things | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| # include "types.h" | ||||
| 
 | ||||
| static string rcsid = "$Header$"; | ||||
| 
 | ||||
| /* In this file the following routines are defined: */ | ||||
| extern	UNLINK(); | ||||
| extern	RENAME(); | ||||
| extern string	libpath(); | ||||
| 
 | ||||
| UNLINK(x) string x; { | ||||
| 	unlink(x);	/* systemcall to remove file */ | ||||
| } | ||||
| 
 | ||||
| RENAME(x,y) string x,y; { | ||||
| 	unlink(y); | ||||
| 	if(link(x,y)!=0)fatal(1,"Cannot link to %s",y); | ||||
| 	unlink(x); | ||||
| } | ||||
| 
 | ||||
| string | ||||
| libpath(s) char *s; { | ||||
| 	static char buf[100]; | ||||
| 
 | ||||
| 	strcpy(buf,"/usr/local/lib/LLgen/"); | ||||
| 	strcat(buf,s); | ||||
| 	return buf; | ||||
| } | ||||
							
								
								
									
										333
									
								
								util/LLgen/src/main.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										333
									
								
								util/LLgen/src/main.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,333 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * main.c | ||||
|  * Contains main program, and some error message routines | ||||
|  */ | ||||
| 
 | ||||
| # include "types.h" | ||||
| # include "io.h" | ||||
| # include "extern.h" | ||||
| # include "sets.h" | ||||
| # include "assert.h" | ||||
| 
 | ||||
| static string rcsid = "$Header$"; | ||||
| 
 | ||||
| static string	rec_file; | ||||
| static string	incl_file; | ||||
| 
 | ||||
| /* In this file the following routines are defined: */ | ||||
| extern int	main(); | ||||
| STATIC		readgrammar(); | ||||
| extern		error(); | ||||
| extern		fatal(); | ||||
| extern		comfatal(); | ||||
| extern		copyfile(); | ||||
| extern		install(); | ||||
| # ifndef NDEBUG | ||||
| extern		badassertion(); | ||||
| # endif not NDEBUG | ||||
| 
 | ||||
| main(argc,argv) register string	argv[]; { | ||||
| 	register string arg; | ||||
| 	string libpath(); | ||||
| 	int nflag = 0; | ||||
| 
 | ||||
| 	/* Initialize */ | ||||
| 
 | ||||
| 	maxorder = order; | ||||
| 	assval = 0400; | ||||
| 	/* read options */ | ||||
| 	 | ||||
| 	while (argc >= 2 && (arg = argv[1], *arg == '-')) { | ||||
| 		while (*++arg) { | ||||
| 			switch(*arg) { | ||||
| 			  case 'v': | ||||
| 			  case 'V': | ||||
| 				verbose++; | ||||
| 				continue; | ||||
| 			  case 'n': | ||||
| 			  case 'N': | ||||
| 				nflag++; | ||||
| 				continue; | ||||
| 			  case 'f': | ||||
| 			  case 'F': | ||||
| 			  	fflag++; | ||||
| 				continue; | ||||
| # ifndef NDEBUG | ||||
| 			  case 'a': | ||||
| 			  case 'A': | ||||
| 				debug++; | ||||
| 				continue; | ||||
| # endif not NDEBUG | ||||
| 			  case 'r': | ||||
| 			  case 'R': | ||||
| 				if (rec_file) { | ||||
| 					fprintf(stderr,"duplicate -r flag\n"); | ||||
| 					exit(1); | ||||
| 				} | ||||
| 			  	rec_file = ++arg; | ||||
| 				break; | ||||
| 			  case 'i': | ||||
| 			  case 'I': | ||||
| 				if (incl_file) { | ||||
| 					fprintf(stderr,"duplicate -i flag\n"); | ||||
| 					exit(1); | ||||
| 				} | ||||
| 			  	incl_file = ++arg; | ||||
| 				break; | ||||
| 			  case 'x': | ||||
| 			  case 'X': | ||||
| 				ntneeded = 1; | ||||
| 				ntprint = 1; | ||||
| 				continue; | ||||
| 			  default: | ||||
| 				fprintf(stderr,"illegal option : %c\n",*arg); | ||||
| 				return 1; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 		argv++; | ||||
| 		argc--; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Now check wether the sets should include nonterminals | ||||
| 	 */ | ||||
| 	if (verbose == 2) ntneeded = 1; | ||||
| 	else if (! verbose) ntneeded = 0; | ||||
| 	/*
 | ||||
| 	 * Initialise | ||||
| 	 */ | ||||
| 	 if (!rec_file) rec_file = libpath("rec"); | ||||
| 	 if (!incl_file) incl_file = libpath("incl"); | ||||
| 	if ((fact = fopen(f_temp,"w")) == NULL) { | ||||
| 		fputs("Cannot create temporary\n",stderr); | ||||
| 		return 1; | ||||
| 	} | ||||
| 	name_init(); | ||||
| 	readgrammar(argc,argv); | ||||
| 	if (nflag) comfatal(); | ||||
| 	setinit(ntneeded); | ||||
| 	maxnt = &nonterms[nnonterms]; | ||||
| 	max_t_ent = &h_entry[nterminals]; | ||||
| 	fclose(fact); | ||||
| 	/*
 | ||||
| 	 * Now, the grammar is read. Do some computations | ||||
| 	 */ | ||||
| 	co_reach();		/* Check for undefined and unreachable */ | ||||
| 	if (nerrors) comfatal(); | ||||
| 	createsets(); | ||||
| 	co_empty();		/* Which nonterminals produce empty? */ | ||||
| 	co_first();		/* Computes first sets */ | ||||
| 	co_follow();		/* Computes follow sets */ | ||||
| 	co_symb();		/* Computes choice sets in alternations */ | ||||
| 	conflchecks();		/* Checks for conflicts etc, and also
 | ||||
| 				 * takes care of LL.output etc | ||||
| 				 */ | ||||
| 	if (nerrors) comfatal(); | ||||
| 	co_contains();		/* Computes the contains sets */ | ||||
| 	co_safes();		/* Computes safe terms and nonterminals.
 | ||||
| 				 * Safe means : always called with a terminal | ||||
| 				 * symbol that is guarantied to be eaten by | ||||
| 				 * the term | ||||
| 				 */ | ||||
| 	if (argc-- == 1) { | ||||
| 		fputs("No code generation for input from standard input\n",stderr); | ||||
| 	} else	gencode(argc); | ||||
| 	UNLINK(f_temp); | ||||
| 	UNLINK(f_pars); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| STATIC | ||||
| readgrammar(argc,argv) char *argv[]; { | ||||
| 	/*
 | ||||
| 	 * Do just what the name suggests : read the grammar | ||||
| 	 */ | ||||
| 	register p_file	p; | ||||
| 	p_mem		alloc(); | ||||
| 
 | ||||
| 	linecount = 0; | ||||
| 	f_input = "no filename"; | ||||
| 	/*
 | ||||
| 	 * Build the file structure | ||||
| 	 */ | ||||
| 	files = p = (p_file) alloc((unsigned) (argc+1) * sizeof(t_file)); | ||||
| 	if (argc-- == 1) { | ||||
| 		finput = stdin; | ||||
| 		p->f_name = f_input = "standard input"; | ||||
| 		p->f_firsts = 0; | ||||
| 		p->f_start = maxorder; | ||||
| 		pfile = p; | ||||
| 		LLparse(); | ||||
| 		p->f_end = maxorder - 1;		 | ||||
| 		p++; | ||||
| 	} else { | ||||
| 		while (argc--) { | ||||
| 			if ((finput = fopen(f_input=argv[1],"r")) == NULL) { | ||||
| 				fatal(0,e_noopen,f_input); | ||||
| 			} | ||||
| 			linecount = 0; | ||||
| 			p->f_name = f_input; | ||||
| 			p->f_start = maxorder; | ||||
| 			p->f_firsts = 0; | ||||
| 			pfile = p; | ||||
| 			LLparse(); | ||||
| 			p->f_end = maxorder-1; | ||||
| 			p++; | ||||
| 			argv++; | ||||
| 			fclose(finput); | ||||
| 		} | ||||
| 	} | ||||
| 	p->f_start = maxorder+1; | ||||
| 	p->f_end = maxorder; | ||||
| 	if (! lexical) lexical = "yylex"; | ||||
| 	/*
 | ||||
| 	 * There must be a start symbol! | ||||
| 	 */ | ||||
| 	if (start == 0) { | ||||
| 		fatal(linecount,"Missing %%start"); | ||||
| 	} | ||||
| 	if (nerrors) comfatal(); | ||||
| } | ||||
| 
 | ||||
| /* VARARGS1 */ | ||||
| error(lineno,s,t,u) string	s,t,u; {	 | ||||
| 	/*
 | ||||
| 	 * Just an error message | ||||
| 	 */ | ||||
| 	register FILE *f; | ||||
| 
 | ||||
| 	f = stderr; | ||||
| 	++nerrors; | ||||
| 	if (lineno) fprintf(f,"\"%s\", line %d : ",f_input,lineno); | ||||
| 	else fprintf(f,"\"%s\" : ",f_input); | ||||
| 	fprintf(f,s,t,u); | ||||
| 	putc('\n',f); | ||||
| } | ||||
| 
 | ||||
| /* VARARGS1 */ | ||||
| fatal(lineno,s,t,u) string	s,t,u; { | ||||
| 	/*
 | ||||
| 	 * Fatal error | ||||
| 	 */ | ||||
| 	error(lineno,s,t,u); | ||||
| 	comfatal(); | ||||
| } | ||||
| 
 | ||||
| comfatal() { | ||||
| 	/*
 | ||||
| 	 * Some common code for exit on errors | ||||
| 	 */ | ||||
| 	if (fact != NULL) { | ||||
| 		fclose(fact); | ||||
| 		UNLINK(f_temp); | ||||
| 	} | ||||
| 	if (fpars != NULL) fclose(fpars); | ||||
| 	UNLINK(f_pars); | ||||
| 	exit(1); | ||||
| } | ||||
| 
 | ||||
| copyfile(n) { | ||||
| 	/*
 | ||||
| 	 * Copies a file indicated by the parameter to filedescriptor fpars. | ||||
| 	 * If n != 0, the error recovery routines are copied, | ||||
| 	 * otherwise a standard header is. | ||||
| 	 */ | ||||
| 	register	c; | ||||
| 	register FILE	*f; | ||||
| 
 | ||||
| 	if ((f = fopen(n?rec_file:incl_file,"r")) == NULL) { | ||||
| 		fatal(0,"Cannot open libraryfile, call an expert"); | ||||
| 	} | ||||
| 	while ((c = getc(f)) != EOF) putc(c,fpars); | ||||
| } | ||||
| 
 | ||||
| install(target, source) string target, source; { | ||||
| 	/*
 | ||||
| 	 * Copy the temporary file generated from source to target | ||||
| 	 * if allowed (which means that the target must be generated | ||||
| 	 * by LLgen from the source, or that the target is not present | ||||
| 	 */ | ||||
| 	register	c; | ||||
| 	register FILE	*f1; | ||||
| 	register FILE	*f2; | ||||
| 	register string	s1; | ||||
| 	register int	i; | ||||
| 	char		buf[100]; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * First open temporary, generated for source | ||||
| 	 */ | ||||
| 	if ((f1 = fopen(f_pars,"r")) == NULL) { | ||||
| 		fatal(0,e_noopen,f_pars); | ||||
| 	} | ||||
| 	i = 0; | ||||
| 	/*
 | ||||
| 	 * Now open target for reading | ||||
| 	 */ | ||||
| 	if ((f2 = fopen(target,"r")) == NULL) { | ||||
| 		i = 1; | ||||
| 		fclose(f1); | ||||
| 	} | ||||
| 	else { | ||||
| 		/*
 | ||||
| 		 * Create string recognised by LLgen. The target must | ||||
| 		 * start with that! | ||||
| 		 */ | ||||
| 		(int) sprintf(buf,LLgenid,source ? source : "."); | ||||
| 		s1 = buf; | ||||
| 		while (*s1 != '\0' && *s1++ == getc(f2)) { /* nothing */ } | ||||
| 		/*
 | ||||
| 		 * Ai,ai, it did not | ||||
| 		 */ | ||||
| 		if (*s1 != '\0') { | ||||
| 			fatal(0,"%s : not a file generated by LLgen",target); | ||||
| 		} | ||||
| 		rewind(f2); | ||||
| 		/*
 | ||||
| 		 * Now compare the target with the temporary | ||||
| 		 */ | ||||
| 		while ((c = getc(f1)) != EOF && c == getc(f2)) { /* nothing */} | ||||
| 		if (c != EOF || getc(f2) != EOF) i = 1; | ||||
| 		fclose(f1); | ||||
| 		fclose(f2); | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Here, if i != 0 the target must be recreated | ||||
| 	 */ | ||||
| 	if (i) RENAME(f_pars,target); | ||||
| } | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| badassertion(asstr,file,line) char *asstr, *file; { | ||||
| 
 | ||||
| 	fprintf(stderr,"Assertion \"%s\" failed %s(%d)\n",asstr,file,line); | ||||
| 	if (fact != NULL) fclose(fact); | ||||
| 	if (fpars != NULL) fclose(fpars); | ||||
| 	abort(); | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										239
									
								
								util/LLgen/src/name.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								util/LLgen/src/name.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,239 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * name.c | ||||
|  * Defines the symboltable search routine and an initialising routine | ||||
|  */ | ||||
| 
 | ||||
| # include "types.h" | ||||
| # include "tunable.h" | ||||
| # include "extern.h" | ||||
| # include "assert.h" | ||||
| # include "io.h" | ||||
| 
 | ||||
| static string rcsid = "$Header$"; | ||||
| 
 | ||||
| # define HASHSIZE 128 | ||||
| 
 | ||||
| static char	name[NAMESZ];			/* space for names */ | ||||
| static int	iname;				/* index in nametable */ | ||||
| static p_entry	h_root[HASHSIZE];		/* hash table */ | ||||
| static string	e_literal = "Illegal literal"; | ||||
| 
 | ||||
| /* Defined in this file are: */ | ||||
| extern string	store(); | ||||
| extern		name_init(); | ||||
| STATIC int	hash(); | ||||
| extern t_gram	search(); | ||||
| 
 | ||||
| string	 | ||||
| store(s) register string s; { | ||||
| 	/*
 | ||||
| 	 * Store a string s in the name table | ||||
| 	 */ | ||||
| 	register string	t,u; | ||||
| 
 | ||||
| 	u = t = &name[iname]; | ||||
| 	do {	if (u > &name[NAMESZ-1]) fatal(linecount,"name table overflow"); | ||||
| 		else *u++ = *s; | ||||
| 	} while (*s++); | ||||
| 	iname = u - name; | ||||
| 	return t; | ||||
| } | ||||
| 
 | ||||
| name_init() { | ||||
| 	/*
 | ||||
| 	 * Initialise hash-table and enter special terminal EOFILE | ||||
| 	 */ | ||||
| 	register p_entry	*p; | ||||
| 	t_gram			search(); | ||||
| 
 | ||||
| 	for(p = h_root; p<= &h_root[HASHSIZE-1]; p++) *p = 0; | ||||
| 	search(TERMINAL,"EOFILE",ENTERING); | ||||
| } | ||||
| 
 | ||||
| STATIC int | ||||
| hash(str) string str; { | ||||
| 	/*
 | ||||
| 	 * Compute the hash for string str | ||||
| 	 */ | ||||
| 	register	i; | ||||
| 	register string l; | ||||
| 
 | ||||
| 	l = str; | ||||
| 	i = 0; | ||||
| 	while (*l != '\0') i += *l++ & 0377; | ||||
| 	i += l - str; | ||||
| 	return i % HASHSIZE; | ||||
| } | ||||
| 
 | ||||
| t_gram | ||||
| search(type,str,option) register string str; { | ||||
| 	/*
 | ||||
| 	 * Search for object str. | ||||
| 	 * It has type UNKNOWN, LITERAL, TERMINAL or NONTERM. | ||||
| 	 * option can be ENTERING, JUSTLOOKING or BOTH. | ||||
| 	 */ | ||||
| 	register int		val; | ||||
| 	register p_entry	p; | ||||
| 	t_gram			r; | ||||
| 	register int		i; | ||||
| 
 | ||||
| 	g_init(&r); | ||||
| 	g_setcont(&r,UNDEFINED); | ||||
| 	r.g_lineno = linecount; | ||||
| 	i = hash(str); | ||||
| 	/*
 | ||||
| 	 * Walk hash chain | ||||
| 	 */ | ||||
| 	for (p = h_root[i]; p != (p_entry) 0; p = p->h_next) { | ||||
| 		if(!strcmp(p->h_name,str)) { | ||||
| 			val = p - h_entry; | ||||
| 			if (type == LITERAL && | ||||
| 			    (val >= NTERMINALS || p->h_num >= 0400)) continue; | ||||
| 			if (val>=NTERMINALS) { | ||||
| 				/* Should be a nonterminal */ | ||||
| 				if (type == TERMINAL) { | ||||
| 					error(linecount, | ||||
| 						"%s : terminal expected", | ||||
| 						str); | ||||
| 				} | ||||
| 				g_settype(&r,NONTERM); | ||||
| 				g_setnont(&r,val - NTERMINALS); | ||||
| 			} else { | ||||
| 				if (type != LITERAL && p->h_num < 0400) { | ||||
| 					continue; | ||||
| 				} | ||||
| 				if (type == NONTERM) { | ||||
| 					error(linecount, | ||||
| 						"%s : nonterminal expected", | ||||
| 						str); | ||||
| 					continue; | ||||
| 				} | ||||
| 				g_setnont(&r, val); | ||||
| 				g_settype(&r, TERMINAL); | ||||
| 			} | ||||
| 			if (option==ENTERING)  { | ||||
| 				error(linecount, | ||||
| 					"%s : already defined",str); | ||||
| 			} | ||||
| 			return r; | ||||
| 		} | ||||
| 	} | ||||
| 	if (option == JUSTLOOKING) return r; | ||||
| 	if (type == TERMINAL || type == LITERAL) { | ||||
| 		if (nterminals == NTERMINALS) { | ||||
| 			fatal(linecount,"too many terminals"); | ||||
| 		} | ||||
| 		p = &h_entry[nterminals]; | ||||
| 	} else { | ||||
| 		/*
 | ||||
| 		 * type == NONTERM || type == UNKNOWN  | ||||
| 		 * UNKNOWN and not yet declared means : NONTERM | ||||
| 		 */ | ||||
| 		if (nnonterms == NNONTERMS) { | ||||
| 			fatal(linecount,"too many nonterminals"); | ||||
| 		} | ||||
| 		p = &h_entry[NTERMINALS+nnonterms]; | ||||
| 	} | ||||
| 	p->h_name = store(str); | ||||
| 	p->h_next = h_root[i]; | ||||
| 	h_root[i] = p; | ||||
| 	if (type == NONTERM || type == UNKNOWN) { | ||||
| 		register p_nont q; | ||||
| 
 | ||||
| 		q = &nonterms[nnonterms]; | ||||
| 		q->n_rule = 0; | ||||
| 		q->n_string = f_input; | ||||
| 		q->n_follow = 0; | ||||
| 		q->n_flags = 0; | ||||
| 		q->n_contains = 0; | ||||
| 		p->h_num = 0; | ||||
| 		g_settype(&r, NONTERM); | ||||
| 		g_setnont(&r, nnonterms); | ||||
| 		nnonterms++; | ||||
| 		return r; | ||||
| 	} | ||||
| 	if (type == LITERAL) { | ||||
| 		if (str[0] == '\\') { | ||||
| 			/*
 | ||||
| 			 * Handle escapes in literals | ||||
| 			 */ | ||||
| 			if (str[2] == '\0') { | ||||
| 				switch(str[1]) { | ||||
| 				  case 'n' : | ||||
| 				  	val = '\n'; | ||||
| 					break; | ||||
| 				  case 'r' : | ||||
| 					val = '\r'; | ||||
| 					break; | ||||
| 				  case 'b' : | ||||
| 					val = '\b'; | ||||
| 					break; | ||||
| 				  case 'f' : | ||||
| 				 	val = '\f'; | ||||
| 					break; | ||||
| 				  case 't' : | ||||
| 				  	val = '\t'; | ||||
| 					break; | ||||
| 				  case '\'': | ||||
| 				  	val = '\''; | ||||
| 					break; | ||||
| 				  case '\\': | ||||
| 				  	val = '\\'; | ||||
| 					break; | ||||
| 				  default  : | ||||
| 				  	error(linecount,e_literal); | ||||
| 				} | ||||
| 			} else { | ||||
| 				/*
 | ||||
| 				 * Here, str[2] != '\0' | ||||
| 				 */ | ||||
| 				if (str[1] > '3' || str[1] < '0' || | ||||
| 				    str[2] > '7' || str[2] < '0' || | ||||
| 				    str[3] > '7' || str[3] < '0' || | ||||
| 				    str[4] != '\0') error(linecount,e_literal); | ||||
| 				val = 64*str[1] - 73*'0' + 8*str[2] + str[3]; | ||||
| 			} | ||||
| 		} else {  | ||||
| 			/*
 | ||||
| 			 * No escape in literal | ||||
| 			 */ | ||||
| 			if (str[1] == '\0') val = str[0]; | ||||
| 			else error(linecount,e_literal); | ||||
| 		} | ||||
| 		p->h_num = val; | ||||
| 	} else { | ||||
| 		/*
 | ||||
| 		 * Here, type = TERMINAL | ||||
| 		 */ | ||||
| 		p->h_num = assval++; | ||||
| 	} | ||||
| 	g_settype(&r, TERMINAL); | ||||
| 	g_setnont(&r, nterminals); | ||||
| 	nterminals++; | ||||
| 	return r; | ||||
| } | ||||
							
								
								
									
										121
									
								
								util/LLgen/src/reach.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								util/LLgen/src/reach.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,121 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * reach.c | ||||
|  * Determine which nonterminals are reachable, and also check that they | ||||
|  * are all defined. | ||||
|  */ | ||||
| 
 | ||||
| # include "tunable.h" | ||||
| # include "types.h" | ||||
| # include "extern.h" | ||||
| # include "io.h" | ||||
| # include "assert.h" | ||||
| 
 | ||||
| static string rcsid = "$Header$"; | ||||
| 
 | ||||
| /* In this file the following routines are defined: */ | ||||
| extern co_reach(); | ||||
| STATIC reachable(); | ||||
| STATIC reachwalk(); | ||||
| 
 | ||||
| co_reach() { | ||||
| 	/*
 | ||||
| 	 * Check for undefined or unreachable nonterminals. | ||||
| 	 * An undefined nonterminal is a fatal error! | ||||
| 	 */ | ||||
| 	register p_nont		p; | ||||
| 	register p_start	st; | ||||
| 	register p_file		x = files; | ||||
| 	register int		*s; | ||||
| 
 | ||||
| 	/* Check for undefined nonterminals */ | ||||
| 	for (p = nonterms; p < maxnt; p++) { | ||||
| 		if (! p->n_rule) { | ||||
| 			f_input = p->n_string; | ||||
| 			fatal(p->n_lineno,"nonterminal %s not defined", | ||||
| 				(min_nt_ent + (p - nonterms))->h_name); | ||||
| 		} | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Walk the grammar rules, starting with the startsymbols | ||||
| 	 * Mark the nonterminals that are encountered with the flag | ||||
| 	 * REACHABLE, and walk their rules, if not done before | ||||
| 	 */ | ||||
| 	for (st = start; st; st = st->ff_next) reachable(st->ff_nont); | ||||
| 	/*
 | ||||
| 	 * Now check for unreachable nonterminals | ||||
| 	 */ | ||||
| 	for (; x->f_end < maxorder; x++) { | ||||
| 	    f_input = x->f_name; | ||||
| 	    for (s = x->f_start; s <= x->f_end; s++) { | ||||
| 		p = &nonterms[*s]; | ||||
| 		if (! (p->n_flags & REACHABLE)) { | ||||
| 			error(p->n_lineno,"nonterminal %s unreachable", | ||||
| 				(min_nt_ent + (p - nonterms))->h_name); | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| STATIC | ||||
| reachable(p) register p_nont p; { | ||||
| 	/*
 | ||||
| 	 * Enter the fact that p is reachable, and look for implications | ||||
| 	 */ | ||||
| 	if (! (p->n_flags & REACHABLE)) { | ||||
| 		p->n_flags |= REACHABLE; | ||||
| 		/*
 | ||||
| 		 * Now walk its grammar rule | ||||
| 		 */ | ||||
| 		reachwalk(p->n_rule); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| STATIC | ||||
| reachwalk(p) register p_gram p; { | ||||
| 	/*
 | ||||
| 	 * Walk through rule p, looking for nonterminals. | ||||
| 	 * The nonterminals found are entered as reachable | ||||
| 	 */ | ||||
| 
 | ||||
| 	for (;;) { | ||||
| 		switch(g_gettype(p)) { | ||||
| 		  case ALTERNATION : | ||||
| 			reachwalk(((p_link) pentry[g_getcont(p)])->l_rule); | ||||
| 			break; | ||||
| 		  case TERM : | ||||
| 			reachwalk(((p_term) pentry[g_getcont(p)])->t_rule); | ||||
| 			break; | ||||
| 		  case NONTERM : | ||||
| 			reachable(&nonterms[g_getnont(p)]); | ||||
| 			break; | ||||
| 		  case EORULE : | ||||
| 			return; | ||||
| 		} | ||||
| 		p++; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										45
									
								
								util/LLgen/src/sets.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								util/LLgen/src/sets.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * sets.h $Header$ | ||||
|  * Some macros that deal with bitsets and their size | ||||
|  */ | ||||
| 
 | ||||
| # define BITS		(8 * sizeof (int)) | ||||
| # define IN(a,i)	((a)[(i)/BITS] & (1<<((i) % BITS))) | ||||
| # define NTIN(a,i)	((a)[((i)+tbitset)/BITS]&(1<<((i)%BITS))) | ||||
| # define PUTIN(a,i)	((a)[(i)/BITS] |=(1<<((i) % BITS))) | ||||
| # define NTPUTIN(a,i)	((a)[((i)+tbitset)/BITS]|=(1<<((i)%BITS))) | ||||
| # define NBYTES(n)	(((n) + 7) / 8) | ||||
| /*
 | ||||
|  * The next two macros operate on byte counts! | ||||
|  */ | ||||
| # define NINTS(n)	(((n) + (int) (sizeof(int) - 1)) / (int) sizeof(int)) | ||||
| # define ALIGN(n)	(NINTS(n) * (int) sizeof (int)) | ||||
| 
 | ||||
| extern int	tbitset; | ||||
| extern p_set	*setptr,*maxptr,*topptr; | ||||
| extern int	tsetsize,setsize; | ||||
							
								
								
									
										435
									
								
								util/LLgen/src/tokens.g
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										435
									
								
								util/LLgen/src/tokens.g
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,435 @@ | |||
| /* | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /* | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /* | ||||
|  * tokens.g | ||||
|  * Defines the tokens for the grammar of LLgen. | ||||
|  * The lexical analyser and LLmes are also included here.  | ||||
|  */ | ||||
| 
 | ||||
| { | ||||
| # include "types.h" | ||||
| # include "io.h" | ||||
| # include "tunable.h" | ||||
| # include "extern.h" | ||||
| # include "assert.h" | ||||
| 
 | ||||
| static string	rcsid = "$Header$"; | ||||
| 
 | ||||
| /* Here are defined : */ | ||||
| extern int	scanner(); | ||||
| extern 		LLmessage(); | ||||
| extern int	input(); | ||||
| extern		unput(); | ||||
| extern		skipcomment(); | ||||
| STATIC		linedirective(); | ||||
| STATIC string	cpy(); | ||||
| STATIC string	vallookup(); | ||||
| } | ||||
| 
 | ||||
| /* Classes */ | ||||
| 
 | ||||
| %token  C_IDENT ;	/* lextoken.t_string contains the identifier read */ | ||||
| %token	C_NUMBER ;	/* lextoken.t_num contains the number read */ | ||||
| %token	C_LITERAL ;	/* lextoken.t_string contains the literal read */ | ||||
| 
 | ||||
| /* Keywords */ | ||||
| 
 | ||||
| %token	C_TOKEN ; | ||||
| %token	C_START ; | ||||
| %token	C_IF ; | ||||
| %token	C_WHILE ; | ||||
| %token	C_PERSISTENT ; | ||||
| %token	C_FIRST ; | ||||
| %token	C_LEXICAL ; | ||||
| %token	C_AVOID ; | ||||
| %token	C_PREFER ; | ||||
| %token	C_DEFAULT ; | ||||
| 
 | ||||
| %lexical scanner ; | ||||
| 
 | ||||
| { | ||||
| 
 | ||||
| /* | ||||
|  * Structure for a keyword | ||||
|  */ | ||||
| 
 | ||||
| struct keyword { | ||||
| 	string	w_word; | ||||
| 	int	w_value; | ||||
| }; | ||||
| 
 | ||||
| /* | ||||
|  * The list of keywords, the most often used keywords come first. | ||||
|  * Linear search is used, as there are not many keywords | ||||
|  */ | ||||
| 
 | ||||
| static struct keyword resword[] = { | ||||
| 	{ "token",	C_TOKEN	}, | ||||
| 	{ "avoid",	C_AVOID	}, | ||||
| 	{ "prefer",	C_PREFER	}, | ||||
| 	{ "persistent", C_PERSISTENT	}, | ||||
| 	{ "default",	C_DEFAULT	}, | ||||
| 	{ "if",		C_IF	}, | ||||
| 	{ "while",	C_WHILE	}, | ||||
| 	{ "first",	C_FIRST	}, | ||||
| 	{ "start",	C_START	}, | ||||
| 	{ "lexical",	C_LEXICAL	}, | ||||
| 	{ 0,		0	} | ||||
| }; | ||||
| 
 | ||||
| static t_token	savedtok;	/* to save lextoken in case of an insertion */ | ||||
| static  int	nostartline;	/* = 0 if at the start of a line */ | ||||
| 
 | ||||
| scanner() { | ||||
| 	/* | ||||
| 	 * Lexical analyser, what else | ||||
| 	 */ | ||||
| 	register	ch;		/* Current char */ | ||||
| 	register	i; | ||||
| 	register	reserved = 0;	/* reserved word? */ | ||||
| 	int		last;		/* Char before current char */ | ||||
| 
 | ||||
| 	if (savedtok.t_tokno) {	/* | ||||
| 				 * A token has been inserted. | ||||
| 				 * Now deliver the last lextoken again | ||||
| 				 */ | ||||
| 		lextoken = savedtok; | ||||
| 		savedtok.t_tokno = 0; | ||||
| 		return lextoken.t_tokno; | ||||
| 	} | ||||
| 	for (;;) {	/* | ||||
| 			 * First, skip space, comments, line directives, etc | ||||
| 			 */ | ||||
| 		do	ch = input(); | ||||
| 		while(isspace(ch)); | ||||
| 		if (ch == '/') skipcomment(0); | ||||
| 		else if (ch == '#' && !nostartline) linedirective(); | ||||
| 		else break; | ||||
| 	} | ||||
| 	/* | ||||
| 	 * Now we have a first character of a token | ||||
| 	 */ | ||||
| 	switch(ch) { | ||||
| 	  case EOF : | ||||
| 	 	 return EOF; | ||||
| 	  case '\'':	/* | ||||
| 			 * Literal, put it in ltext | ||||
| 			 */ | ||||
| 		i = 0; | ||||
| 		for (;;) { | ||||
| 			last = ch; | ||||
| 			ch = input(); | ||||
| 			if (ch == '\n' || ch == EOF) { | ||||
| 				error(linecount,"missing '"); | ||||
| 				break; | ||||
| 			} | ||||
| 			if (ch == '\'' && last != '\\') break; | ||||
| 			ltext[i] = ch; | ||||
| 			if (i < LTEXTSZ - 1) ++i; | ||||
| 		} | ||||
| 		ltext[i] = '\0'; | ||||
| 		lextoken.t_string = ltext; | ||||
| 		return C_LITERAL; | ||||
| 	  case '%' :	/* | ||||
| 			 * Start of a reserved word | ||||
| 			 */ | ||||
| 		reserved = 1; | ||||
| 		ch = input(); | ||||
| 		/* Fall through */ | ||||
| 	  default  : | ||||
| 		i = 0; | ||||
| 		if (isdigit(ch)) { | ||||
| 			if (reserved) { | ||||
| 				error(linecount," A reserved number ?"); | ||||
| 			} | ||||
| 			while (isdigit(ch)) { | ||||
| 				i = 10 * i + (ch - '0'); | ||||
| 				ch= input(); | ||||
| 			} | ||||
| 			lextoken.t_num = i; | ||||
| 			unput(ch); | ||||
| 			return C_NUMBER; | ||||
| 		} | ||||
| 		if (isalpha(ch) || ch == '_') { | ||||
| 			do { | ||||
| 				if (reserved && isupper(ch)) ch += 'a' - 'A'; | ||||
| 				ltext[i] = ch; | ||||
| 				if (i < LTEXTSZ - 1) ++i; | ||||
| 				ch = input(); | ||||
| 			} while (isalnum(ch) || ch == '_'); | ||||
| 		} else	return ch; | ||||
| 		unput(ch); | ||||
| 	} | ||||
| 	ltext[i] = '\0'; | ||||
| 	if (reserved) {	/* | ||||
| 			 * Now search for the keyword | ||||
| 			 */ | ||||
| 		register struct keyword *w; | ||||
| 
 | ||||
| 		w = resword; | ||||
| 		while (w->w_word) { | ||||
| 			if (! strcmp(ltext,w->w_word)) { | ||||
| 				/* | ||||
| 				 * Found it. Return token number. | ||||
| 				 */ | ||||
| 				return w->w_value; | ||||
| 			} | ||||
| 			w++; | ||||
| 		} | ||||
| 		error(linecount,"illegal reserved word"); | ||||
| 	} | ||||
| 	lextoken.t_string = ltext; | ||||
| 	return C_IDENT; | ||||
| } | ||||
| 
 | ||||
| static int	backupc;	/* for unput() */ | ||||
| static int	nonline;	/* = 1 if last char read was a newline */ | ||||
| 
 | ||||
| input() { | ||||
| 	/* | ||||
| 	 * Low level input routine, used by all other input routines | ||||
| 	 */ | ||||
| 	register	c; | ||||
| 	register FILE	*f; | ||||
| 
 | ||||
|         if(backupc) {	/* | ||||
| 			 * Last char was "unput()". Deliver it again | ||||
| 			 */ | ||||
| 		c = backupc; | ||||
| 		backupc = 0; | ||||
|                 return c; | ||||
| 	} | ||||
| 	f = finput; | ||||
| 	if ((c = getc(f)) == EOF) return c; | ||||
| 	nostartline = 1; | ||||
| 	if (!nonline) { | ||||
| 		linecount++; | ||||
| 		nostartline = 0; | ||||
| 		nonline = 1; | ||||
| 	} | ||||
| 	if (c == ' ' || c == '\t') {	/* | ||||
| 					 * Deliver space, but only once | ||||
| 					 */ | ||||
| 		do	c = getc(f); | ||||
| 		while (c == ' ' || c == '\t'); | ||||
| 		ungetc(c,f); | ||||
| 		return ' '; | ||||
| 	} | ||||
| 	if (c == '\n') nonline = 0; | ||||
| 	return c; | ||||
| } | ||||
| 
 | ||||
| unput(c) { | ||||
| 	/* | ||||
| 	 * "unread" c | ||||
| 	 */ | ||||
| 	backupc = c; | ||||
| } | ||||
| 
 | ||||
| skipcomment(flag) { | ||||
| 	/* | ||||
| 	 * Skip comment. If flag != 0, the comment is inside a fragment | ||||
| 	 * of C-code, so the newlines in it must be copied to enable the | ||||
| 	 * C-compiler to keep a correct line count | ||||
| 	 */ | ||||
| 	register	ch; | ||||
| 	int		saved;	/* line count on which comment starts */ | ||||
| 
 | ||||
| 	saved = linecount; | ||||
| 	if (input() != '*') error(linecount,"illegal comment"); | ||||
| 	ch = input(); | ||||
| 	while (ch != EOF) { | ||||
| 		if (flag && ch == '\n') putc(ch,fact); | ||||
| 		while (ch == '*') { | ||||
| 			if ((ch = input()) == '/') return; | ||||
| 			if (flag && ch == '\n') putc(ch,fact); | ||||
| 		} | ||||
| 		ch = input(); | ||||
| 	} | ||||
| 	error(saved,"Comment does not terminate"); | ||||
| } | ||||
| 
 | ||||
| STATIC | ||||
| linedirective() { | ||||
| 	/* | ||||
| 	 * Read a line directive | ||||
| 	 */ | ||||
| 	register	ch; | ||||
| 	register	i; | ||||
| 	string		s_error = "Illegal line directive"; | ||||
| 	string		store(); | ||||
| 	register string	c; | ||||
| 
 | ||||
| 	do {	/* | ||||
| 		 * Skip to next digit | ||||
| 		 * Do not skip newlines | ||||
| 		 */ | ||||
| 		ch = input(); | ||||
| 	} while (ch != '\n' && ! isdigit(ch)); | ||||
| 	if (ch == '\n') { | ||||
| 		error(linecount,s_error); | ||||
| 		return; | ||||
| 	} | ||||
| 	i = ch - '0'; | ||||
| 	ch = input(); | ||||
| 	while (isdigit(ch)) { | ||||
| 		i = i*10 + (ch - '0'); | ||||
| 		ch = input(); | ||||
| 	} | ||||
| 	while (ch != '\n' && ch != '"') ch = input(); | ||||
| 	if (ch == '"') { | ||||
| 		c = ltext; | ||||
| 		do { | ||||
| 			*c++ = ch = input(); | ||||
| 		} while (ch != '"' && ch != '\n'); | ||||
| 		if (ch == '\n') { | ||||
| 			error(linecount,s_error); | ||||
| 			return; | ||||
| 		} | ||||
| 		*--c = '\0'; | ||||
| 		do { | ||||
| 			ch = input(); | ||||
| 		} while (ch != '\n'); | ||||
| 		/* | ||||
| 		 * Remember the file name | ||||
| 		 */ | ||||
| 		if (strcmp(f_input,ltext)) f_input = store(ltext); | ||||
| 	} | ||||
| 	linecount = i; | ||||
| } | ||||
| 
 | ||||
| STATIC string | ||||
| vallookup(s) { | ||||
| 	/* | ||||
| 	 * Look up the keyword that has token number s | ||||
| 	 */ | ||||
| 	register struct keyword *p = resword; | ||||
| 
 | ||||
| 	while (p->w_value) { | ||||
| 		if (p->w_value == s) return p->w_word; | ||||
| 		p++; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| STATIC string | ||||
| cpy(s,p,flag) register s; register string p; { | ||||
| 	/* | ||||
| 	 * Create a piece of error message for token s and put it at p. | ||||
| 	 * flag = 0 if the token s was deleted (in which case we have | ||||
| 	 * attributes), else it was inserted | ||||
| 	 */ | ||||
| 	register string t = 0; | ||||
| 
 | ||||
| 	switch(s) { | ||||
| 	  case C_IDENT : 	 | ||||
| 		if (!flag) t = lextoken.t_string; | ||||
| 		else t = "identifier"; | ||||
| 		break; | ||||
| 	  case C_NUMBER : | ||||
| 		t = "number"; | ||||
| 		break; | ||||
| 	  case C_LITERAL : | ||||
| 		if (!flag) { | ||||
| 			*p++ = '"'; | ||||
| 			*p++ = '\''; | ||||
| 			t = lextoken.t_string; | ||||
| 			break; | ||||
| 		} | ||||
| 		t = "literal"; | ||||
| 		break; | ||||
| 	  case EOFILE : | ||||
| 		t = "endoffile"; | ||||
| 		break; | ||||
| 	} | ||||
| 	if (!t) { | ||||
| 		t = vallookup(s); | ||||
| 		if (t) { | ||||
| 			*p++ = '%'; | ||||
| 		} | ||||
| 	} | ||||
| 	if (t) {	/* | ||||
| 			 * We have a string for the token. Copy it | ||||
| 			 */ | ||||
| 		while (*t) *p++ = *t++; | ||||
| 		if (s == C_LITERAL && !flag) { | ||||
| 			*p++ = '\''; | ||||
| 			*p++ = '"'; | ||||
| 		} | ||||
| 		return p; | ||||
| 	} | ||||
| 	/* | ||||
| 	 * The token is a literal | ||||
| 	 */ | ||||
| 	*p++ = '\''; | ||||
| 	if (s >= 040 && s <= 0176) *p++ = s; | ||||
| 	else switch(s) { | ||||
| 	  case '\b' : *p++ = '\\'; *p++ = 'b'; break; | ||||
| 	  case '\f' : *p++ = '\\'; *p++ = 'f'; break; | ||||
| 	  case '\n' : *p++ = '\\'; *p++ = 'n'; break; | ||||
| 	  case '\r' : *p++ = '\\'; *p++ = 'r'; break; | ||||
| 	  case '\t' : *p++ = '\\'; *p++ = 't'; break; | ||||
| 	  default : *p++='0'+((s&0377)>>6); *p++='0'+((s>>3)&07); | ||||
| 		    *p++='0'+(s&07); | ||||
| 	} | ||||
| 	*p++ = '\''; | ||||
| 	return p; | ||||
| } | ||||
| 
 | ||||
| LLmessage(d) { | ||||
| 	/* | ||||
| 	 * d is either 0, in which case the current token has been deleted, | ||||
| 	 * or non-zero, in which case it represents a token that is inserted | ||||
| 	 * before the current token | ||||
| 	 */ | ||||
| 	register string	s,t; | ||||
| 	char		buf[128]; | ||||
| 
 | ||||
| 	nerrors++; | ||||
| 	s = buf; | ||||
| 	if (d == 0) { | ||||
| 		s = cpy(LLsymb,s,0); | ||||
| 		t = " deleted"; | ||||
| 		do *s++ = *t; while (*t++); | ||||
| 	} else { | ||||
| 		s = cpy(d,s,1); | ||||
| 		t = " inserted in front of "; | ||||
| 		do *s++ = *t++; while (*t); | ||||
| 		s = cpy(LLsymb,s,0); | ||||
| 		*s = '\0'; | ||||
| 	} | ||||
| 	error(linecount,buf); | ||||
| 	if (d) {	/* | ||||
| 			 * Save the current token and make up some | ||||
| 			 * attributes for the inserted token | ||||
| 			 */ | ||||
| 		savedtok = lextoken; | ||||
| 		if (d == C_IDENT) lextoken.t_string = "dummy_identifier"; | ||||
| 		else if (d == C_LITERAL) lextoken.t_string = "dummy_literal"; | ||||
| 		else if (d == C_NUMBER) lextoken.t_num = 1; | ||||
| 	} | ||||
| } | ||||
| } | ||||
							
								
								
									
										35
									
								
								util/LLgen/src/tunable.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								util/LLgen/src/tunable.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  *  L L G E N | ||||
|  * | ||||
|  *  An Extended LL(1) Parser Generator | ||||
|  * | ||||
|  *  Author : Ceriel J.H. Jacobs | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * tunable.h $Header$ | ||||
|  * Tunable constants | ||||
|  */ | ||||
| 
 | ||||
| # define NNONTERMS	150	/* size	of nonterminal array */ | ||||
| # define NTERMINALS	150	/* size	of terminal array */ | ||||
| # define NAMESZ		3000	/* size	of name	table */ | ||||
| # define LTEXTSZ	51	/* size	of token */ | ||||
| # define ENTSIZ		900	/* size	of entry table, max 8191 */ | ||||
		Loading…
	
	Add table
		
		Reference in a new issue