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