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.
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.
19 #define PUSHBACK_LEN 4
21 static char pushback[PUSHBACK_LEN];
24 void print(const char* format, ...) {
26 va_start(args, format);
28 vprintf(format, args);
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.
37 if (pushback[0] == '\0') {
41 memmove(pushback, pushback + 1, PUSHBACK_LEN - 1);
42 pushback[PUSHBACK_LEN - 1] = '\0';
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') {
70 struct node *nodes = NULL;
73 struct node *mk_node(char const *name, int n, ...) {
76 unsigned sz = sizeof(struct node) + (n * sizeof(struct node *));
77 struct node *nn, *nd = (struct node *)malloc(sz);
79 print("# New %d-ary node: %s = %p\n", n, name, nd);
94 nn = va_arg(ap, struct node *);
95 print("# arg[%d]: %p\n", i, nn);
96 print("# (%s ...)\n", nn->name);
104 struct node *mk_atom(char *name) {
105 struct node *nd = mk_node((char const *)strdup(name), 0);
110 struct node *mk_none() {
111 return mk_atom("<none>");
114 struct node *ext_node(struct node *nd, int n, ...) {
116 int i = 0, c = nd->n_elems + n;
117 unsigned sz = sizeof(struct node) + (c * sizeof(struct node *));
120 print("# Extending %d-ary node by %d nodes: %s = %p",
121 nd->n_elems, c, nd->name, nd);
124 nd->next->prev = nd->prev;
127 nd->prev->next = nd->next;
129 nd = realloc(nd, sz);
135 print(" ==> %p\n", nd);
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;
149 int const indent_step = 4;
151 void print_indent(int depth) {
153 if (depth-- % indent_step == 0) {
161 void print_node(struct node *n, int depth) {
164 if (n->n_elems == 0) {
165 print("%s\n", n->name);
167 print("(%s\n", n->name);
168 for (i = 0; i < n->n_elems; ++i) {
169 print_node(n->elems[i], depth + indent_step);
176 int main(int argc, char **argv) {
177 if (argc == 2 && strcmp(argv[1], "-v") == 0) {
184 memset(pushback, '\0', PUSHBACK_LEN);
186 print("--- PARSE COMPLETE: ret:%d, n_nodes:%d ---\n", ret, n_nodes);
188 print_node(nodes, 0);
193 if (tmp->own_string) {
194 free((void*)tmp->name);
201 void rserror(char const *s) {
202 fprintf(stderr, "%s\n", s);