]> git.lizzy.rs Git - rust.git/blob - src/grammar/parser-lalr-main.c
Auto merge of #63233 - RalfJung:get_unchecked, r=Centril
[rust.git] / src / grammar / parser-lalr-main.c
1 #include <stdio.h>
2 #include <stdarg.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 extern int yylex();
7 extern int rsparse();
8
9 #define PUSHBACK_LEN 4
10
11 static char pushback[PUSHBACK_LEN];
12 static int verbose;
13
14 void print(const char* format, ...) {
15   va_list args;
16   va_start(args, format);
17   if (verbose) {
18     vprintf(format, args);
19   }
20   va_end(args);
21 }
22
23 // If there is a non-null char at the head of the pushback queue,
24 // dequeue it and shift the rest of the queue forwards. Otherwise,
25 // return the token from calling yylex.
26 int rslex() {
27   if (pushback[0] == '\0') {
28     return yylex();
29   } else {
30     char c = pushback[0];
31     memmove(pushback, pushback + 1, PUSHBACK_LEN - 1);
32     pushback[PUSHBACK_LEN - 1] = '\0';
33     return c;
34   }
35 }
36
37 // Note: this does nothing if the pushback queue is full. As long as
38 // there aren't more than PUSHBACK_LEN consecutive calls to push_back
39 // in an action, this shouldn't be a problem.
40 void push_back(char c) {
41   for (int i = 0; i < PUSHBACK_LEN; ++i) {
42     if (pushback[i] == '\0') {
43       pushback[i] = c;
44       break;
45     }
46   }
47 }
48
49 extern int rsdebug;
50
51 struct node {
52   struct node *next;
53   struct node *prev;
54   int own_string;
55   char const *name;
56   int n_elems;
57   struct node *elems[];
58 };
59
60 struct node *nodes = NULL;
61 int n_nodes;
62
63 struct node *mk_node(char const *name, int n, ...) {
64   va_list ap;
65   int i = 0;
66   unsigned sz = sizeof(struct node) + (n * sizeof(struct node *));
67   struct node *nn, *nd = (struct node *)malloc(sz);
68
69   print("# New %d-ary node: %s = %p\n", n, name, nd);
70
71   nd->own_string = 0;
72   nd->prev = NULL;
73   nd->next = nodes;
74   if (nodes) {
75     nodes->prev = nd;
76   }
77   nodes = nd;
78
79   nd->name = name;
80   nd->n_elems = n;
81
82   va_start(ap, n);
83   while (i < n) {
84     nn = va_arg(ap, struct node *);
85     print("#   arg[%d]: %p\n", i, nn);
86     print("#            (%s ...)\n", nn->name);
87     nd->elems[i++] = nn;
88   }
89   va_end(ap);
90   n_nodes++;
91   return nd;
92 }
93
94 struct node *mk_atom(char *name) {
95   struct node *nd = mk_node((char const *)strdup(name), 0);
96   nd->own_string = 1;
97   return nd;
98 }
99
100 struct node *mk_none() {
101   return mk_atom("<none>");
102 }
103
104 struct node *ext_node(struct node *nd, int n, ...) {
105   va_list ap;
106   int i = 0, c = nd->n_elems + n;
107   unsigned sz = sizeof(struct node) + (c * sizeof(struct node *));
108   struct node *nn;
109
110   print("# Extending %d-ary node by %d nodes: %s = %p",
111         nd->n_elems, c, nd->name, nd);
112
113   if (nd->next) {
114     nd->next->prev = nd->prev;
115   }
116   if (nd->prev) {
117     nd->prev->next = nd->next;
118   }
119   nd = realloc(nd, sz);
120   nd->prev = NULL;
121   nd->next = nodes;
122   nodes->prev = nd;
123   nodes = nd;
124
125   print(" ==> %p\n", nd);
126
127   va_start(ap, n);
128   while (i < n) {
129     nn = va_arg(ap, struct node *);
130     print("#   arg[%d]: %p\n", i, nn);
131     print("#            (%s ...)\n", nn->name);
132     nd->elems[nd->n_elems++] = nn;
133     ++i;
134   }
135   va_end(ap);
136   return nd;
137 }
138
139 int const indent_step = 4;
140
141 void print_indent(int depth) {
142   while (depth) {
143     if (depth-- % indent_step == 0) {
144       print("|");
145     } else {
146       print(" ");
147     }
148   }
149 }
150
151 void print_node(struct node *n, int depth) {
152   int i = 0;
153   print_indent(depth);
154   if (n->n_elems == 0) {
155     print("%s\n", n->name);
156   } else {
157     print("(%s\n", n->name);
158     for (i = 0; i < n->n_elems; ++i) {
159       print_node(n->elems[i], depth + indent_step);
160     }
161     print_indent(depth);
162     print(")\n");
163   }
164 }
165
166 int main(int argc, char **argv) {
167   if (argc == 2 && strcmp(argv[1], "-v") == 0) {
168     verbose = 1;
169   } else {
170     verbose = 0;
171   }
172   int ret = 0;
173   struct node *tmp;
174   memset(pushback, '\0', PUSHBACK_LEN);
175   ret = rsparse();
176   print("--- PARSE COMPLETE: ret:%d, n_nodes:%d ---\n", ret, n_nodes);
177   if (nodes) {
178     print_node(nodes, 0);
179   }
180   while (nodes) {
181     tmp = nodes;
182     nodes = tmp->next;
183     if (tmp->own_string) {
184       free((void*)tmp->name);
185     }
186     free(tmp);
187   }
188   return ret;
189 }
190
191 void rserror(char const *s) {
192   fprintf(stderr, "%s\n", s);
193 }