1 /*
2   Copyright 2002-2008 John Plevyak, All Rights Reserved
3 */
4 
5 //#include "d.h"
6 module ddparser.parse;
7 
8 import std.stdio;
9 import std.ascii;
10 import std.algorithm;
11 import std.conv;
12 
13 import ddparser.util;
14 import ddparser.dparse_tables;
15 import ddparser.dparse;
16 import ddparser.scan;
17 import ddparser.gram;
18 import ddparser.symtab;
19 
20 import core.stdc.string;
21 
22 enum NO_DPN = cast(D_ParseNode*)0x1;
23 PNode* DPN_TO_PN(D_ParseNode* dpn)
24 {
25     return (cast(PNode *)((cast(char*)dpn)-cast(intptr_t)(&(cast(PNode*)0).parse_node)));
26 }
27 
28 bool is_epsilon_PNode(PNode* _pn)
29 {
30     return (_pn.parse_node.start_loc.s == _pn.parse_node.end);
31 }
32 
33 
34 alias VecZNode = Vec!(ZNode*);
35 alias VecVecZNode = Vec!(VecZNode*);
36 alias VecSNode = Vec!(SNode*);
37 alias VecPNode = Vec!(PNode*);
38 
39 struct PNodeHash {
40   PNode*[] v;
41   uint		i;	/* size index (power of 2) */
42   uint  	n;	/* size */
43   PNode  *all;
44 }
45 
46 struct SNodeHash {
47   SNode*[]  v;
48   uint		i;	/* size index (power of 2) */
49   uint  	n;	/* size */
50   SNode  *all;
51   SNode  *last_all;
52 }
53 
54 struct Reduction {
55   ZNode		*znode;
56   SNode		*snode;
57   D_Reduction	*reduction;
58   SNode		*new_snode;
59   int			new_depth;
60   Reduction	*next;
61 }
62 
63 struct Shift {
64   SNode		*snode;
65   Shift		*next;
66 }
67 
68 struct Parser {
69   D_ParseNode_Globals	*initial_globals;		/* global values */
70   D_WhiteSpaceFn 	initial_white_space_fn;
71   D_Scope 	*initial_scope;
72   D_SyntaxErrorFn 	syntax_error_fn;
73   D_AmbiguityFn 	ambiguity_fn;
74   D_FreeNodeFn          free_node_fn;
75   d_loc_t 		loc; 		/* initial location, set on error */
76   int			start_state;
77   /* user configurables */
78   int 			sizeof_user_parse_node;
79   int 			save_parse_tree;
80   int			dont_compare_stacks;
81   int 			dont_fixup_internal_productions;
82   int 			fixup_EBNF_productions;
83   int			dont_merge_epsilon_trees;
84   int			dont_use_height_for_disambiguation;
85   int			dont_use_greediness_for_disambiguation;
86   int 			commit_actions_interval; /* 0 is immediate */
87   bool 			error_recovery;
88   bool			partial_parses;
89   /* parse results */
90   int 			syntax_errors;
91 
92   /* string to parse */
93   const(char) *start, end;
94 
95 private:
96   D_ParserTables *t;
97   /* statistics */
98   int states, pnodes, scans, shifts, reductions, compares, ambiguities;
99   /* parser state */
100   PNodeHash pnode_hash;
101   SNodeHash snode_hash;
102   Reduction *reductions_todo;
103   Shift *shifts_todo;
104   D_Scope *top_scope;
105   SNode *accept;
106   int last_syntax_error_line;
107   /* memory management */
108   Reduction *free_reductions;
109   Shift *free_shifts;
110   int live_pnodes;
111   PNode *free_pnodes;
112   SNode *free_snodes;
113   ZNode *free_znodes;
114   Vec!(D_Reduction *) error_reductions;
115   ShiftResult[] shift_results;
116   D_Shift[] code_shifts;
117   /* comments */
118   Parser *whitespace_parser;
119 }
120 
121 alias D_Parser = Parser;
122 
123 /*
124   Parse Node - the 'symbol' and the constructed parse subtrees.
125 */
126 struct PNode {
127   uint			hash;
128   AssocKind		assoc;
129   int			priority;
130   AssocKind		op_assoc;
131   int			op_priority;
132   D_Reduction		*reduction;
133   const(D_Shift)* shift;
134   VecPNode		children;
135   uint			height;		/* max tree height */
136   bool			evaluated;
137   bool			error_recovery;
138   PNode		*all_next;
139   PNode		*bucket_next;
140   PNode		*ambiguities;
141   PNode		*latest;	/* latest version of this PNode */
142   const(char)	*ws_before;
143   const(char)	*ws_after;
144   D_Scope               *initial_scope;
145   void                  *initial_globals;
146   D_ParseNode		parse_node;	/* public fields */
147 }
148 
149 /*
150   State Node - the 'state'.
151 */
152 struct SNode {
153   D_Scope	*initial_scope;
154   void		*initial_globals;
155   d_loc_t	loc;
156   PNode		*last_pn;
157   VecZNode	zns;
158   SNode  *bucket_next;
159   SNode	*all_next;
160   uint stateIndex;
161   uint		depth;	     	/* max stack depth (less loops) */
162 }
163 
164 /*
165   (Z)Symbol Node - holds one of the symbols associated with a state.
166 */
167 struct ZNode {
168   PNode		*pn;
169   VecSNode	sns;
170 }
171 
172 ZNode* znode_next(ZNode* _z)
173 {
174     assert((*cast(ZNode**)&(_z.pn)) == cast(ZNode*)_z.pn);
175     return  (*cast(ZNode**)&(_z.pn));
176 }
177 
178 
179 /* tunables */
180 enum DEFAULT_COMMIT_ACTIONS_INTERVAL =         100;
181 enum PNODE_HASH_INITIAL_SIZE_INDEX =          10;
182 enum SNODE_HASH_INITIAL_SIZE_INDEX  =         8;
183 enum ERROR_RECOVERY_QUEUE_SIZE       =        10000;
184 
185 
186 void LATEST(ref PNode * _pn) @safe
187 {
188  while (_pn.latest != _pn.latest.latest) {
189     PNode *t = _pn.latest.latest;
190     _pn.latest = t; 
191   }
192  _pn = _pn.latest;
193 }
194 
195 
196 alias StackPNode = Stack!(PNode*);
197 alias StackSNode = Stack!(SNode*);
198 alias StackInt = Stack!int;
199 
200 
201 private void
202 print_paren(Parser *pp, PNode *p) {
203   int i;
204   const(char) *c;
205   LATEST(p);
206   if (!p.error_recovery) {
207     if (p.children.n) {
208       if (p.children.n > 1)
209         logf("(");
210       for (i = 0; i < p.children.n; i++)
211         print_paren(pp, p.children[i]);
212       if (p.children.n > 1)
213         logf(")");
214     } else if (p.parse_node.start_loc.s != p.parse_node.end_skip) {
215       logf(" ");
216       for (c = p.parse_node.start_loc.s; c < p.parse_node.end_skip; c++)
217         logf("%c", *c);
218       logf(" ");
219     }
220   }
221 }
222 
223 void
224 xprint_paren(Parser *pp, PNode *p) {
225   int i;
226   const(char) *c;
227   LATEST(p);
228   if (!p.error_recovery) {
229     logf("[%X %s]", p, pp.t.symbols[p.parse_node.symbol].name);
230     if (p.children.n) {
231       logf("(");
232       for (i = 0; i < p.children.n; i++)
233         xprint_paren(pp, p.children[i]);
234       logf(")");
235     } else if (p.parse_node.start_loc.s != p.parse_node.end_skip) {
236       logf(" ");
237       for (c = p.parse_node.start_loc.s; c < p.parse_node.end_skip; c++)
238         logf("%c", *c);
239       logf(" ");
240     }
241     if (p.ambiguities) {
242       logf(" |OR| ");
243       xprint_paren(pp, p.ambiguities);
244     }
245   }
246 }
247 
248 auto D_ParseNode_to_PNode(D_ParseNode* _apn)
249 {
250     return (cast(PNode*)(D_PN(_apn, -cast(intptr_t)&(cast(PNode*)null).parse_node)));
251 }
252 
253 auto PNode_to_D_ParseNode(PNode* _apn)
254 {
255     return (cast(D_ParseNode*)&_apn.parse_node);
256 }
257 
258 D_ParseNode *
259 d_get_child(D_ParseNode *apn, int child) {
260   PNode *pn = D_ParseNode_to_PNode(apn);
261   if (child < 0 || child >= pn.children.n)
262     return null;
263   return &pn.children[child].parse_node;
264 }
265 
266 int
267 d_get_number_of_children(D_ParseNode *apn) {
268   PNode *pn = D_ParseNode_to_PNode(apn);
269   return pn.children.n;
270 }
271 
272 D_ParseNode *
273 d_find_in_tree(D_ParseNode *apn, int symbol) {
274   PNode *pn = D_ParseNode_to_PNode(apn);
275   D_ParseNode *res;
276   int i;
277 
278   if (pn.parse_node.symbol == symbol)
279     return apn;
280   for (i = 0; i < pn.children.n; i++)
281   {
282     res = d_find_in_tree(&pn.children[i].parse_node, symbol);
283     if (res)
284       return res;
285   }
286   return null;
287 }
288 
289 const(char) *
290 d_ws_before(D_Parser *ap, D_ParseNode *apn) {
291   PNode *pn = D_ParseNode_to_PNode(apn);
292   return pn.ws_before;
293 }
294 
295 const(char) *
296 d_ws_after(D_Parser *ap, D_ParseNode *apn) {
297   PNode *pn = D_ParseNode_to_PNode(apn);
298   return pn.ws_after;
299 }
300 
301 uint SNODE_HASH(uint _s, D_Scope* _sc, void* _g)
302 {
303     return  cast(uint)(((cast(uintptr_t)(_s)) << 12) + ((cast(uintptr_t)(_sc))) + (cast(uintptr_t)(_g)));
304 }
305 
306 private SNode *
307 find_SNode(Parser *p, uint stateIndex, D_Scope *sc, void *g) {
308   SNodeHash *ph = &p.snode_hash;
309   uint h = SNODE_HASH(stateIndex, sc, g);
310   
311   if (ph.v)
312     for (SNode *sn = ph.v[h % $]; sn; sn = sn.bucket_next)
313       if (stateIndex == sn.stateIndex &&
314           sn.initial_scope == sc &&
315           sn.initial_globals == g)
316         return sn;
317   return null;
318 }
319 
320 private void
321 insert_SNode_internal(Parser *p, SNode *sn) {
322   SNodeHash *ph = &p.snode_hash;
323   uint h = SNODE_HASH(sn.stateIndex, sn.initial_scope, sn.initial_globals), i;
324 
325   if (ph.n + 1 > ph.v.length) {
326     SNode*[] v = ph.v;
327     auto m = ph.v.length;
328     ph.i++;
329     ph.v = new SNode*[d_prime2[ph.i]];
330     for (i = 0; i < m; i++)
331     {
332         SNode *t = v[i];
333       while (t) {
334         v[i] = v[i].bucket_next;
335         insert_SNode_internal(p, t);
336         t = v[i];
337       }
338     }
339   }
340   sn.bucket_next = ph.v[h % $];
341   assert(sn.bucket_next != sn);
342   ph.v[h % $] = sn;
343   ph.n++;
344 }
345 
346 private void
347 insert_SNode(Parser *p, SNode *sn) {
348   insert_SNode_internal(p, sn);
349   sn.all_next = p.snode_hash.all;
350   p.snode_hash.all = sn;
351 }
352 
353 private SNode *
354 new_SNode(Parser *p, uint stateIndex, d_loc_t *loc, D_Scope *sc, void *g) {
355   SNode *sn = p.free_snodes;
356   if (!sn)
357     sn = new SNode();
358   else
359     p.free_snodes = sn.all_next;
360   sn.depth = 0;
361   vec_clear(&sn.zns);
362   sn.all_next = null;
363   p.states++;
364   sn.stateIndex = stateIndex;
365   sn.initial_scope = sc;
366   sn.initial_globals = g;
367   sn.last_pn = null;
368   sn.loc = *loc;
369 
370   insert_SNode(p, sn);
371   if (p.t.states[stateIndex].accept) {
372     if (!p.accept) {
373       p.accept = sn;
374     } else if (sn.loc.s > p.accept.loc.s) {
375       p.accept = sn;
376     }
377   }
378   return sn;
379 }
380 
381 private ZNode *
382 new_ZNode(Parser *p, PNode *pn) {
383     auto z = new ZNode();
384     z.pn = pn;
385     vec_clear(&z.sns);
386   return z;
387 }
388 
389 private void
390 free_PNode(Parser *p, PNode *pn) {
391   int i;
392   if (p.free_node_fn)
393     p.free_node_fn(&pn.parse_node);
394   vec_free(&pn.children);
395 }
396 
397 uint PNODE_HASH(const char* _si, const char* _ei, int _s, D_Scope* _sc, void* _g)
398 {
399     return cast(uint)(((cast(uintptr_t)_si) << 8) + ((cast(uintptr_t)_ei) << 16) + ((cast(uintptr_t)_s)) + ((cast(uintptr_t)_sc)) + ((cast(uintptr_t)_g)));
400 }
401 
402 private PNode *
403 find_PNode(Parser *p, const char *start, const char *end_skip, int symbol, D_Scope *sc, void *g, uint *hash) {
404   PNodeHash *ph = &p.pnode_hash;
405   PNode *pn;
406   uint h = PNODE_HASH(start, end_skip, symbol, sc, g);
407   *hash = h;
408   if (ph.v)
409     for (pn = ph.v[h % ph.v.length]; pn; pn = pn.bucket_next)
410       if (pn.hash == h &&
411           pn.parse_node.symbol == symbol &&
412           pn.parse_node.start_loc.s == start &&
413           pn.parse_node.end_skip == end_skip &&
414           pn.initial_scope == sc &&
415           pn.initial_globals == g) {
416         LATEST(pn);
417         return pn;
418       }
419   return null;
420 }
421 
422 private void
423 insert_PNode_internal(Parser *p, PNode *pn) {
424   PNodeHash *ph = &p.pnode_hash;
425   uint h = PNODE_HASH(pn.parse_node.start_loc.s, pn.parse_node.end_skip,
426                       pn.parse_node.symbol, pn.initial_scope, pn.initial_globals), i;
427 
428   if (ph.n + 1 > ph.v.length) {
429     PNode *[]v = ph.v;
430     auto m = v.length;
431     ph.i++;
432     ph.v = new PNode *[d_prime2[ph.i]];
433     for (i = 0; i < m; i++)
434     {
435       PNode *t = v[i];
436       while (t) {
437         v[i] = v[i].bucket_next;
438         insert_PNode_internal(p, t);
439         t = v[i];
440       }
441     }
442   }
443   pn.bucket_next = ph.v[h % $];
444   ph.v[h % $] = pn;
445   ph.n++;
446 }
447 
448 private void
449 insert_PNode(Parser *p, PNode *pn) {
450   insert_PNode_internal(p, pn);
451   pn.all_next = p.pnode_hash.all;
452   p.pnode_hash.all = pn;
453 }
454 
455 private void
456 free_old_nodes(Parser *p) {
457   uint h;
458   PNode *pn = p.pnode_hash.all;
459   PNode* tpn;
460   SNode *sn = p.snode_hash.all;
461   SNode*tsn;
462   while (sn) {
463     h = SNODE_HASH(sn.stateIndex, sn.initial_scope, sn.initial_globals);
464     SNode** lsn = &p.snode_hash.v[h % $];
465     tsn = sn; sn = sn.all_next;
466     while (*lsn != tsn) lsn = &(*lsn).bucket_next;
467     *lsn = (*lsn).bucket_next;
468   }
469   sn = p.snode_hash.last_all;
470   p.snode_hash.last_all = null;
471   while (sn) {
472     tsn = sn; sn = sn.all_next;
473   }
474   p.snode_hash.last_all = p.snode_hash.all;
475   p.snode_hash.all = null;
476   while (pn) {
477     foreach (ref c; pn.children) {
478       while (c != c.latest) {
479         tpn = c.latest;
480         c = tpn;
481       }
482     }
483     h = PNODE_HASH(pn.parse_node.start_loc.s, pn.parse_node.end_skip,
484                    pn.parse_node.symbol, pn.initial_scope, pn.initial_globals);
485     PNode** lpn = &p.pnode_hash.v[h % $];
486     tpn = pn; pn = pn.all_next;
487     while (*lpn != tpn) lpn = &(*lpn).bucket_next;
488     *lpn = (*lpn).bucket_next;
489   }
490   p.pnode_hash.n = 0;
491   p.pnode_hash.all = null;
492 }
493 
494 private void
495 alloc_parser_working_data(Parser *p) {
496   p.pnode_hash.i = PNODE_HASH_INITIAL_SIZE_INDEX;
497   p.pnode_hash.v = new PNode*[d_prime2[p.pnode_hash.i]];
498   p.snode_hash.i = SNODE_HASH_INITIAL_SIZE_INDEX;
499   p.snode_hash.v = new SNode*[d_prime2[p.snode_hash.i]];
500   p.shift_results = null;
501   p.code_shifts = null;
502 }
503 
504 private void
505 free_parser_working_data(Parser *p) {
506   free_old_nodes(p);
507   free_old_nodes(p); /* to catch SNodes saved for error repair */
508   p.pnode_hash = p.pnode_hash.init;
509   p.snode_hash = p.snode_hash.init;
510   while (p.reductions_todo) {
511     Reduction *r = p.free_reductions.next;
512     FREE(p.free_reductions); p.free_reductions = r;
513   }
514   while (p.shifts_todo) {
515     Shift *s = p.free_shifts.next;
516     FREE(p.free_shifts); p.free_shifts = s;
517   }
518   while (p.free_reductions) {
519     Reduction *r = p.free_reductions.next;
520     FREE(p.free_reductions); p.free_reductions = r;
521   }
522   while (p.free_shifts) {
523     Shift *s = p.free_shifts.next;
524     FREE(p.free_shifts); p.free_shifts = s;
525   }
526   while (p.free_pnodes) {
527     PNode *pn = p.free_pnodes.all_next;
528     FREE(p.free_pnodes); p.free_pnodes = pn;
529   }
530   while (p.free_znodes) {
531     ZNode *zn = znode_next(p.free_znodes);
532     FREE(p.free_znodes); p.free_znodes = zn;
533   }
534   while (p.free_snodes) {
535     SNode *sn = p.free_snodes.all_next;
536     FREE(p.free_snodes); p.free_snodes = sn;
537   }
538   vec_free(&p.error_reductions);
539   if (p.whitespace_parser)
540     free_parser_working_data(p.whitespace_parser);
541   p.shift_results = null;
542   p.code_shifts = null;
543 }
544 
545 private int
546 znode_depth(ZNode *z) @safe {
547   int i, d = 0;
548   if (!z)
549     return int.max;
550   for (i = 0; i < z.sns.n; i++)
551     d = d < z.sns[i].depth ? z.sns[i].depth : d;
552   return d;
553 }
554 
555 private Reduction *
556 add_Reduction(Parser *p, ZNode *z, SNode *sn, D_Reduction *reduction) @safe {
557   Reduction **l = &p.reductions_todo;
558   int d = znode_depth(z), dd;
559   for (Reduction* x = p.reductions_todo; x; l = &x.next, x = x.next) {
560     if (sn.loc.s < x.snode.loc.s)
561       break;
562     dd = znode_depth(x.znode);
563     if ((sn.loc.s == x.snode.loc.s && d >= dd)) {
564       if (d == dd)
565         while (x) {
566           if (sn == x.snode && z == x.znode && reduction == x.reduction)
567             return null;
568           x = x.next;
569         }
570       break;
571     }
572   }
573   {
574     Reduction *r = p.free_reductions;
575     if (!r)
576       r = new Reduction();
577     else
578       p.free_reductions = r.next;
579     r.znode = z;
580     r.snode = sn;
581     r.new_snode = null;
582     r.reduction = reduction;
583     r.next = *l;
584     *l = r;
585     return r;
586   }
587 }
588 
589 private void
590 add_Shift(Parser *p, SNode *snode) @safe {
591   Shift **l = &p.shifts_todo;
592   Shift *s = p.free_shifts;
593   if (!s)
594     s = new Shift();
595   else
596     p.free_shifts = s.next;
597   s.snode = snode;
598   for (Shift* x = p.shifts_todo; x; l = &x.next, x = x.next)
599     if (snode.loc.s <= x.snode.loc.s) break;
600   s.next = *l;
601   *l = s;
602 }
603 
604 private SNode *
605 add_SNode(Parser *p, uint stateIndex, d_loc_t *loc, D_Scope *sc, void *g) {
606   SNode *sn = find_SNode(p, stateIndex, sc, g);
607   if (sn)
608     return sn;
609   sn = new_SNode(p, stateIndex, loc, sc, g);
610   auto state = &p.t.states[stateIndex];
611   if (state.shifts)
612     add_Shift(p, sn);
613   foreach(r; state.reductions)
614     if (!r.nelements)
615       add_Reduction(p, null, sn, r);
616   return sn;
617 }
618 
619 private int
620 reduce_actions(Parser *p, PNode *pn, D_Reduction *r) {
621   int height = 0;
622 
623   foreach (c; pn.children) {
624     if (c.op_assoc) {
625       pn.assoc = c.op_assoc;
626       pn.priority = c.op_priority;
627     }
628     if (c.height >= height)
629       height = c.height + 1;
630   }
631 
632   pn.op_assoc = cast(AssocKind)r.op_assoc;
633   pn.op_priority = r.op_priority;
634   pn.height = height;
635   if (r.rule_assoc) {
636     pn.assoc = cast(AssocKind)r.rule_assoc;
637     pn.priority = r.rule_priority;
638   }
639   if (r.speculative_code)
640     return r.speculative_code(
641       pn, cast(void**)pn.children.v, cast(int)pn.children.n,
642       cast(int)&(cast(PNode*)null).parse_node, p);
643   return 0;
644 }
645 
646 enum x  = 666; /* impossible */
647 private int[6][3][4] child_table = [
648 [
649 /* binary parent, child on left */
650   /* priority of child vs parent, or = with child|parent associativity
651      > < =LL =LR =RL =RR
652    */
653   [ 1, 0, 1, 1, 0, 0], /* binary child */
654   [ 1, 1, 1, 1, x, x], /* left unary child */
655   [ 1, 0, x, x, 1, 1]  /* right unary child */
656 ],
657 [ /* binary parent, child on right */
658   [ 1, 0, 0, 0, 1, 1], /* binary child */
659   [ 1, 0, 1, 1, x, x], /* left unary child */
660   [ 1, 1, x, x, 1, 1]  /* right unary child */
661 ],
662 [ /* left unary parent */
663   [ 1, 0, 0, x, 0, x], /* binary child */
664   [ 1, 1, 1, x, x, x], /* left unary child */
665   [ 1, 0, x, x, 1, x]  /* right unary child */
666 ],
667 [ /* right unary parent */
668   [ 1, 0, x, 0, x, 0], /* binary child */
669   [ 1, 0, x, 1, x, x], /* left unary child */
670   [ 1, 1, x, x, x, 1]  /* right unary child */
671 ]
672 ];
673 
674 /* returns 1 if legal for child reduction and illegal for child shift */
675 private int
676 check_child(int ppri, AssocKind passoc, int cpri, AssocKind cassoc,
677             int left, int right)
678 {
679   int p = IS_BINARY_NARY_ASSOC(passoc) ? (right ? 1 : 0) :
680           (passoc == AssocKind.ASSOC_UNARY_LEFT ? 2 : 3);
681   int c = IS_BINARY_NARY_ASSOC(cassoc) ? 0 :
682           (cassoc == AssocKind.ASSOC_UNARY_LEFT ? 1 : 2);
683   int r =
684     cpri > ppri ? 0 : (
685       cpri < ppri ? 1 : ( 2 + (
686         (IS_RIGHT_ASSOC(cassoc) ? 2 : 0) +
687         (IS_RIGHT_ASSOC(passoc) ? 1 : 0))));
688   return child_table[p][c][r];
689 }
690 
691 /* check assoc/priority legality, 0 is OK, -1 is bad */
692 private int
693 check_assoc_priority(PNode *pn0, PNode *pn1, PNode *pn2) {
694   if (!IS_UNARY_BINARY_ASSOC(pn0.op_assoc)) {
695     if (IS_UNARY_BINARY_ASSOC(pn1.op_assoc)) { /* second token is operator */
696       /* check expression pn0 (child of pn1) */
697       if (pn0.assoc) {
698         if (!check_child(pn1.op_priority, pn1.op_assoc,
699                          pn0.priority, pn0.assoc, 0, 1))
700         return -1;
701       }
702     }
703   } else { /* pn0 is an operator */
704     if (pn1.op_assoc) {
705       /* check pn0 (child of operator pn1) */
706       if (!check_child(pn1.op_priority, pn1.op_assoc,
707                        pn0.op_priority, pn0.op_assoc, 0, 1))
708         return -1;
709     } else if (pn2) {
710       /* check pn0 (child of operator pn2) */
711       if (pn2.op_assoc &&
712           !check_child(pn2.op_priority, pn2.op_assoc,
713                        pn0.op_priority, pn0.op_assoc, 0, 1))
714         return -1;
715     }
716     /* check expression pn1 (child of pn0)  */
717     if (pn1.assoc) {
718       if (!check_child(pn0.op_priority, pn0.op_assoc,
719                        pn1.priority, pn1.assoc, 1, 0))
720         return -1;
721     }
722   }
723   return 0;
724 }
725 
726 /* check to see if a path is legal with respect to
727    the associativity and priority of its operators */
728 private int
729 check_path_priorities_internal(ref VecZNode path) {
730   bool one = false;
731 
732   if (path.length == 0) return 0;
733 
734   int i = 0;
735   PNode *pn0 = path[i].pn;
736   if (!pn0.op_assoc) { /* deal with top expression directly */
737     i = 1;
738     if (path.n < i + 1)
739       return 0;
740     PNode *pn1 = path[i].pn;
741     if (!pn1.op_assoc)
742       return 0;
743     if (pn0.assoc) {
744       if (!check_child(pn1.op_priority, pn1.op_assoc,
745                        pn0.priority, pn0.assoc, 0, 1))
746         return -1;
747     }
748     pn0 = pn1;
749   }
750   if (path.n > i + 1) { /* entirely in the path */
751     PNode *pn1 = path[i + 1].pn;
752     if (path.n > i + 2)
753       return check_assoc_priority(pn0, pn1, path[i + 2].pn);
754     else { /* one level from the stack beyond the path */
755       foreach (k; path[i + 1].sns)
756         foreach (zz; k.zns) {
757           one = true;
758           if (zz && !check_assoc_priority(pn0, pn1, zz.pn))
759             return 0;
760         }
761       if (!one)
762         return check_assoc_priority(pn0, pn1, null);
763     }
764   } else { /* two levels from the stack beyond the path */
765     foreach (k; path[i].sns)
766       foreach (zz; k.zns) {
767         if (zz)
768           foreach (kk; zz.sns)
769             foreach (zzz; kk.zns) {
770               if (zzz && !check_assoc_priority(pn0, zz.pn, zzz.pn))
771                 return 0;
772             }
773       }
774     return 0;
775   }
776   return -1;
777 }
778 
779 /* avoid cases without operator priorities */
780 bool check_path_priorities(ref VecZNode _p)
781 {
782     return (_p.n > 1                  && 
783    (_p[0].pn.op_assoc || _p[1].pn.op_assoc)       && 
784    check_path_priorities_internal(_p));
785 }
786 
787 private int
788 compare_priorities(int* xpri, int xn, int* ypri, int yn) {
789   int i = 0;
790 
791   while (i < xn && i < yn) {
792     if (xpri[i] > ypri[i])
793       return -1;
794     if (xpri[i] < ypri[i])
795       return 1;
796     i++;
797   }
798   return 0;
799 }
800 
801 private void
802 intreverse(int *xp, int n) {
803   int *a = xp, b = xp + n -1;
804   while (a < b) {
805     int t = *a;
806     *a = *b;
807     *b = t;
808     a++; b--;
809   }
810 }
811 
812 /* sort by deepest, then by location */
813 private void
814 priority_insert(StackPNode *psx, PNode *x) {
815   PNode *t;
816   PNode** start, cur;
817 
818   stack_push(psx, x);
819   start = psx.start;
820   cur = psx.cur;
821   for (;cur > start + 1;cur--) {
822     if (cur[-1].height > cur[-2].height)
823       continue;
824     if (cur[-1].height == cur[-2].height &&
825         cur[-1].parse_node.start_loc.s > cur[-2].parse_node.start_loc.s)
826       continue;
827     t = cur[-1];
828     cur[-1] = cur[-2];
829     cur[-2] = t;
830   }
831 }
832 
833 private void
834 get_exp_all(Parser *p, PNode *x, StackInt *psx) {
835   if (x.assoc)
836     stack_push(psx, x.priority);
837   foreach (pn; x.children) {
838     LATEST(pn);
839     get_exp_all(p, pn, psx);
840   }
841 }
842 
843 private void
844 get_exp_one(Parser *p, PNode *x, StackPNode *psx, StackInt *isx) {
845   LATEST(x);
846   if (!IS_NARY_ASSOC(x.assoc))
847     priority_insert(psx, x);
848   else {
849     stack_push(isx, x.priority);
850     foreach (i; x.children)
851       if (i.assoc)
852         get_exp_one(p, i, psx, isx);
853   }
854 }
855 
856 private void
857 get_exp_one_down(Parser *p, PNode *x, StackPNode *psx, StackInt *isx) {
858   LATEST(x);
859   stack_push(isx, x.priority);
860   foreach (i; x.children)
861     if (i.assoc)
862       get_exp_one(p, i, psx, isx);
863 }
864 
865 /* get the set of priorities for unshared nodes,
866    eliminating shared subtrees via priority queues */
867 private void
868 get_unshared_priorities(Parser *p, StackPNode *psx, StackPNode *psy,
869                         StackInt *isx, StackInt *isy)
870 {
871   StackPNode *psr;
872   while (1) {
873     if (is_stack_empty(psx)) {
874       psr = psy;
875       break;
876     } else if (is_stack_empty(psy)) {
877       psr = psx;
878       break;
879     }
880     if (stack_head(psx).height > stack_head(psy).height)
881       psr = psx;
882     else if (stack_head(psx).height < stack_head(psy).height)
883       psr = psy;
884     else if (stack_head(psx) > stack_head(psy))
885       psr = psx;
886     else if (stack_head(psx) < stack_head(psy))
887       psr = psy;
888     else {
889       stack_pop(psx);
890       stack_pop(psy);
891       continue;
892     }
893     PNode *t = stack_pop(psr);
894     if (psr == psx)
895       get_exp_one_down(p, t, psx, isx);
896     else
897       get_exp_one_down(p, t, psy, isy);
898   }
899   while (!is_stack_empty(psr)) {
900     PNode *t = stack_pop(psr);
901     if (psr == psx)
902       get_exp_all(p, t, isx);
903     else
904       get_exp_all(p, t, isy);
905   }
906   return;
907 }
908 
909 /* compare the priorities of operators in two trees
910    while eliminating common subtrees for efficiency.
911 */
912 private int
913 cmp_priorities(Parser *p, PNode *x, PNode *y) {
914   StackPNode psx, psy;
915   StackInt isx, isy;
916 
917   stack_clear(&psx); stack_clear(&psy); stack_clear(&isx); stack_clear(&isy);
918   get_exp_one(p, x, &psx, &isx);
919   get_exp_one(p, y, &psy, &isy);
920   get_unshared_priorities(p, &psx, &psy, &isx, &isy);
921   intreverse(isx.start, stack_depth(&isx));
922   intreverse(isy.start, stack_depth(&isy));
923   int r = compare_priorities(isx.start, stack_depth(&isx),
924                      isy.start, stack_depth(&isy));
925   stack_free(&psx); stack_free(&psy); stack_free(&isx); stack_free(&isy);
926   return r;
927 }
928 
929 private void
930 get_all(Parser *p, PNode *x, ref bool[PNode*] vx) {
931   if (x !in vx) {
932     vx[x] = true;
933     foreach (pn; x.children) {
934       LATEST(pn);
935       get_all(p, pn, vx);
936     }
937   }
938 }
939 
940 private void
941 get_unshared_pnodes(Parser *p, PNode *x, PNode *y, ref PNode*[] pvx, ref PNode*[] pvy) {
942   bool[PNode*] vx, vy;
943 
944   LATEST(x); LATEST(y);
945   get_all(p, x, vx);
946   get_all(p, y, vy);
947   foreach (i, _; vx)
948     if (i && i !in vy)
949       pvx ~= cast(PNode*)i;
950   foreach (i, _; vy)
951     if (i && i !in vx)
952       pvy ~= cast(PNode*)i;
953 }
954 
955 int
956 greedycmp(PNode* x, PNode* y) @safe {
957   // first by start
958   if (x.parse_node.start_loc.s < y.parse_node.start_loc.s)
959     return -1;
960   if (x.parse_node.start_loc.s > y.parse_node.start_loc.s)
961     return 1;
962   // second by symbol
963   if (x.parse_node.symbol < y.parse_node.symbol)
964     return -1;
965   if (x.parse_node.symbol > y.parse_node.symbol)
966     return 1;
967   // third by length
968   if (x.parse_node.end < y.parse_node.end)
969     return -1;
970   if (x.parse_node.end > y.parse_node.end)
971     return 1;
972   return 0;
973 }
974 
975 bool PNodeIsLessGreedyThanPNode(PNode* x, PNode* y) @safe
976 {
977     return greedycmp(x, y) < 0;
978 }
979 
980 private int
981 cmp_greediness(Parser *p, PNode *x, PNode *y) {
982   PNode*[] pvx, pvy;
983   get_unshared_pnodes(p, x, y, pvx, pvy);
984   /* set_to_vec(&pvx); set_to_vec(&pvy); */
985   pvx.sort!(PNodeIsLessGreedyThanPNode)();
986   pvy.sort!(PNodeIsLessGreedyThanPNode)();
987 
988   int ix = 0, iy = 0;
989   while (1) {
990       if (pvx.length <= ix || pvy.length <= iy)
991           return(0);
992       x = pvx[ix]; y = pvy[iy];
993       if (x == y) {
994           ix++;
995           iy++;
996       } else if (x.parse_node.start_loc.s < y.parse_node.start_loc.s)
997           ix++;
998       else if (x.parse_node.start_loc.s > y.parse_node.start_loc.s)
999           iy++;
1000       else if (x.parse_node.symbol < y.parse_node.symbol)
1001           ix++;
1002       else if (x.parse_node.symbol > y.parse_node.symbol)
1003           iy++;
1004       else if (x.parse_node.end > y.parse_node.end)
1005           return(-1);
1006       else if (x.parse_node.end < y.parse_node.end)
1007           return(1);
1008       else if (x.children.n < y.children.n)
1009           return(-1);
1010       else if (x.children.n > y.children.n)
1011           return(1);
1012       else {
1013           ix++;
1014           iy++;
1015       }
1016   }
1017 }
1018 
1019 int
1020 resolve_amb_greedy(D_Parser *dp, int n, D_ParseNode **v) {
1021   int i, result, selected_node = 0;
1022 
1023   for(i=1; i<n; i++) {
1024      result = cmp_greediness(dp, D_ParseNode_to_PNode(v[i]),D_ParseNode_to_PNode( v[selected_node]) );
1025      if ( result < 0 ||
1026          (result == 0 && D_ParseNode_to_PNode(v[i]).height < D_ParseNode_to_PNode(v[selected_node]).height) )
1027         selected_node = i;
1028   }
1029   return selected_node;
1030 }
1031 
1032 /* return -1 for x, 1 for y and 0 if they are ambiguous */
1033 private int
1034 cmp_pnodes(Parser *p, PNode *x, PNode *y) {
1035   int r = 0;
1036   if (x.assoc && y.assoc) {
1037     r = cmp_priorities(p, x, y);
1038     if (r)
1039       return r;
1040   }
1041   if (!p.dont_use_greediness_for_disambiguation)
1042   {
1043     r = cmp_greediness(p, x, y);
1044     if (r)
1045       return r;
1046   }
1047   if (!p.dont_use_height_for_disambiguation) {
1048     if (x.height < y.height)
1049       return -1;
1050     if (x.height > y.height)
1051       return 1;
1052   }
1053   return r;
1054 }
1055 
1056 private PNode *
1057 make_PNode(Parser *p, uint hash, int symbol, d_loc_t *start_loc, const char *e, PNode *pn,
1058            D_Reduction *r, VecZNode *path, const D_Shift *sh, D_Scope *scope_)
1059 {
1060   int l = cast(int)(PNode.sizeof - d_voidp.sizeof + p.sizeof_user_parse_node);
1061   PNode *new_pn = p.free_pnodes;
1062   if (!new_pn)
1063     new_pn = cast(PNode*)MALLOC(l);
1064   else
1065     p.free_pnodes = new_pn.all_next;
1066   p.pnodes++;
1067   memset(new_pn, 0, l);
1068   new_pn.hash = hash;
1069   new_pn.parse_node.symbol = symbol;
1070   new_pn.parse_node.start_loc = *start_loc;
1071   new_pn.ws_before = start_loc.ws;
1072   if (!r || !path) /* end of last parse node of path for non-epsilon reductions */
1073     new_pn.parse_node.end = e;
1074   else
1075     new_pn.parse_node.end = pn.parse_node.end;
1076   new_pn.parse_node.end_skip = e;
1077   new_pn.shift = sh;
1078   new_pn.reduction = r;
1079   new_pn.parse_node.scope_ = pn.parse_node.scope_;
1080   new_pn.initial_scope = scope_;
1081   new_pn.parse_node.globals = pn.parse_node.globals;
1082   new_pn.initial_globals = new_pn.parse_node.globals;
1083   new_pn.parse_node.white_space = pn.parse_node.white_space;
1084   new_pn.latest = new_pn;
1085   new_pn.ws_after = e;
1086   if (sh) {
1087     new_pn.op_assoc = cast(AssocKind)sh.op_assoc;
1088     new_pn.op_priority = sh.op_priority;
1089     if (sh.speculative_code && sh.action_index != -1) {
1090       D_Reduction dummy;
1091       dummy.action_index = sh.action_index;
1092       new_pn.reduction = &dummy;
1093       if (sh.speculative_code(
1094         new_pn, cast(void**)new_pn.children.v, new_pn.children.n,
1095         cast(int)&(cast(PNode*)(null)).parse_node, p))
1096       {
1097         free_PNode(p, new_pn);
1098         return null;
1099       }
1100       new_pn.reduction = null;
1101     }
1102   } else if (r) {
1103     if (path)
1104       foreach_reverse (i; *path) {
1105         PNode *latest = i.pn;
1106         LATEST(latest);
1107         vec_add(&new_pn.children, latest);
1108       }
1109     if (reduce_actions(p, new_pn, r)) {
1110       free_PNode(p, new_pn);
1111       return null;
1112     }
1113     if (path && path.n > 1) {
1114       int n = path.n;
1115       for (int i = 0; i < n; i += n-1) {
1116         PNode *child = new_pn.children[i];
1117         if (child.assoc && new_pn.assoc &&
1118             !check_child(new_pn.priority, new_pn.assoc,
1119                          child.priority, child.assoc, i == 0, i == n - 1))
1120         {
1121           free_PNode(p, new_pn);
1122           return null;
1123         }
1124       }
1125     }
1126   }
1127   return new_pn;
1128 }
1129 
1130 private int
1131 PNode_equal(Parser *p, PNode *pn, D_Reduction *r, VecZNode *path, const D_Shift* sh) {
1132   int i, n = pn.children.n;
1133   if (sh)
1134     return sh == pn.shift;
1135   if (r != pn.reduction)
1136     return 0;
1137   if (!path && !n)
1138     return 1;
1139   if (n == path.n) {
1140     for (i = 0; i < n; i++) {
1141       PNode *x = pn.children[i], y = (*path)[n - i - 1].pn;
1142       LATEST(x);
1143       LATEST(y);
1144       if (x != y)
1145         return 0;
1146     }
1147     return 1;
1148   }
1149   return 0;
1150 }
1151 
1152 /* find/create PNode */
1153 private PNode *
1154 add_PNode(Parser *p, int symbol, d_loc_t *start_loc, const char *e, PNode *pn,
1155           D_Reduction *r, VecZNode *path, const D_Shift* sh)
1156 {
1157   D_Scope *scope_ = equiv_D_Scope(pn.parse_node.scope_);
1158   uint hash;
1159   PNode *old_pn = find_PNode(p, start_loc.s, e, symbol, scope_, pn.parse_node.globals, &hash);
1160   if (old_pn) {
1161     if (PNode_equal(p, old_pn, r, path, sh))
1162       return old_pn;
1163     for (PNode *amb = old_pn.ambiguities; amb; amb = amb.ambiguities) {
1164       if (PNode_equal(p, amb, r, path, sh))
1165         return old_pn;
1166     }
1167   }
1168   PNode *new_pn = make_PNode(p, hash, symbol, start_loc, e, pn, r, path, sh, scope_);
1169   if (!old_pn) {
1170     old_pn = new_pn;
1171     if (!new_pn)
1172       return null;
1173     insert_PNode(p, new_pn);
1174     return old_pn;
1175   }
1176   if (!new_pn)
1177     return old_pn;
1178   p.compares++;
1179   switch (cmp_pnodes(p, new_pn, old_pn)) {
1180     case 0:
1181       new_pn.ambiguities = old_pn.ambiguities;
1182       old_pn.ambiguities = new_pn;
1183       break;
1184     case -1:
1185       insert_PNode(p, new_pn);
1186       LATEST(old_pn);
1187       old_pn.latest = new_pn;
1188       old_pn = new_pn;
1189       break;
1190     case 1:
1191       free_PNode(p, new_pn);
1192       break;
1193     default:
1194   }
1195   return old_pn;
1196 }
1197 
1198 /* The set of znodes associated with a state can be very large
1199    because of cascade reductions (for example, large expression trees).
1200    Use an adaptive data structure starting with a short list and
1201    then falling back to a direct map hash table.
1202 */
1203 
1204 private void
1205 set_union_znode(ref VecZNode v, VecZNode *vv) {
1206   foreach(z; *vv)
1207     if (z)
1208       set_add_znode(v, z);
1209 }
1210 
1211 private ZNode *
1212 set_find_znode(ref VecZNode v, PNode *pn) {
1213   uint i, j, n = v.n, h;
1214   if (n <= INTEGRAL_VEC_SIZE) {
1215     for (i = 0; i < n; i++)
1216       if (v[i].pn == pn)
1217         return v[i];
1218     return null;
1219   }
1220   h = (cast(uintptr_t)pn) % n;
1221   for (i = h, j = 0;
1222        i < v.n && j < SET_MAX_SEQUENTIAL;
1223        i = ((i + 1) % n), j++)
1224   {
1225     if (!v[i])
1226       return null;
1227     else if (v[i].pn == pn)
1228       return v[i];
1229   }
1230   return null;
1231 }
1232 
1233 private void
1234 set_add_znode_hash(ref VecZNode v, ZNode *z) {
1235   VecZNode vv;
1236   vec_clear(&vv);
1237   int i, j, n = v.n;
1238   if (n) {
1239     uint h = cast(uint)((cast(uintptr_t)z.pn) % n);
1240     for (i = h, j = 0;
1241          i < v.n && j < SET_MAX_SEQUENTIAL;
1242          i = ((i + 1) % n), j++)
1243     {
1244       if (!v[i]) {
1245         v[i] = z;
1246         return;
1247       }
1248     }
1249   }
1250   if (!n) {
1251     vv.v = null;
1252     v.i = INITIAL_SET_SIZE_INDEX;
1253   } else {
1254     vv.v = cast(ZNode**)v.v;
1255     vv.n = v.n;
1256     v.i = v.i + 2;
1257   }
1258   v.n = d_prime2[v.i];
1259   v.v = cast(ZNode**)MALLOC(v.n * (void *).sizeof);
1260   if (vv.v) {
1261     set_union_znode(v, &vv);
1262   }
1263   set_add_znode(v, z);
1264 }
1265 
1266 private void
1267 set_add_znode(ref VecZNode v, ZNode *z) {
1268   int i, n = v.n;
1269   if (n < INTEGRAL_VEC_SIZE) {
1270     vec_add(&v, z);
1271     return;
1272   }
1273   if (n == INTEGRAL_VEC_SIZE) {
1274     VecZNode vv;
1275     vec_clear(&vv);
1276     vv = v;
1277     vec_clear(&v);
1278     for (i = 0; i < n; i++)
1279       set_add_znode_hash(v, vv[i]);
1280   }
1281   set_add_znode_hash(v, z);
1282 }
1283 
1284 private int GOTO_STATE(Parser* _p, PNode* _pn, SNode* _ps) @safe
1285 {
1286     auto offset = _p.t.states[_ps.stateIndex].goto_table_offset;
1287     return _p.t.goto_table[_pn.parse_node.symbol - offset] - 1;
1288 }
1289 
1290 private SNode *
1291 goto_PNode(Parser *p, d_loc_t *loc, PNode *pn, SNode *ps) {
1292   int i;
1293 
1294   if (!IS_BIT_SET(p.t.states[ps.stateIndex].goto_valid, pn.parse_node.symbol))
1295     return null;
1296   int state_index = GOTO_STATE(p, pn, ps);
1297   D_State *state = &p.t.states[state_index];
1298   SNode *new_ps = add_SNode(p, state_index, loc, pn.parse_node.scope_, pn.parse_node.globals);
1299   new_ps.last_pn = pn;
1300 
1301   debug(trace) logf("goto %d (%s) . %d %X\n",
1302              ps.stateIndex,
1303              p.t.symbols[pn.parse_node.symbol].name,
1304              state_index, new_ps);
1305   if (ps != new_ps && new_ps.depth < ps.depth + 1)
1306     new_ps.depth = ps.depth + 1;
1307   /* find/create ZNode */
1308   ZNode *z = set_find_znode(new_ps.zns, pn);
1309   if (!z) { /* not found */
1310     set_add_znode(new_ps.zns, (z = new_ZNode(p, pn)));
1311     foreach(r; state.reductions)
1312       if (r.nelements)
1313         add_Reduction(p, z, new_ps, r);
1314     if (!pn.shift)
1315       foreach(h; state.right_epsilon_hints) {
1316         SNode *pre_ps = find_SNode(p, h.preceeding_state, new_ps.initial_scope, new_ps.initial_globals);
1317         if (!pre_ps) continue;
1318         foreach (k; pre_ps.zns)
1319           if (k) {
1320             Reduction *r = add_Reduction(p, k, pre_ps, h.reduction);
1321             if (r) {
1322               r.new_snode = new_ps;
1323               r.new_depth = h.depth;
1324             }
1325           }
1326       }
1327   }
1328   for (i = 0; i < z.sns.n; i++)
1329     if (z.sns[i] == ps) break;
1330   if (i >= z.sns.n) { /* not found */
1331     vec_add(&z.sns, ps);
1332   }
1333   return new_ps;
1334 }
1335 
1336 void
1337 parse_whitespace(D_Parser *ap, d_loc_t *loc, void **p_globals) {
1338   Parser *pp = ap.whitespace_parser;
1339   pp.start = loc.s;
1340   if (!exhaustive_parse(pp, ap.t.whitespace_state)) {
1341     if (pp.accept) {
1342       int old_col = loc.col, old_line = loc.line;
1343       *loc = pp.accept.loc;
1344       if (loc.line == 1)
1345         loc.col = old_col + loc.col;
1346       loc.line = old_line + (pp.accept.loc.line - 1);
1347       pp.accept = null;
1348     }
1349   }
1350 }
1351 
1352 private void
1353 shift_all(Parser *p, const char *pos) {
1354     int i, j, nshifts = 0, ncode = 0;
1355     d_loc_t loc, skip_loc;
1356     D_WhiteSpaceFn skip_fn = null;
1357     ShiftResult *r;
1358     Shift *saved_s = p.shifts_todo, s = saved_s, ss;
1359 
1360     loc = s.snode.loc;
1361     skip_loc.s = null;
1362 
1363     s = p.shifts_todo;
1364     while (s && s.snode.loc.s == pos) {
1365         if (p.shift_results.length - nshifts < p.t.symbols.length * 2) {
1366             p.shift_results.length = nshifts + p.t.symbols.length * 3;
1367         }
1368         p.shifts_todo = p.shifts_todo.next;
1369         p.scans++;
1370         D_State *state = &p.t.states[s.snode.stateIndex];
1371         if (state.scanner_code) {
1372             if (p.code_shifts.length < ncode + 1) {
1373                 p.code_shifts.length = ncode + 2;
1374             }
1375             p.code_shifts[ncode].shift_kind = D_SCAN_ALL;
1376             p.code_shifts[ncode].term_priority = 0;
1377             p.code_shifts[ncode].op_assoc = 0;
1378             p.code_shifts[ncode].action_index = 0;
1379             p.code_shifts[ncode].speculative_code = null;
1380             p.shift_results[nshifts].loc = loc;
1381             if ((state.scanner_code(
1382                             &p.shift_results[nshifts].loc,
1383                             &p.code_shifts[ncode].symbol, &p.code_shifts[ncode].term_priority,
1384                             &p.code_shifts[ncode].op_assoc, &p.code_shifts[ncode].op_priority)))
1385             {
1386                 p.shift_results[nshifts].snode = s.snode;
1387                 p.shift_results[nshifts++].shift = &p.code_shifts[ncode++];
1388             }
1389         }
1390         if (state.scanner_table) {
1391             int n = scan_buffer(loc, *state, p.shift_results[nshifts .. $]);
1392             for (i = 0; i < n; i++)
1393                 p.shift_results[nshifts + i].snode = s.snode;
1394             nshifts += n;
1395         }
1396         s = p.shifts_todo;
1397     }
1398     for (i = 0; i < nshifts; i++) {
1399         r = &p.shift_results[i];
1400         if (!r.shift)
1401             continue;
1402         if (r.shift.shift_kind == D_SCAN_TRAILING) {
1403             int symbol = r.shift.symbol;
1404             SNode *sn = r.snode;
1405             r.shift = null;
1406             for (j = i + 1; j < nshifts; j++) {
1407                 if (p.shift_results[j].shift &&
1408                         sn == p.shift_results[j].snode &&
1409                         symbol == p.shift_results[j].shift.symbol) {
1410                     r.shift = p.shift_results[j].shift;
1411                     p.shift_results[j].shift = null;
1412                 }
1413             }
1414         }
1415         if (r.shift && r.shift.term_priority) {
1416             /* potentially n^2 but typically small */
1417             for (j = 0; j < nshifts; j++) {
1418                 if (!p.shift_results[j].shift)
1419                     continue;
1420                 if (r.loc.s == p.shift_results[j].loc.s && j != i) {
1421                     if (r.shift.term_priority < p.shift_results[j].shift.term_priority) {
1422                         r.shift = null;
1423                         break;
1424                     }
1425                     if (r.shift.term_priority > p.shift_results[j].shift.term_priority)
1426                         p.shift_results[j].shift = null;
1427                 }
1428             }
1429         }
1430     }
1431     for (i = 0; i < nshifts; i++) {
1432         r = &p.shift_results[i];
1433         if (!r.shift)
1434             continue;
1435         p.shifts++;
1436         debug(trace) logf("shift %d %X %d (%s)\n",
1437                 r.snode.stateIndex, r.snode, r.shift.symbol,
1438                 p.t.symbols[r.shift.symbol].name);
1439         PNode *new_pn = add_PNode(p, r.shift.symbol, &r.snode.loc, r.loc.s,
1440                 r.snode.last_pn, null, null, r.shift);
1441         if (new_pn) {
1442             if (!skip_loc.s || skip_loc.s != r.loc.s || skip_fn != new_pn.parse_node.white_space) {
1443                 skip_loc = r.loc;
1444                 skip_fn = new_pn.parse_node.white_space;
1445                 new_pn.parse_node.white_space(
1446                         p, &skip_loc, cast(void**)&new_pn.parse_node.globals);
1447                 skip_loc.ws = r.loc.s;
1448                 new_pn.ws_before = loc.ws;
1449                 new_pn.ws_after = skip_loc.s;
1450             }
1451             goto_PNode(p, &skip_loc, new_pn, r.snode);
1452         }
1453     }
1454     for (s = saved_s; s && s.snode.loc.s == pos;) {
1455         ss = s;
1456         s = s.next;
1457         ss.next = p.free_shifts;
1458         p.free_shifts = ss;
1459     }
1460 }
1461 
1462 private VecZNode path1; /* static first path for speed */
1463 
1464 private VecZNode *
1465 new_VecZNode(ref VecVecZNode paths, int n, int parent) {
1466   int i;
1467   VecZNode *pv;
1468 
1469   if (!paths.n)
1470     pv = &path1;
1471   else
1472     pv = new VecZNode();
1473   vec_clear(pv);
1474   if (parent >= 0)
1475     for (i = 0; i < n; i++)
1476       vec_add(pv, (*paths[parent])[i]);
1477   return pv;
1478 }
1479 
1480 private void
1481 build_paths_internal(ZNode *z, ref VecVecZNode paths, int parent,
1482                      int n, int n_to_go)
1483 {
1484   int j, k, l;
1485 
1486   vec_add(paths[parent], z);
1487   if (n_to_go <= 1)
1488     return;
1489   for (k = 0; k < z.sns.n; k++)
1490     for (j = 0, l = 0; j < z.sns[k].zns.n; j++) {
1491       if (z.sns[k].zns[j]) {
1492         if (k + l) {
1493           vec_add(&paths, new_VecZNode(paths, n - (n_to_go - 1), parent));
1494           parent = paths.n - 1;
1495         }
1496         build_paths_internal(z.sns[k].zns[j], paths, parent,
1497                              n, n_to_go - 1);
1498         l++;
1499       }
1500     }
1501 }
1502 
1503 private void
1504 build_paths(ZNode *z, ref VecVecZNode paths, int nchildren_to_go) {
1505   if (!nchildren_to_go)
1506     return;
1507   vec_add(&paths, new_VecZNode(paths, 0, -1));
1508   build_paths_internal(z, paths, 0, nchildren_to_go, nchildren_to_go);
1509 }
1510 
1511 private void
1512 reduce_one(Parser *p, Reduction *r) {
1513   SNode *sn = r.snode;
1514   PNode *pn;
1515   int j, n = r.reduction.nelements;
1516 
1517   if (!r.znode) { /* epsilon reduction */
1518     pn = add_PNode(p, r.reduction.symbol, &sn.loc,
1519                         sn.loc.s, sn.last_pn, r.reduction, null, null);
1520     if (pn)
1521       goto_PNode(p, &sn.loc, pn, sn);
1522   } else {
1523     debug(trace) logf("reduce %d %X %d\n", r.snode.stateIndex, sn, n);
1524     VecVecZNode paths;
1525     vec_clear(&paths);
1526     build_paths(r.znode, paths, n);
1527     foreach (path; paths) {
1528       if (r.new_snode) { /* prune paths by new right epsilon node */
1529         for (j = 0; j < (*path)[r.new_depth].sns.n; j++)
1530           if ((*path)[r.new_depth].sns[j] == r.new_snode)
1531             break;
1532         if (j >= (*path)[r.new_depth].sns.n)
1533           continue;
1534       }
1535       if (check_path_priorities(*path))
1536         continue;
1537       p.reductions++;
1538       PNode *last_pn = (*path)[0].pn;
1539       ZNode *first_z = (*path)[n - 1];
1540       pn = add_PNode(p, r.reduction.symbol,
1541                      &first_z.pn.parse_node.start_loc,
1542                      sn.loc.s, last_pn, r.reduction, path, null);
1543       if (pn)
1544         foreach (j; first_z.sns)
1545           goto_PNode(p, &sn.loc, pn, j);
1546     }
1547   }
1548   r.next = p.free_reductions;
1549   p.free_reductions = r;
1550 }
1551 
1552 private int
1553 VecSNode_equal(const ref VecSNode vsn1, const ref VecSNode vsn2) @safe nothrow pure {
1554   if (vsn1.n != vsn2.n)
1555     return 0;
1556   for (int i = 0; i < vsn1.n; i++) {
1557     int j;
1558     for (j = 0; j < vsn2.n; j++) {
1559       if (vsn1[i] == vsn2[j])
1560         break;
1561     }
1562     if (j >= vsn2.n)
1563       return 0;
1564   }
1565   return 1;
1566 }
1567 
1568 private ZNode *
1569 binary_op_ZNode(SNode *sn) @safe nothrow pure {
1570   ZNode *z;
1571   if (sn.zns.n != 1)
1572     return null;
1573   z = sn.zns[0];
1574   if (z.pn.op_assoc == AssocKind.ASSOC_UNARY_RIGHT) {
1575     if (z.sns.n != 1)
1576       return null;
1577     sn = z.sns[0];
1578     if (sn.zns.n != 1)
1579       return null;
1580     z = sn.zns[0];
1581   }
1582   if (!IS_BINARY_ASSOC(z.pn.op_assoc))
1583     return null;
1584   return z;
1585 }
1586 
1587 
1588 debug(trace) private const char *spaces = "                                                                                                  ";
1589 debug(trace) private void
1590 print_stack(Parser *p, SNode *s, int indent) {
1591   logf("%d", s.stateIndex);
1592   indent += 2;
1593   foreach (i; s.zns) {
1594     if (!i)
1595       continue;
1596     if (s.zns.n > 1)
1597       logf("\n%s[", &spaces[99-indent]);
1598     logf("(%s:", p.t.symbols[i.pn.parse_node.symbol].name);
1599     print_paren(p, i.pn);
1600     logf(")");
1601     foreach (j; i.sns) {
1602       if (i.sns.n > 1)
1603         logf("\n%s[", &spaces[98-indent]);
1604       print_stack(p, j, indent);
1605       if (i.sns.n > 1)
1606         logf("]");
1607     }
1608     if (s.zns.n > 1)
1609       logf("]");
1610   }
1611 }
1612 
1613 /* compare two stacks with operators on top of identical substacks
1614    eliminating the stack with the lower priority binary operator
1615    - used to eliminate unnecessary stacks created by the
1616      (empty) application binary operator
1617 */
1618 private void
1619 cmp_stacks(Parser *p) {
1620   Shift *a, b;
1621   Shift **al, bl;
1622   ZNode *az, bz;
1623 
1624   const char *pos = p.shifts_todo.snode.loc.s;
1625   debug(trace) {
1626     int i = 0;
1627     for (al = &p.shifts_todo, a = *al; a && a.snode.loc.s == pos;
1628          al = &a.next, a = a.next)
1629   {
1630     if (++i < 2) logf("\n");
1631     print_stack(p, a.snode, 0);
1632     logf("\n");
1633   }}
1634   for (al = &p.shifts_todo, a = *al; a && a.snode.loc.s == pos;
1635        al = &a.next, a = a.next)
1636   {
1637     az = binary_op_ZNode(a.snode);
1638     if (!az)
1639       continue;
1640     for (bl = &a.next, b = a.next; b && b.snode.loc.s == pos;
1641          bl = &b.next, b = b.next) {
1642       bz = binary_op_ZNode(b.snode);
1643       if (!bz)
1644         continue;
1645       if (!VecSNode_equal(az.sns, bz.sns))
1646         continue;
1647       if ((p.t.states[a.snode.stateIndex].reduces_to != b.snode.stateIndex) &&
1648           (p.t.states[b.snode.stateIndex].reduces_to != a.snode.stateIndex))
1649         continue;
1650       if (az.pn.op_priority > bz.pn.op_priority) {
1651         debug(trace){logf("DELETE ");
1652             print_stack(p, b.snode, 0);
1653             logf("\n");}
1654         *bl = b.next;
1655         b = *bl;
1656         break;
1657       }
1658       if (az.pn.op_priority < bz.pn.op_priority) {
1659         debug(trace){logf("DELETE ");
1660             print_stack(p, a.snode, 0);
1661             logf("\n");}
1662         *al = a.next;
1663         a = *al;
1664         goto Lbreak2;
1665       }
1666     }
1667   Lbreak2:;
1668   }
1669 }
1670 
1671 private void
1672 free_ParseTreeBelow(Parser *p, PNode *pn) {
1673   int i;
1674   PNode *amb;
1675 
1676   vec_free(&pn.children);
1677     amb = pn.ambiguities;
1678   if (amb) {
1679     pn.ambiguities = null;
1680     free_PNode(p, amb);
1681   }
1682 }
1683 
1684 void
1685 free_D_ParseTreeBelow(D_Parser *p, D_ParseNode *dpn) {
1686   free_ParseTreeBelow(p, DPN_TO_PN(dpn));
1687 }
1688 
1689 D_ParseNode *
1690 ambiguity_count_fn(D_Parser *p, int n, D_ParseNode **v) {
1691   p.ambiguities += n - 1;
1692   return v[0];
1693 }
1694 
1695 D_ParseNode *
1696 ambiguity_abort_fn(D_Parser *pp, int n, D_ParseNode **v) {
1697   int i;
1698   if (d_verbose_level) {
1699     for (i = 0; i < n; i++) {
1700       print_paren(pp, D_ParseNode_to_PNode(v[i]));
1701       logf("\n");
1702     }
1703   }
1704   d_fail("unresolved ambiguity line %d file %s", v[0].start_loc.line,
1705          v[0].start_loc.pathname);
1706   return v[0];
1707 }
1708 
1709 private int
1710 final_actionless(PNode *pn) {
1711   int i;
1712   if (pn.reduction && pn.reduction.final_code)
1713     return 0;
1714   for (i = 0; i < pn.children.n; i++)
1715     if (!final_actionless(pn.children[i]))
1716       return 0;
1717   return 1;
1718 }
1719 
1720 private PNode *
1721 resolve_ambiguities(Parser *p, PNode *pn) {
1722   PNode *amb;
1723   D_ParseNode *res;
1724   Vec!(D_ParseNode*) pns;
1725 
1726   vec_clear(&pns);
1727   bool efa = is_epsilon_PNode(pn) && final_actionless(pn);
1728   vec_add(&pns, &pn.parse_node);
1729   for (amb = pn.ambiguities; amb; amb = amb.ambiguities) {
1730     int i, found = 0;
1731     LATEST(amb);
1732     if (!p.dont_merge_epsilon_trees)
1733       if (efa && is_epsilon_PNode(amb) && final_actionless(amb))
1734         continue;
1735     for (i = 0; i < pns.n; i++)
1736       if (pns[i] == &amb.parse_node)
1737         found = 1;
1738     if (!found)
1739       vec_add(&pns, &amb.parse_node);
1740   }
1741   if (pns.n == 1) {
1742     res = pns[0];
1743     goto Ldone;
1744   }
1745   res = p.ambiguity_fn(cast(D_Parser *)p, pns.n, pns.v);
1746  Ldone:
1747   vec_free(&pns);
1748   return D_ParseNode_to_PNode(res);
1749 }
1750 
1751 private void
1752 fixup_internal_symbol(Parser *p, PNode *pn, int ichild) {
1753   PNode *child = pn.children[ichild];
1754   int j, n, pnn;
1755   n = child.children.n, pnn = pn.children.n;
1756   if (pn == child)
1757     d_fail("circular parse: unable to fixup internal symbol");
1758   if (n == 0) {
1759     for (j = ichild; j < pnn - 1; j++)
1760       pn.children[j] = pn.children[j + 1];
1761     pn.children.n--;
1762   } else if (n == 1) {
1763     pn.children[ichild] = child.children[0];
1764   } else {
1765     for (j = 0; j < n - 1; j++) /* expand children vector */
1766       vec_add(&pn.children, null);
1767     for (j = pnn - 1; j >= ichild + 1; j--) /* move to new places */
1768       pn.children[j - 1 + n] = pn.children[j];
1769     for (j = 0; j < n; j++) {
1770       pn.children[ichild + j] = child.children[j];
1771     }
1772   }
1773 }
1774 
1775 bool is_symbol_internal_or_EBNF(Parser* _p, PNode* _pn)
1776 {
1777     return (_p.t.symbols[_pn.parse_node.symbol].kind == D_SymbolKind.D_SYMBOL_INTERNAL ||
1778  _p.t.symbols[_pn.parse_node.symbol].kind == D_SymbolKind.D_SYMBOL_EBNF);
1779 }
1780 
1781 bool is_symbol_internal(Parser* _p, PNode* _pn)
1782 {
1783     return _p.t.symbols[_pn.parse_node.symbol].kind == D_SymbolKind.D_SYMBOL_INTERNAL;
1784 }
1785 
1786 bool is_unreduced_epsilon_PNode(PNode* _pn)
1787 {
1788     return is_epsilon_PNode(_pn) && (_pn.reduction && _pn.reduction.final_code);
1789 }
1790 
1791 private PNode *
1792 commit_tree(Parser *p, PNode *pn) {
1793   int i, fixup_ebnf = 0, fixup = 0, internal = 0;
1794   LATEST(pn);
1795   if (pn.evaluated)
1796     return pn;
1797   if (!is_unreduced_epsilon_PNode(pn))
1798     pn.evaluated = true;
1799   if (pn.ambiguities)
1800     pn = resolve_ambiguities(p, pn);
1801   fixup_ebnf = p.fixup_EBNF_productions;
1802   internal = is_symbol_internal_or_EBNF(p, pn);
1803   fixup = !p.dont_fixup_internal_productions && internal;
1804   for (i = 0; i < pn.children.n; i++) {
1805     PNode *tpn = commit_tree(p, pn.children[i]);
1806     if (tpn != pn.children[i]){
1807       pn.children[i] = tpn;
1808     }
1809     if (fixup &&
1810         (fixup_ebnf ? is_symbol_internal_or_EBNF(p, pn.children[i]) :
1811          is_symbol_internal(p, pn.children[i])))
1812     {
1813       fixup_internal_symbol(p, pn, i);
1814       i -= 1;
1815       continue;
1816     }
1817   }
1818   if (pn.reduction)
1819     debug(trace) logf("commit %X (%s)\n", pn, p.t.symbols[pn.parse_node.symbol].name);
1820   if (pn.reduction && pn.reduction.final_code)
1821     pn.reduction.final_code(
1822       pn, cast(void**)pn.children.v, pn.children.n,
1823       cast(int)&(cast(PNode*)(null)).parse_node, p);
1824   if (pn.evaluated) {
1825     if (!p.save_parse_tree && !internal)
1826       free_ParseTreeBelow(p, pn);
1827   }
1828   return pn;
1829 }
1830 
1831 private int
1832 commit_stack(Parser *p, SNode *sn) {
1833   int res = 0;
1834 
1835   if (sn.zns.n != 1)
1836     return -1;
1837   if (sn.zns[0].sns.n > 1)
1838     return -2;
1839   if (is_unreduced_epsilon_PNode(sn.zns[0].pn)) /* wait till reduced */
1840     return -3;
1841   if (sn.zns[0].sns.n)
1842     if ((res = commit_stack(p, sn.zns[0].sns[0])) < 0)
1843       return res;
1844   PNode *tpn = commit_tree(p, sn.zns[0].pn);
1845   if (tpn != sn.zns[0].pn){
1846       sn.zns[0].pn = tpn;
1847   }
1848   return res;
1849 }
1850 
1851 private const (char) *
1852 find_substr(const (char) *str, const(char)[] s) {
1853   auto len = s.length;
1854   if (len == 1) {
1855     while (*str && *str != s[0]) str++;
1856     if (*str == s[0])
1857       return str + 1;
1858   } else
1859     while (*str) {
1860       if (!strncmp(s.ptr, str, len))
1861         return str + len;
1862       str++;
1863     }
1864   return null;
1865 }
1866 
1867 private void
1868 syntax_error_report_fn(D_Parser *p) {
1869   const(char)[] fn = d_dup_pathname_str(p.loc.pathname);
1870   const(char)[] after;
1871   ZNode *z = p.snode_hash.last_all ? p.snode_hash.last_all.zns[0] : null;
1872   while (z && z.pn.parse_node.start_loc.s == z.pn.parse_node.end)
1873     z = (z.sns.v && z.sns[0].zns.v) ? z.sns[0].zns[0] : null;
1874   if (z && z.pn.parse_node.start_loc.s != z.pn.parse_node.end)
1875     after = z.pn.parse_node.matchedString;
1876   if (after)
1877     stderr.writefln("%s:%d: syntax error after '%s'", fn, p.loc.line, after);
1878     /* fprintf(stderr, "%s:%d: syntax error after '%s'\n", fn, p.loc.line, after); */
1879   else
1880     stderr.writefln("%s:%d: syntax error", fn, p.loc.line);
1881     /* fprintf(stderr, "%s:%d: syntax error\n", fn, p.loc.line); */
1882 }
1883 
1884 private void
1885 update_line(const (char) *s, const char *e, int *line) {
1886   for (;s < e; s++) if (*s == '\n') (*line)++;
1887 }
1888 
1889 private int
1890 error_recovery(Parser *p) {
1891   SNode *sn, best_sn = null;
1892   const (char) *best_s = null, ss, s;
1893   int head = 0, tail = 0, res = 1;
1894   D_ErrorRecoveryHint *best_er = null;
1895 
1896   if (!p.snode_hash.last_all)
1897     return res;
1898   p.loc = p.snode_hash.last_all.loc;
1899   if (!p.error_recovery)
1900     return res;
1901   SNode*[] q = new SNode*[ERROR_RECOVERY_QUEUE_SIZE];
1902   if (p.loc.line > p.last_syntax_error_line) {
1903     p.last_syntax_error_line = p.loc.line;
1904     p.syntax_errors++;
1905     p.syntax_error_fn(p);
1906   }
1907   for (sn = p.snode_hash.last_all; sn; sn = sn.all_next) {
1908     if (tail < ERROR_RECOVERY_QUEUE_SIZE - 1)
1909       q[tail++] = sn;
1910   }
1911   s = p.snode_hash.last_all.loc.s;
1912   while (tail > head) {
1913     sn = q[head++];
1914       foreach(ref rer; p.t.states[sn.stateIndex].error_recovery_hints) {
1915         ss = find_substr(s, rer.str);
1916         if (ss) {
1917           if (!best_sn || ss < best_s ||
1918               (best_sn && ss == best_s &&
1919                (best_sn.depth < sn.depth ||
1920                  (best_sn.depth == sn.depth &&
1921                    best_er.depth < rer.depth))))
1922           {
1923             best_sn = sn;
1924             best_s = ss;
1925             best_er = &rer;
1926           }
1927         }
1928       }
1929     foreach (i; sn.zns)
1930       if (i)
1931         foreach (j; i.sns) {
1932           if (tail < ERROR_RECOVERY_QUEUE_SIZE - 1)
1933             q[tail++] = j;
1934         }
1935   }
1936   if (best_sn) {
1937     d_loc_t best_loc = p.loc;
1938 
1939     D_Reduction *rr = new D_Reduction();
1940     vec_add(&p.error_reductions, rr);
1941     rr.nelements = cast(ushort)(best_er.depth + 1);
1942     rr.symbol = best_er.symbol;
1943     update_line(best_loc.s, best_s, &best_loc.line);
1944     best_loc.s = cast(char*)best_s;
1945     PNode *best_pn;
1946     foreach (i; best_sn.zns)
1947       if (i) {
1948         best_pn = i.pn;
1949         break;
1950       }
1951     best_pn.parse_node.white_space(
1952       p, &best_loc, cast(void**)&best_pn.parse_node.globals);
1953     PNode *new_pn = add_PNode(p, 0, &p.loc, best_loc.s, best_pn, null, null, null);
1954     SNode *new_sn = new_SNode(p, best_sn.stateIndex, &best_loc, new_pn.initial_scope, new_pn.initial_globals);
1955     new_sn.last_pn = new_pn;
1956     ZNode *z = new_ZNode(p, new_pn);
1957     set_add_znode(new_sn.zns, z);
1958     vec_add(&z.sns, best_sn);
1959     Reduction *r = new Reduction();
1960     r.znode = z;
1961     r.snode = new_sn;
1962     r.reduction = rr;
1963     r.new_snode = null;
1964     r.next = null;
1965     free_old_nodes(p);
1966     free_old_nodes(p);
1967     reduce_one(p, r);
1968     foreach (i; p.snode_hash.v)
1969       for (sn = i; sn; sn = sn.bucket_next)
1970         foreach (z; sn.zns)
1971         {
1972           if (z)
1973             if (z.pn.reduction == rr) {
1974               z.pn.evaluated = true;
1975               z.pn.error_recovery = true;
1976             }
1977         }
1978     if (p.shifts_todo || p.reductions_todo)
1979       res = 0;
1980   }
1981   return res;
1982 }
1983 
1984 bool PASS_CODE_FOUND(D_Pass* _p, PNode* _pn)
1985 {
1986     return (_pn.reduction && _pn.reduction.pass_code.length > _p.index &&
1987                                   _pn.reduction.pass_code[_p.index]);
1988 }
1989 
1990 private void
1991 pass_call(Parser *p, D_Pass *pp, PNode *pn) {
1992   if (PASS_CODE_FOUND(pp, pn))
1993     pn.reduction.pass_code[pp.index](
1994       pn, cast(void**)pn.children.v, pn.children.n,
1995       cast(int)&(cast(PNode*)(null)).parse_node, p);
1996 }
1997 
1998 private void
1999 pass_preorder(Parser *p, D_Pass *pp, PNode *pn) {
2000   int found = PASS_CODE_FOUND(pp, pn), i;
2001   pass_call(p, pp, pn);
2002   if ((pp.kind & D_PASS_FOR_ALL) ||
2003       ((pp.kind & D_PASS_FOR_UNDEFINED) && !found))
2004     for (i = 0; i < pn.children.n; i++)
2005       pass_preorder(p, pp, pn.children[i]);
2006 }
2007 
2008 private void
2009 pass_postorder(Parser *p, D_Pass *pp, PNode *pn) {
2010   int found = PASS_CODE_FOUND(pp, pn);
2011   if ((pp.kind & D_PASS_FOR_ALL) ||
2012       ((pp.kind & D_PASS_FOR_UNDEFINED) && !found))
2013     foreach (i; pn.children)
2014       pass_postorder(p, pp, i);
2015   pass_call(p, pp, pn);
2016 }
2017 
2018 void
2019 d_pass(D_Parser *p, D_ParseNode *apn, int pass_number) {
2020   PNode *pn = D_ParseNode_to_PNode(apn);
2021   D_Pass *pp;
2022 
2023   if (pass_number >= p.t.passes.length)
2024     d_fail("bad pass number: %d\n", pass_number);
2025   pp = &p.t.passes[pass_number];
2026   if (pp.kind & D_PASS_MANUAL)
2027     pass_call(p, pp, pn);
2028   else if (pp.kind & D_PASS_PRE_ORDER)
2029     pass_preorder(p, pp, pn);
2030   else if (pp.kind & D_PASS_POST_ORDER)
2031     pass_postorder(p, pp, pn);
2032 }
2033 
2034 private int
2035 exhaustive_parse(Parser *p, int state) {
2036   const(char) *pos, epos = null;
2037   PNode tpn;
2038   int progress = 0;
2039   d_loc_t loc;
2040 
2041   pos = p.loc.ws = p.loc.s = p.start;
2042   loc = p.loc;
2043   p.initial_white_space_fn(p, &loc, &p.initial_globals);
2044   /* initial state */
2045   SNode *sn = add_SNode(p, state, &loc, p.top_scope, p.initial_globals);
2046   tpn.parse_node.white_space = p.initial_white_space_fn;
2047   tpn.parse_node.globals = p.initial_globals;
2048   tpn.initial_scope = tpn.parse_node.scope_ = p.top_scope;
2049   tpn.parse_node.end = loc.s;
2050   PNode *pn = add_PNode(p, 0, &loc, loc.s, &tpn, null, null, null);
2051   sn.last_pn = pn;
2052   set_add_znode(sn.zns, new_ZNode(p, pn));
2053   while (1) {
2054     /* reduce all */
2055     while (p.reductions_todo) {
2056       pos = p.reductions_todo.snode.loc.s;
2057       if (p.shifts_todo && p.shifts_todo.snode.loc.s < pos)
2058         break;
2059       if (pos > epos) {
2060         epos = pos;
2061         free_old_nodes(p);
2062       }
2063       Reduction* r = p.reductions_todo;
2064       while (r && r.snode.loc.s == pos) {
2065         p.reductions_todo = p.reductions_todo.next;
2066         reduce_one(p, r);
2067         r = p.reductions_todo;
2068       }
2069     }
2070     /* done? */
2071     if (!p.shifts_todo) {
2072       if (p.accept &&
2073           (p.accept.loc.s == p.end || p.partial_parses))
2074         return 0;
2075       else {
2076         if (error_recovery(p))
2077           return 1;
2078         continue;
2079       }
2080     } else if (!p.dont_compare_stacks && p.shifts_todo.next)
2081       cmp_stacks(p);
2082     /* shift all */
2083     pos = p.shifts_todo.snode.loc.s;
2084     if (pos > epos) {
2085       epos = pos;
2086       free_old_nodes(p);
2087     }
2088     progress++;
2089     int ready = progress > p.commit_actions_interval;
2090     if (ready && !p.shifts_todo.next && !p.reductions_todo) {
2091       commit_stack(p, p.shifts_todo.snode);
2092       ready = progress = 0;
2093     }
2094     shift_all(p, pos);
2095     if (ready && p.reductions_todo && !p.reductions_todo.next) {
2096       commit_stack(p, p.reductions_todo.snode);
2097       progress = 0;
2098     }
2099   }
2100 }
2101 
2102 private bool wspace(char _x) // doesn't include nl
2103 {
2104     switch (_x)
2105     {
2106         case '\t', '\v', '\f', '\r', ' ': return true;
2107         default: return false;
2108     }
2109 }
2110 
2111 void advance(ref const(char)[] s, size_t n = 1)
2112 {
2113     assert(n <= s.length);
2114     s = s[n .. $];
2115     assert(s.length < 10000);
2116 }
2117 
2118 void
2119 white_space(D_Parser *p, d_loc_t *loc, void **p_user_globals) {
2120     int rec = 0;
2121     //const(char) *s = loc.s, scol = null;
2122     const(char)* scol;
2123     assert(p.end >= loc.s);
2124     const(char)[] s = loc.s[0 .. p.end - loc.s];
2125 
2126     if (s.length && s[0] == '#' && loc.col == 0) {
2127 Ldirective:
2128         {
2129             auto save = s;
2130             s.advance();
2131             while (s.length && wspace(s[0])) s.advance();
2132             if (s.startsWith("line")) {
2133                 if (wspace(s[4])) {
2134                     s.advance(5);
2135                     while (wspace(s[0])) s.advance();
2136                 }
2137             }
2138             if (isDigit(s[0])) {
2139                 loc.line = s.parse!uint() - 1;
2140                 while (wspace(s[0])) s.advance();
2141                 if (s[0] == '"')
2142                     loc.pathname = s.ptr;
2143             } else {
2144                 s = save;
2145                 goto Ldone;
2146             }
2147         }
2148         while (s.length && s[0] != '\n') s.advance();
2149     }
2150 Lmore:
2151     while (s.length && wspace(s[0])) { s.advance(); }
2152     if (s.length && s[0] == '\n') {
2153         loc.line++;
2154         s.advance();
2155         scol = s.ptr;
2156 
2157         if (s.length && s[0] == '#')
2158             goto Ldirective;
2159         else
2160             goto Lmore;
2161     }
2162     if (s.length && s[0] == '/') {
2163         if (s[1] == '/') {
2164             while (s.length && s[0] != '\n') { s.advance(); }
2165             goto Lmore;
2166         }
2167         if (s[1] == '*') {
2168             s.advance(2);
2169 LnestComment:
2170             rec++;
2171 LmoreComment:
2172             while (s.length) {
2173                 if (s[0] == '*' && s[1] == '/') {
2174                     s.advance(2);
2175                     rec--;
2176                     if (!rec)
2177                         goto Lmore;
2178                     goto LmoreComment;
2179                 }
2180                 if (s[0] == '/' && s[1] == '*') {
2181                     s.advance(2);
2182                     goto LnestComment;
2183                 }
2184                 if (s[0] == '\n') {
2185                     loc.line++;
2186                     scol = s.ptr + 1;
2187                 }
2188                 s.advance();
2189             }
2190         }
2191     }
2192 Ldone:
2193     assert(s.ptr <= p.end);
2194     if (scol)
2195         loc.col = cast(uint)(s.ptr - scol);
2196     else
2197         loc.col += s.ptr - loc.s;
2198     loc.s = s.ptr;
2199     return;
2200 }
2201 
2202 void null_white_space(D_Parser *p, d_loc_t *loc, void **p_globals) { }
2203 
2204 D_Parser *
2205 new_D_Parser(D_ParserTables *t, int sizeof_ParseNode_User) {
2206   Parser* p = new Parser();
2207   p.t = t;
2208   p.loc.line = 1;
2209   p.sizeof_user_parse_node = sizeof_ParseNode_User;
2210   p.commit_actions_interval = DEFAULT_COMMIT_ACTIONS_INTERVAL;
2211   p.syntax_error_fn = &syntax_error_report_fn;
2212   p.ambiguity_fn = &ambiguity_abort_fn;
2213   p.error_recovery = true;
2214   p.save_parse_tree = t.save_parse_tree;
2215   if (p.t.default_white_space)
2216     p.initial_white_space_fn = p.t.default_white_space;
2217   else if (p.t.whitespace_state)
2218     p.initial_white_space_fn = &parse_whitespace;
2219   else
2220     p.initial_white_space_fn = &white_space;
2221   return p;
2222 }
2223 
2224 void
2225 free_D_Parser(D_Parser *p) {
2226   if (p.top_scope && !p.initial_scope)
2227     free_D_Scope(p.top_scope, 0);
2228   if (p.whitespace_parser)
2229     free_D_Parser(p.whitespace_parser);
2230 }
2231 
2232 void
2233 free_D_ParseNode(D_Parser * p, D_ParseNode *dpn) {
2234   if (dpn != NO_DPN) {
2235     free_parser_working_data(p);
2236   }
2237 }
2238 
2239 private void
2240 copy_user_configurables(Parser *pp, Parser *p) @safe {
2241     pp.sizeof_user_parse_node = p.sizeof_user_parse_node;
2242     pp.save_parse_tree = p.save_parse_tree;
2243     pp.dont_compare_stacks = p.dont_compare_stacks;
2244     pp.dont_fixup_internal_productions = p.dont_fixup_internal_productions;
2245     pp.fixup_EBNF_productions = p.fixup_EBNF_productions;
2246     pp.dont_merge_epsilon_trees = p.dont_merge_epsilon_trees;
2247     pp.dont_use_height_for_disambiguation = p.dont_use_height_for_disambiguation;
2248     pp.dont_use_greediness_for_disambiguation = p.dont_use_greediness_for_disambiguation;
2249     pp.commit_actions_interval = p.commit_actions_interval;
2250     pp.error_recovery = p.error_recovery;
2251     pp.partial_parses = p.partial_parses;
2252 }
2253 
2254 Parser *
2255 new_subparser(Parser *p) {
2256   Parser * pp = new_D_Parser(p.t, p.sizeof_user_parse_node);
2257   copy_user_configurables(pp, p);
2258   pp.end = p.end;
2259   alloc_parser_working_data(pp);
2260   return pp;
2261 }
2262 
2263 private void
2264 initialize_whitespace_parser(Parser *p) {
2265   if (p.t.whitespace_state) {
2266     p.whitespace_parser = new_subparser(p);
2267     p.whitespace_parser.initial_white_space_fn = &null_white_space;
2268     p.whitespace_parser.error_recovery = false;
2269     p.whitespace_parser.partial_parses = true;
2270     p.whitespace_parser.free_node_fn = p.free_node_fn;
2271   }
2272 }
2273 
2274 private void
2275 free_whitespace_parser(Parser *p) {
2276   if (p.whitespace_parser) {
2277     free_D_Parser(p.whitespace_parser);
2278     p.whitespace_parser = null;
2279   }
2280 }
2281 
2282 private PNode *
2283 handle_top_level_ambiguities(Parser *p, SNode *sn) {
2284   ZNode *z = null;
2285   PNode *pn = null, last = null;
2286   foreach (ZNode *i; sn.zns) {
2287     if (i) {
2288       PNode *x = i.pn;
2289       LATEST(x);
2290       if (!pn) {
2291         z = i;
2292         pn = x;
2293       } else  {
2294         if (x != pn && !x.ambiguities && x != last) {
2295           x.ambiguities = pn.ambiguities;
2296           pn.ambiguities = x;
2297           if (!last) last = x;
2298         }
2299       }
2300     }
2301   }
2302   sn.zns[0] = z;
2303   sn.zns.n = 1;
2304   sn.zns.i = 0;
2305   return pn;
2306 }
2307 
2308 D_ParseNode *
2309 dparse(D_Parser *p, string buf) {
2310     D_ParseNode *res = null;
2311 
2312     auto len = buf.length;
2313     buf ~= '\0';
2314     p.states = p.scans = p.shifts = p.reductions = p.compares = 0;
2315     p.start = buf.ptr;
2316     p.end = buf.ptr + len;
2317 
2318     initialize_whitespace_parser(p);
2319     alloc_parser_working_data(p);
2320     if (p.initial_scope)
2321         p.top_scope = p.initial_scope;
2322     else {
2323         if (p.top_scope)
2324             free_D_Scope(p.top_scope, 0);
2325         p.top_scope = new_D_Scope(null);
2326         p.top_scope.kind = D_SCOPE_SEQUENTIAL;
2327     }
2328     int r = exhaustive_parse(p, p.start_state);
2329     if (!r) {
2330         SNode *sn = p.accept;
2331         PNode *pn;
2332         if (sn.zns.n != 1)
2333             pn = handle_top_level_ambiguities(p, sn);
2334         else
2335             pn = sn.zns[0].pn;
2336         pn = commit_tree(p, pn);
2337 
2338         if (d_verbose_level) {
2339             logf(
2340                     "%d states %d scans %d shifts %d reductions "
2341                     "%d compares %d ambiguities\n",
2342                     p.states, p.scans, p.shifts, p.reductions,
2343                     p.compares, p.ambiguities);
2344             if (p.save_parse_tree) {
2345                 if (d_verbose_level > 1)
2346                     xprint_paren(p, pn);
2347                 else
2348                     print_paren(p, pn);
2349                 logf("\n");
2350             }
2351         }
2352         if (p.save_parse_tree) {
2353             res = &pn.parse_node;
2354         } else
2355             res = NO_DPN;
2356     }
2357 
2358     p.accept = null;
2359     free_parser_working_data(p);
2360     free_whitespace_parser(p);
2361     return res;
2362 }
2363