summaryrefslogtreecommitdiffstats
path: root/BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c')
-rw-r--r--BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c b/BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c
new file mode 100644
index 0000000000..0b8bc163d1
--- /dev/null
+++ b/BaseTools/Source/C/VfrCompile/Pccts/dlg/relabel.c
@@ -0,0 +1,217 @@
+/* This group of functions does the character class compression.
+ It goes over the dfa and relabels the arcs with the partitions
+ of characters in the NFA. The partitions are stored in the
+ array class.
+
+ *
+ * SOFTWARE RIGHTS
+ *
+ * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
+ * Set (PCCTS) -- PCCTS is in the public domain. An individual or
+ * company may do whatever they wish with source code distributed with
+ * PCCTS or the code generated by PCCTS, including the incorporation of
+ * PCCTS, or its output, into commerical software.
+ *
+ * We encourage users to develop software with PCCTS. However, we do ask
+ * that credit is given to us for developing PCCTS. By "credit",
+ * we mean that if you incorporate our source code into one of your
+ * programs (commercial product, research project, or otherwise) that you
+ * acknowledge this fact somewhere in the documentation, research report,
+ * etc... If you like PCCTS and have developed a nice tool with the
+ * output, please mention that you developed it using PCCTS. In
+ * addition, we ask that this header remain intact in our source code.
+ * As long as these guidelines are kept, we expect to continue enhancing
+ * this system and expect to make other tools available as they are
+ * completed.
+ *
+ * DLG 1.33
+ * Will Cohen
+ * With mods by Terence Parr; AHPCRC, University of Minnesota
+ * 1989-2001
+ */
+
+#include <stdio.h>
+#include "dlg.h"
+#ifdef MEMCHK
+#include "trax.h"
+#else
+#ifdef __STDC__
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif /* __STDC__ */
+#endif
+
+int class_no = CHAR_RANGE; /* number of classes for labels */
+int first_el[CHAR_RANGE]; /* first element in each class partition */
+set class_sets[CHAR_RANGE]; /* array holds partitions from class */
+ /* compression */
+
+/* goes through labels on NFA graph and partitions the characters into
+ * character classes. This reduces the amount of space required for each
+ * dfa node, since only one arc is required each class instead of one arc
+ * for each character
+ * level:
+ * 0 no compression done
+ * 1 remove unused characters from classes
+ * 2 compress equivalent characters into same class
+ *
+ * returns the number of character classes required
+ */
+#ifdef __USE_PROTOS
+int relabel(nfa_node* start,int level)
+#else
+int relabel(start,level)
+int level;
+nfa_node *start;
+#endif
+{
+ if (level){
+ set_free(used_classes);
+ partition(start,level);
+ label_with_classes(start);
+ }else{
+ /* classes equivalent to all characters in alphabet */
+ class_no = CHAR_RANGE;
+ }
+ return class_no;
+}
+
+/* makes character class sets for new labels */
+#ifdef __USE_PROTOS
+void partition(nfa_node* start,int level)
+#else
+void partition(start,level)
+nfa_node *start; /* beginning of nfa graph */
+int level; /* compression level to uses */
+#endif
+{
+ set current_class;
+ set unpart_chars;
+ set temp;
+
+ unpart_chars = set_dup(used_chars);
+#if 0
+ /* EOF (-1+1) alway in class 0 */
+ class_sets[0] = set_of(0);
+ first_el[0] = 0;
+ used_classes = set_of(0);
+ temp = set_dif(unpart_chars, class_sets[0]);
+ set_free(unpart_chars);
+ unpart_chars = temp;
+ class_no = 1;
+#else
+ class_no = 0;
+#endif
+ while (!set_nil(unpart_chars)){
+ /* don't look for equivalent labels if c <= 1 */
+ if (level <= 1){
+ current_class = set_of(set_int(unpart_chars));
+ }else{
+ current_class = set_dup(unpart_chars);
+ intersect_nfa_labels(start,&current_class);
+ }
+ set_orel(class_no,&used_classes);
+ first_el[class_no] = set_int(current_class);
+ class_sets[class_no] = current_class;
+ temp = set_dif(unpart_chars,current_class);
+ set_free(unpart_chars);
+ unpart_chars = temp;
+ ++class_no;
+ }
+
+ /* free unpart_chars -ATG 5/6/95 */
+ set_free(unpart_chars);
+
+#if 0
+ /* group all the other unused characters into a class */
+ set_orel(class_no,&used_classes);
+ first_el[class_no] = set_int(current_class);
+ class_sets[class_no] = set_dif(normal_chars,used_chars);
+ ++class_no;
+#endif
+}
+
+
+/* given pointer to beginning of graph and recursively walks it trying
+ * to find a maximal partition. This partion in returned in maximal_class
+ */
+#ifdef __USE_PROTOS
+void intersect_nfa_labels(nfa_node* start,set* maximal_class)
+#else
+void intersect_nfa_labels(start,maximal_class)
+nfa_node *start;
+set *maximal_class;
+#endif
+{
+ /* pick a new operation number */
+ ++operation_no;
+ r_intersect(start,maximal_class);
+}
+
+#ifdef __USE_PROTOS
+void r_intersect(nfa_node* start,set* maximal_class)
+#else
+void r_intersect(start,maximal_class)
+nfa_node *start;
+set * maximal_class;
+#endif
+{
+ set temp;
+
+ if(start && start->nfa_set != operation_no)
+ {
+ start->nfa_set = operation_no;
+ temp = set_and(*maximal_class,start->label);
+ if (!set_nil(temp))
+ {
+ set_free(*maximal_class);
+ *maximal_class = temp;
+ }else{
+ set_free(temp);
+ }
+ r_intersect(start->trans[0],maximal_class);
+ r_intersect(start->trans[1],maximal_class);
+ }
+}
+
+
+/* puts class labels in place of old character labels */
+#ifdef __USE_PROTOS
+void label_with_classes(nfa_node* start)
+#else
+void label_with_classes(start)
+nfa_node *start;
+#endif
+{
+ ++operation_no;
+ label_node(start);
+}
+
+#ifdef __USE_PROTOS
+void label_node(nfa_node *start)
+#else
+void label_node(start)
+nfa_node *start;
+#endif
+{
+ set new_label;
+ register int i;
+
+ /* only do node if it hasn't been done before */
+ if (start && start->nfa_set != operation_no){
+ start->nfa_set = operation_no;
+ new_label = empty;
+ for (i = 0; i<class_no; ++i){
+ /* if one element of class in old_label,
+ all elements are. */
+ if (set_el(first_el[i],start->label))
+ set_orel(i,&new_label);
+ }
+ set_free(start->label);
+ start->label = new_label;
+ /* do any nodes that can be reached from this one */
+ label_node(start->trans[0]);
+ label_node(start->trans[1]);
+ }
+}