]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/CodeTools/Source/Pccts/dlg/output.c
1 /* output.c, output generator for dlg
5 * DfaStates == number of dfa nodes in automaton (just a #define)
6 * DfaState == type large enough to index every node in automaton
7 * <256 unsigned char, <65536 unsigned short, etc.
9 * Thus, the elements in each of the automaton states (st%d) are type DfaState
10 * and are size appropriately, since they must be able to index the next
13 * dfa[] == a linear array that points to all the automaton states (st%d)
14 * (dfa_base[] should be the same, but isn't right now)
16 * accepts[] == Taking a closer look at this one, it probably shouldn't be type
17 * DfaState because there is no real requirement that the number of
18 * accepts states is less than the number of dfa state. However, if
19 * the number of accept states was more than the number of DFA states
20 * then the lexical specification would be really ambiguous.
22 * Another note. Is that is should be possible to fold accepts[] and
23 * actions[] together. If this is done, I would suggest get rid of
24 * accept[] and make actions[] have an entry for each state (st%d) in
27 * dfa_base[] == starting location for each lexical mode. This should be
28 * Dfastate type (but isn't right now), since it points to the states
31 * dfa_class_no[] == indicates the number of columns each lexical mode has.
33 * b_class_no[] == pointer to the start of the translation array used to
34 * convert from input character to character class. This could cause
35 * problems if there are more than 256 classes
37 * shift%d[] == the actual translation arrays that convert the input character
38 * into the character class. These will have to change if there are
39 * more than 256 character classes.
43 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
44 * Set (PCCTS) -- PCCTS is in the public domain. An individual or
45 * company may do whatever they wish with source code distributed with
46 * PCCTS or the code generated by PCCTS, including the incorporation of
47 * PCCTS, or its output, into commerical software.
49 * We encourage users to develop software with PCCTS. However, we do ask
50 * that credit is given to us for developing PCCTS. By "credit",
51 * we mean that if you incorporate our source code into one of your
52 * programs (commercial product, research project, or otherwise) that you
53 * acknowledge this fact somewhere in the documentation, research report,
54 * etc... If you like PCCTS and have developed a nice tool with the
55 * output, please mention that you developed it using PCCTS. In
56 * addition, we ask that this header remain intact in our source code.
57 * As long as these guidelines are kept, we expect to continue enhancing
58 * this system and expect to make other tools available as they are
63 * With mods by Terence Parr; AHPCRC, University of Minnesota
80 static char *mode_name
[MAX_MODES
];
81 static int mode_number
[MAX_MODES
];
82 static int cur_mode
=0;
84 int operation_no
= 0; /* used to mark nodes so that infinite loops avoided */
85 int dfa_basep
[MAX_MODES
]; /* start of each group of states */
86 int dfa_class_nop
[MAX_MODES
]; /* number of elements in each group of states*/
88 int gen_ansi
= FALSE
; /* allows ansi code to be generated */
90 FILE *input_stream
; /* where to read description from */
91 FILE *output_stream
; /* where to put the output */
92 FILE *mode_stream
; /* where to put the mode.h stuff */
93 FILE *class_stream
; /* where to put the scan.h stuff (if gen_cpp) */
95 /* NOTE: This section is MACHINE DEPENDENT */
97 #if defined(PC) && !defined(PC32)
98 unsigned long typesize
[DIF_SIZE
] = { 0x7f, 0x7fff, 0x7ffful
, 0x7ffffffful
}; /* MR20 */
99 char t0
[] = "unsigned char";
100 char t1
[] = "unsigned short";
101 char t2
[] = "unsigned int";
102 char t3
[] = "unsigned long";
103 char *typevar
[DIF_SIZE
] = { t0
, t1
, t2
, t3
};
105 unsigned long typesize
[DIF_SIZE
] = { 0x7f, 0x7fff, 0x7ffffffful
, 0x7ffffffful
}; /* MR20 */
106 char t0
[] = "unsigned char";
107 char t1
[] = "unsigned short";
108 char t2
[] = "unsigned int";
109 char t3
[] = "unsigned long";
110 char *typevar
[DIF_SIZE
] = { t0
, t1
, t2
, t3
};
113 /* Added by TJP August 1994 */
114 /* Take in MyLexer and return MyLexer_h */
118 gate_symbol(char *name
)
124 static char buf
[100];
125 sprintf(buf
, "%s_h", name
);
129 /* Added by TJP August 1994 */
138 char *p
= (char *)malloc(strlen(s
)+1);
144 void p_class_hdr(void)
149 if ( class_stream
== NULL
) return;
150 fprintf(class_stream
, "#ifndef %s\n", gate_symbol(ClassName("")));
151 fprintf(class_stream
, "#define %s\n", gate_symbol(ClassName("")));
152 fprintf(class_stream
, "/*\n");
153 fprintf(class_stream
, " * D L G L e x e r C l a s s D e f i n i t i o n\n");
154 fprintf(class_stream
, " *\n");
155 fprintf(class_stream
, " * Generated from:");
156 fprintf(class_stream
, " %s", file_str
[0]);
157 fprintf(class_stream
, "\n");
158 fprintf(class_stream
, " *\n");
159 fprintf(class_stream
, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n");
160 fprintf(class_stream
, " * Purdue University Electrical Engineering\n");
161 fprintf(class_stream
, " * DLG Version %s\n", version
);
162 fprintf(class_stream
, " */\n\n");
163 fprintf(class_stream
, "\n");
164 fprintf(class_stream
, "#include \"%s\"\n", DLEXERBASE_H
);
168 /* MR1 16-Apr-97 Split printing of class header up into several parts */
169 /* MR1 so that #lexprefix <<...>>and #lexmember <<...>> */
170 /* MR1 can be inserted in the appropriate spots */
174 void p_class_def1(void)
179 if ( class_stream
== NULL
) return;
180 fprintf(class_stream
, "\nclass %s : public DLGLexerBase {\n", ClassName(""));
181 fprintf(class_stream
, "public:\n");
185 void p_class_def2(void)
191 if ( class_stream
== NULL
) return;
192 fprintf(class_stream
, "public:\n");
193 fprintf(class_stream
, "\tstatic const int MAX_MODE;\n");
194 fprintf(class_stream
, "\tstatic const int DfaStates;\n");
195 for (i
=0; i
<cur_mode
; i
++) {
196 fprintf(class_stream
, "\tstatic const int %s;\n", mode_name
[i
]);
199 fprintf(class_stream
, "\ttypedef %s DfaState;\n\n", minsize(dfa_allocated
));
200 fprintf(class_stream
, "\t%s(DLGInputStream *in,\n",ClassName(""));
201 fprintf(class_stream
, "\t\tunsigned bufsize=2000)\n");
202 fprintf(class_stream
, "\t\t: DLGLexerBase(in, bufsize, %d)\n", interactive
);
203 fprintf(class_stream
, "\t{\n");
204 fprintf(class_stream
, "\t;\n");
205 fprintf(class_stream
, "\t}\n");
206 fprintf(class_stream
, "\tvoid mode(int);\n");
207 fprintf(class_stream
, "\tANTLRTokenType nextTokenType(void);\n");
208 fprintf(class_stream
, "\tvoid advance(void);\n");
209 fprintf(class_stream
, "protected:\n");
210 for (i
=1; i
<=action_no
; ++i
) {
211 fprintf(class_stream
, "\tANTLRTokenType act%d();\n", i
);
214 for(m
=0; m
<(mode_counter
-1); ++m
){
215 for(i
=dfa_basep
[m
]; i
<dfa_basep
[m
+1]; ++i
)
216 fprintf(class_stream
, "\tstatic DfaState st%d[%d];\n", i
-1, dfa_class_nop
[m
]+1);
218 for(i
=dfa_basep
[m
]; i
<=dfa_allocated
; ++i
)
219 fprintf(class_stream
, "\tstatic DfaState st%d[%d];\n", i
-1, dfa_class_nop
[m
]+1);
221 fprintf(class_stream
, "\tstatic DfaState *dfa[%d];\n", dfa_allocated
);
222 fprintf(class_stream
, "\tstatic DfaState dfa_base[];\n");
223 /* fprintf(class_stream, "\tstatic int dfa_base_no[];\n"); */
224 fprintf(class_stream
, "\tstatic unsigned char *b_class_no[];\n");
225 fprintf(class_stream
, "\tstatic DfaState accepts[%d];\n",dfa_allocated
+1);
226 fprintf(class_stream
, "\tstatic DLGChar alternatives[%d];\n",dfa_allocated
+1);
227 /* WARNING: should be ANTLRTokenType for action table, but g++ 2.5.6 is hosed */
228 fprintf(class_stream
, "\tstatic ANTLRTokenType (%s::*actions[%d])();\n", ClassName(""), action_no
+1);
229 for(m
=0; m
<mode_counter
; ++m
) {
230 fprintf(class_stream
, "\tstatic unsigned char shift%d[%d];\n",
234 fprintf(class_stream
, "\tint ZZSHIFT(int c) { return b_class_no[automaton][1+c]; }\n");
236 fprintf(class_stream
, "\tint ZZSHIFT(int c) { return 1+c; }\n");
239 /* MR1 11-APr-97 Kludge to allow inclusion of user-defined code in */
240 /* MR1 DLGLexer class header */
241 /* MR1 Deprecated in favor of 133MR1 addition #lexmember <<>> */
243 /* MR1 */ fprintf(class_stream
,"//\n");
244 /* MR1 */ fprintf(class_stream
,
245 /* MR1 */ "// 133MR1 Deprecated feature to allow inclusion of ");
246 /* MR1 */ fprintf(class_stream
,
247 /* MR1 */ "user-defined code in DLG class header\n");
248 /* MR1 */ fprintf(class_stream
,"//\n");
250 /* MR1 */ fprintf(class_stream
,"#ifdef DLGLexerIncludeFile\n");
251 /* MR1 */ fprintf(class_stream
,"#include DLGLexerIncludeFile\n");
252 /* MR1 */ fprintf(class_stream
,"#endif\n");
254 fprintf(class_stream
, "};\n");
256 fprintf(class_stream
, "typedef ANTLRTokenType (%s::*Ptr%sMemberFunc)();\n",
257 ClassName(""), ClassName(""));
259 fprintf(class_stream
, "#endif\n");
262 /* generate required header on output */
270 fprintf(OUT
, "/*\n");
271 fprintf(OUT
, " * D L G tables\n");
272 fprintf(OUT
, " *\n");
273 fprintf(OUT
, " * Generated from:");
274 fprintf(OUT
, " %s", file_str
[0]);
276 fprintf(OUT
, " *\n");
277 fprintf(OUT
, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n");
278 fprintf(OUT
, " * Purdue University Electrical Engineering\n");
279 fprintf(OUT
, " * DLG Version %s\n", version
);
280 fprintf(OUT
, " */\n\n");
281 if ( gen_cpp
) fprintf(OUT
, "#include \"pcctscfg.h\"\n");
282 if ( gen_cpp
) fprintf(OUT
, "#include \"pccts_stdio.h\"\n");
283 if ( !gen_cpp
) fprintf(OUT
, "#include \"%s\"\n\n", mode_file
);
288 void p_includes(void)
293 fprintf(OUT
, "#include \"%s\"\n", APARSER_H
);
294 fprintf(OUT
, "#include \"%s\"\n", DLEXERBASE_H
);
295 fprintf(OUT
, "#include \"%s\"\n", ClassName(".h"));
298 /* generate code to tie up any loose ends */
301 void p_tail(void) /* MR1 */
303 void p_tail() /* MR1 */
307 if ( strcmp(ClassName(""), DEFAULT_CLASSNAME
)!=0 )
308 fprintf(OUT
, "#define DLGLexer %s\n", ClassName(""));
309 fprintf(OUT
, "#include \"%s\"\n", DLEXER_H
); /* MR23 Rename DLexer.cpp to DLexer.h */
315 fprintf(OUT
, "#define ZZSHIFT(c) (b_class_no[zzauto][1+c])\n");
317 fprintf(OUT
, "#define ZZSHIFT(c) (1+c)\n");
318 if ( !gen_cpp
) fprintf(OUT
, "#define MAX_MODE %d\n",mode_counter
);
319 fprintf(OUT
, "#include \"dlgauto.h\"\n");
323 /* output the table of DFA for general use */
332 fprintf(OUT
, "#define DfaStates\t%d\n", dfa_allocated
);
333 fprintf(OUT
, "typedef %s DfaState;\n\n", minsize(dfa_allocated
));
339 fprintf(OUT
, "const int %s::MAX_MODE=%d;\n",
342 fprintf(OUT
, "const int %s::DfaStates=%d;\n",
345 for (i
=0; i
<cur_mode
; i
++) {
346 fprintf(OUT
, "const int %s::%s=%d;\n",
347 ClassName(""), mode_name
[i
], mode_number
[i
]);
360 if (interactive
|| gen_cpp
)
361 p_alternative_table();
365 /* figures out the smallest variable type that will hold the transitions
369 char *minsize(int elements
)
371 char *minsize(elements
)
377 while ((unsigned long) elements
> typesize
[i
]) /* MR20 */
384 void p_node_table(void)
392 for(m
=0; m
<(mode_counter
-1); ++m
){
393 for(i
=dfa_basep
[m
]; i
<dfa_basep
[m
+1]; ++i
)
394 p_single_node(i
,dfa_class_nop
[m
]);
396 for(i
=dfa_basep
[m
]; i
<=dfa_allocated
; ++i
)
397 p_single_node(i
,dfa_class_nop
[m
]);
402 void p_single_node(int i
,int classes
)
404 void p_single_node(i
,classes
)
409 register int trans
, items_on_line
;
412 /* extra state (classes+1) for invalid characters */
413 fprintf(OUT
, "%sDfaState %sst%d[%d] = {\n ",
414 gen_cpp
?ClassName("::"):"static ",
415 gen_cpp
?ClassName("::"):"",(i
-1), (classes
+1));
417 fprintf(OUT
, "static DfaState st%d[%d] = {\n ", (i
-1), classes
);
419 items_on_line
= MAX_ON_LINE
;
420 for(j
=0; j
<classes
; ++j
){
422 trans
= DFA(i
)->trans
[j
];
423 if (trans
== NIL_INDEX
)
424 trans
= dfa_allocated
+1;
425 /* all of DFA moved down one in array */
426 fprintf(OUT
, "%d", trans
-1);
428 if (!(--items_on_line
)){
430 items_on_line
= MAX_ON_LINE
;
434 /* put in jump to error state */
435 fprintf(OUT
, "%d\n};\n\n", dfa_allocated
);
437 fprintf(OUT
, "\n};\n\n");
443 void p_dfa_table(void)
450 fprintf(OUT
, "\n%sDfaState *%sdfa[%d] = {\n",
451 gen_cpp
?ClassName("::"):"",gen_cpp
?ClassName("::"):"", dfa_allocated
);
452 for (i
=0; i
<(dfa_allocated
-1); ++i
){
453 fprintf(OUT
, "\tst%d,\n", i
);
455 fprintf(OUT
, "\tst%d\n", i
);
456 fprintf(OUT
, "};\n\n");
461 void p_accept_table(void)
463 void p_accept_table()
467 register int items_on_line
= 0;
468 int true_interactive
= TRUE
;
470 /* make sure element for one past (zzerraction) -WEC 12/16/92 */
471 fprintf(OUT
,"\n%sDfaState %saccepts[%d] = {\n ",
472 gen_cpp
?ClassName("::"):"",
473 gen_cpp
?ClassName("::"):"",
475 /* don't do anything if no dfa nodes */
476 if (i
>dfa_allocated
) goto skip_accepts
;
478 int accept
=0; /* MR14a - Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de) */
481 unsigned int *t
, *nfa_i
;
482 unsigned int *q
, *regular_expr
;
485 nfa_states
= DFA(i
)->nfa_states
;
486 t
= nfa_i
= set_pdq(nfa_states
);
487 /* NOTE: picks lowest accept because accepts monotonic */
488 /* with respect to nfa node numbers and set_pdq */
489 /* returns in that order */
490 while((*nfa_i
!= nil
) && (!(accept
= NFA(*nfa_i
)->accept
))){
494 /* figure out if more than one accept state there */
496 set_orel(accept
, &accept_set
);
497 while(*nfa_i
!= nil
){
498 set_orel(NFA(*nfa_i
)->accept
, &accept_set
);
501 /* remove error action from consideration */
502 set_rm(0, accept_set
);
504 if( set_deg(accept_set
)>1){
505 fprintf(stderr
, "dlg warning: ambiguous regular expression ");
506 q
= regular_expr
= set_pdq(accept_set
);
507 while(*regular_expr
!= nil
){
508 fprintf(stderr
," %d ", *regular_expr
);
511 fprintf(stderr
, "\n");
516 if ((DFA(i
)->alternatives
) && (accept
!= 0)){
517 true_interactive
= FALSE
;
519 fprintf(OUT
, "%d, ", accept
);
521 /* free up memory before we "break" below -ATG 4/6/95 */
523 set_free(accept_set
);
525 if ((++i
)>dfa_allocated
)
527 if ((++items_on_line
)>=MAX_ON_LINE
){
533 set_free(accept_set);
536 /* make sure element for one past (zzerraction) -WEC 12/16/92 */
538 fprintf(OUT
, "0\n};\n\n");
543 void p_action_table(void)
545 void p_action_table()
549 char* theClassName
= ClassName("");
552 fprintf(OUT
, "Ptr%sMemberFunc %s::actions[%d] = {\n", theClassName
,
553 theClassName
, action_no
+1);
555 fprintf(OUT
, "void (*actions[%d])() = {\n", action_no
+1);
557 /* fprintf(OUT, "\t(Ptr%sMemberFunc)&%s::erraction,\n", theClassName, theClassName);*/
558 fprintf(OUT
, "\t&%s::erraction,\n", theClassName
);
560 fprintf(OUT
, "\tzzerraction,\n");
561 for (i
=1; i
<action_no
; ++i
) {
563 /* fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d,\n", theClassName, theClassName, i);*/
564 fprintf(OUT
,"\t&%s::act%d,\n", theClassName
, i
);
566 fprintf(OUT
,"\tact%d,\n", i
);
570 /* fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d\n", theClassName, theClassName, i);*/
571 fprintf(OUT
,"\t&%s::act%d\n", theClassName
, i
);
573 fprintf(OUT
,"\tact%d\n", i
);
574 fprintf(OUT
, "};\n\n");
579 void p_shift_table(int m
) /* MR1 */
581 void p_shift_table(m
) /* MR1 */
585 register int i
= 0, j
;
586 register int items_on_line
= 0;
588 fprintf(OUT
, "%s unsigned char %sshift%d[%d] = {\n ",
590 gen_cpp
?ClassName("::"):"", m
, CHAR_RANGE
);
592 /* find which partition character i is in */
593 for (j
=0; j
<dfa_class_nop
[mode_counter
]; ++j
){
594 if (set_el(i
,class_sets
[j
]))
598 if ((++i
)>=CHAR_RANGE
)
601 if ((++items_on_line
)>=MAX_ON_LINE
){
606 fprintf(OUT
, "\n};\n\n");
611 void p_base_table(void)
618 fprintf(OUT
, "%sDfaState %sdfa_base[] = {\n",
619 gen_cpp
?ClassName("::"):"static ",
620 gen_cpp
?ClassName("::"):"");
621 for(m
=0; m
<(mode_counter
-1); ++m
)
622 fprintf(OUT
, "\t%d,\n", dfa_basep
[m
]-1);
623 fprintf(OUT
, "\t%d\n};\n\n", dfa_basep
[m
]-1);
628 void p_class_table(void) /* MR1 */
630 void p_class_table() /* MR1 */
636 fprintf(OUT
,"%s int %sdfa_class_no[] = {\n",
638 gen_cpp
?ClassName("::"):"");
639 for(m
=0; m
<(mode_counter
-1); ++m
)
640 fprintf(OUT
,"\t%d,\n", dfa_class_nop
[m
]);
641 fprintf(OUT
,"\t%d\n};\n\n", dfa_class_nop
[m
]);
647 void p_bshift_table(void) /* MR1 */
649 void p_bshift_table() /* MR1 */
654 fprintf(OUT
,"%s unsigned char *%sb_class_no[] = {\n",
656 gen_cpp
?ClassName("::"):"");
657 for(m
=0; m
<(mode_counter
-1); ++m
)
658 fprintf(OUT
, "\tshift%d,\n", m
);
659 fprintf(OUT
, "\tshift%d\n};\n\n", m
);
664 void p_alternative_table(void) /* MR1 */
666 void p_alternative_table() /* MR1 */
671 if ( !gen_cpp
) fprintf(OUT
, "#define ZZINTERACTIVE\n\n");
673 fprintf(OUT
, "DLGChar %salternatives[%d] = {\n", /* mr23 vhs %sDfaStates+1 */
675 dfa_allocated
+1); /* vhs ClassName("::")); */
677 fprintf(OUT
, "static %s zzalternatives[DfaStates+1] = {\n",
678 minsize(dfa_allocated
));
680 for(i
=1; i
<=dfa_allocated
; ++i
)
681 fprintf(OUT
, "\t%d,\n", DFA(i
)->alternatives
);
682 fprintf(OUT
, "/* must have 0 for zzalternatives[DfaStates] */\n");
683 fprintf(OUT
, "\t0\n};\n\n");
688 void p_mode_def(char *s
,int m
) /* MR1 */
690 void p_mode_def(s
,m
) /* MR1 */
697 mode_name
[cur_mode
] = mystrdup(s
);
698 mode_number
[cur_mode
] = m
;
702 fprintf(mode_stream
, "#define %s %d\n", s
, m
);
706 char * ClassName(char *suffix
)
708 char * ClassName(suffix
)
712 static char buf
[200];
713 extern char *class_name
;
715 sprintf(buf
, "%s%s", class_name
, suffix
);
721 /* print out a particular nfa node that is pointed to by p */
724 void p_nfa_node(nfa_node
*p
)
730 register nfa_node
*t
;
733 printf("NFA state : %d\naccept state : %d\n",
734 NFA_NO(p
),p
->accept
);
735 if (p
->trans
[0] != NIL_INDEX
){
736 printf("trans[0] => %d on ", NFA_NO(p
->trans
[0]));
741 printf("trans[0] => nil\n");
742 if (p
->trans
[1] != NIL_INDEX
)
743 printf("trans[1] => %d on epsilon\n",
744 NFA_NO(p
->trans
[1]));
746 printf("trans[1] => nil\n");
754 /* code to print out special structures when using a debugger */
759 void p_nfa(nfa_node
*p
)
760 nfa_node
*p
; /* state number also index into array */
763 /* each node has a marker on it so it only gets printed once */
765 operation_no
++; /* get new number */
770 void s_p_nfa(nfa_node
*p
)
773 nfa_node
*p
; /* state number also index into array */
776 if ((p
!= NIL_INDEX
) && (p
->nfa_set
!= operation_no
)){
777 /* so it is only printed once */
778 p
->nfa_set
= operation_no
;
780 s_p_nfa(p
->trans
[0]);
781 s_p_nfa(p
->trans
[1]);
786 void p_dfa_node(dfa_node
*p
)
795 printf("DFA state :%d\n",NFA_NO(p
));
800 printf("from nfa states : ");
801 p_set(p
->nfa_states
);
803 /* NOTE: trans arcs stored as ints rather than pointer*/
804 for (i
=0; i
<class_no
; i
++){
805 printf("%d ",p
->trans
[i
]);
817 /* prints out all the dfa nodes actually allocated */
821 for (i
= 1; i
<=dfa_allocated
; i
++)
826 /* print out numbers in the set label */
829 void p_set(set label
)
840 t
= e
= set_pdq(label
);
842 printf("%d ", (*e
+MIN_CHAR
));