11 static char pushback[PUSHBACK_LEN];
14 void print(const char* format, ...) {
16 va_start(args, format);
18 vprintf(format, args);
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.
27 if (pushback[0] == '\0') {
31 memmove(pushback, pushback + 1, PUSHBACK_LEN - 1);
32 pushback[PUSHBACK_LEN - 1] = '\0';
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') {
60 struct node *nodes = NULL;
63 struct node *mk_node(char const *name, int n, ...) {
66 unsigned sz = sizeof(struct node) + (n * sizeof(struct node *));
67 struct node *nn, *nd = (struct node *)malloc(sz);
69 print("# New %d-ary node: %s = %p\n", n, name, nd);
84 nn = va_arg(ap, struct node *);
85 print("# arg[%d]: %p\n", i, nn);
86 print("# (%s ...)\n", nn->name);
94 struct node *mk_atom(char *name) {
95 struct node *nd = mk_node((char const *)strdup(name), 0);
100 struct node *mk_none() {
101 return mk_atom("<none>");
104 struct node *ext_node(struct node *nd, int n, ...) {
106 int i = 0, c = nd->n_elems + n;
107 unsigned sz = sizeof(struct node) + (c * sizeof(struct node *));
110 print("# Extending %d-ary node by %d nodes: %s = %p",
111 nd->n_elems, c, nd->name, nd);
114 nd->next->prev = nd->prev;
117 nd->prev->next = nd->next;
119 nd = realloc(nd, sz);
125 print(" ==> %p\n", nd);
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;
139 int const indent_step = 4;
141 void print_indent(int depth) {
143 if (depth-- % indent_step == 0) {
151 void print_node(struct node *n, int depth) {
154 if (n->n_elems == 0) {
155 print("%s\n", n->name);
157 print("(%s\n", n->name);
158 for (i = 0; i < n->n_elems; ++i) {
159 print_node(n->elems[i], depth + indent_step);
166 int main(int argc, char **argv) {
167 if (argc == 2 && strcmp(argv[1], "-v") == 0) {
174 memset(pushback, '\0', PUSHBACK_LEN);
176 print("--- PARSE COMPLETE: ret:%d, n_nodes:%d ---\n", ret, n_nodes);
178 print_node(nodes, 0);
183 if (tmp->own_string) {
184 free((void*)tmp->name);
191 void rserror(char const *s) {
192 fprintf(stderr, "%s\n", s);