1 ///////////////////////////////////////////////////////////////////////////////
3 // This file implements various pretty printing and formating routines.
5 ///////////////////////////////////////////////////////////////////////////////
9 #include <AD/contain/bitset.h>
10 #include <AD/strings/charesc.h>
11 #include <AD/strings/quark.h>
16 #include "matchcom.ph"
20 #include "graphtype.h"
22 ///////////////////////////////////////////////////////////////////////////////
24 // Flags controlling printing formats of types.
26 ///////////////////////////////////////////////////////////////////////////////
27 Bool pretty_print_ty = true;
28 Bool pretty_print_pattern = false;
29 Bool pretty_print_exp = false;
30 Bool print_semantic_stack = false;
31 Bool print_inner_action = false;
32 Bool print_default_value = true;
34 Parameter ty_parameter = TYformal;
36 ///////////////////////////////////////////////////////////////////////////////
38 // Print an identifier list
40 ///////////////////////////////////////////////////////////////////////////////
41 std::ostream& operator << (std::ostream& f, Ids vars)
42 { for(Ids vs = vars; vs; vs = vs->#2)
43 { f << vs->#1; if (vs->#2) f << ", "; }
47 ///////////////////////////////////////////////////////////////////////////////
51 ///////////////////////////////////////////////////////////////////////////////
52 std::ostream& operator << (std::ostream& f, Scope s)
54 { case PUBLICscope: f << "public";
55 case PROTECTEDscope: f << "protected";
56 case PRIVATEscope: f << "private";
61 ///////////////////////////////////////////////////////////////////////////////
62 // Return the label for an tuple element index
63 ///////////////////////////////////////////////////////////////////////////////
64 Id index_of(int i,Id prefix)
65 { if (prefix == 0) prefix = "";
66 return Quark(Quark(prefix,"_"),i);
69 ///////////////////////////////////////////////////////////////////////////////
71 // Print a persistent id.
73 ///////////////////////////////////////////////////////////////////////////////
74 std::ostream& operator << (std::ostream& f, Pid pid)
76 { PERSISTid id: { f << id; }
77 | PERSISTnone: // skip
82 ///////////////////////////////////////////////////////////////////////////////
86 ///////////////////////////////////////////////////////////////////////////////
87 std::ostream& operator << (std::ostream& f, Literal l)
89 { INTlit i: { f << i; }
90 | BOOLlit b: { f << (b ? "true" : "false"); }
91 | CHARlit c: { char b[32]; print_char(b,c); f << '\'' << b << '\''; }
93 { // use sprintf due to library problems in libg++ 2.5.8 on Linux
95 sprintf(buf,"%lf", r);
97 // ostrstream S(buf,sizeof(buf));
98 // std::ostream& S2 = S;
102 | STRINGlit s: { f << s; }
103 | REGEXPlit re: { f << re; }
104 | QUARKlit q: { if (pretty_print_pattern) f << '#' << q;
105 else f << MatchCompiler::quark_name(q);
107 | BIGINTlit n: { if (pretty_print_pattern) f << "#" << n;
114 ///////////////////////////////////////////////////////////////////////////////
118 ///////////////////////////////////////////////////////////////////////////////
119 std::ostream& operator << (std::ostream& f, Tys tys)
120 { for(Tys t = tys; t; t = t->#2) {
122 if (t->#2 != #[]) f << ", ";
127 ///////////////////////////////////////////////////////////////////////////////
129 // Print type variables (i.e. template actual arguments)
131 ///////////////////////////////////////////////////////////////////////////////
132 void print_tyvars(std::ostream& f, Tys tys, Bool is_datatype)
134 if (is_datatype) f << "(" << tys << ")";
135 else f << '<' << tys << "> ";
138 ///////////////////////////////////////////////////////////////////////////////
140 // Print type variables (i.e. formal template arguments)
142 ///////////////////////////////////////////////////////////////////////////////
143 void print_tyvars(std::ostream& f, TyVars tyvars, char open, char close, Bool header)
144 { if (tyvars != #[]) {
145 if (header) f << "template ";
147 for(TyVars t = tyvars; t; t = t->#2) {
148 if (header) f << "class ";
150 if (t->#2) f << ", ";
153 if (header) f << ' ';
157 ///////////////////////////////////////////////////////////////////////////////
159 // Print a tuple type.
161 ///////////////////////////////////////////////////////////////////////////////
162 void print_tuple(std::ostream& f, Tys tys)
163 { if (pretty_print_ty) {
164 f << '(' << tys << ')';
168 for (Tys t = tys; t; t = t->#2) {
177 ///////////////////////////////////////////////////////////////////////////////
179 // Print a mktuple type
181 ///////////////////////////////////////////////////////////////////////////////
182 void print_mktuple(std::ostream& f, Tys tys)
183 { if (pretty_print_ty) {
184 f << ".[" << tys << ']';
186 f << "Tuple" << length(tys);
187 print_tyvars(f,tys,false);
191 ///////////////////////////////////////////////////////////////////////////////
193 // Print a record type.
195 ///////////////////////////////////////////////////////////////////////////////
196 void print_record(std::ostream& f, Ids labs, Tys tys, Bool flex)
197 { if (! pretty_print_ty) f << "struct ";
200 for (t = tys, l = labs; t && l; t = t->#2, l = l->#2) {
201 if (pretty_print_ty) {
202 f << l->#1 << " : " << t->#1;
203 if (t->#2) f << ", ";
205 ty_id = l->#1; f << t->#1 << "; ";
209 if (pretty_print_ty && flex) f << " ... ";
213 ///////////////////////////////////////////////////////////////////////////////
215 // Print a function parameter.
217 ///////////////////////////////////////////////////////////////////////////////
218 void print_parameter (std::ostream& f, Ty ty, Id id, Parameter p)
219 { Parameter save = ty_parameter;
220 Bool sp = pretty_print_ty;
221 pretty_print_ty = false;
226 if (p == TYformal || p == TYsimpleformal ||
227 p == TYactual && tys != #[]) f << '(';
228 for (Tys ts = tys; ts; ts = ts->#2) {
229 ty_id = index_of(i,(p != TYbody ? "x" : ""));
230 if (p != TYactual) f << ts->#1;
232 if (p != TYbody) { if (ts->#2) f << ", "; }
237 if (p == TYformal || p == TYsimpleformal ||
238 p == TYactual && tys != #[]) f << ')';
240 | RECORDty(labs,_,tys):
243 if (p == TYformal || p == TYsimpleformal ||
244 p == TYactual && tys != #[]) f << '(';
245 for (l = labs, t = tys; l && t; l = l->#2, t = t->#2) {
247 ty_id = #"x_" + l->#1;
250 if (p != TYactual) f << t->#1;
252 if (p != TYbody) { if (t->#2) f << ", "; }
256 if (p == TYformal || p == TYsimpleformal ||
257 p == TYactual && tys != #[]) f << ')';
259 | ty: { if (p != TYbody) f << '(';
264 if (p != TYactual) f << ty;
266 if (p == TYbody) f << "; ";
268 if (p != TYbody) f << ')';
272 pretty_print_ty = sp;
275 ///////////////////////////////////////////////////////////////////////////////
277 // Method to print a type expression.
279 ///////////////////////////////////////////////////////////////////////////////
280 std::ostream& operator << (std::ostream& f, Ty ty)
282 if (ty_id) { this_id = ty_id; ty_id = 0; }
285 { NOty: { f << "error"; }
286 | VARty _: { f << "???"; }
287 | INDty (id, _): { f << id; }
288 | POLYty(t, _, _): { f << t; }
289 | TYPEty: { f << "type"; }
290 | POINTERty t: { f << t << " *"; }
291 | REFty t: { f << t << " &"; }
292 | FUNty(a, b): { f << a << " -> " << b; }
293 | GRAPHty G: { f << G->class_name; }
294 | NODEty n: { f << n->graph()->class_name <<"::"<< n->name(); }
295 | EDGEty e: { f << "edge " << e->name(); }
296 | TUPLEty tys: { print_tuple(f,tys); }
297 | EXTUPLEty tys: { print_mktuple(f,tys); }
298 | RECORDty(l,flex,tys): { print_record(f,l,tys,flex); }
300 { if (options.new_type_format && tys != #[])
301 { match (deref_all(ty))
302 { DATATYPEty({ id ... },_):
303 { if (! pretty_print_ty) f << "a_";
304 f << id; print_tyvars(f,tys,false);
305 if (! pretty_print_ty)
306 { if (tys == #[]) f << ' ';
310 | _: { f << id; print_tyvars(f,tys,false); }
314 match (deref_all(ty))
315 { DATATYPEty(_,_): { print_tyvars(f,tys,! pretty_print_ty); }
316 | _: { print_tyvars(f,tys,false); }
321 { if (this_id) { ty_id = this_id; this_id = 0; }
322 f << t << '[' << exp << ']';
325 { if (this_id) { ty_id = this_id; this_id = 0; }
327 if (ty_parameter != TYbody && ty_parameter != TYsimpleformal
328 && print_default_value) f << " = " << exp;
331 { if (q & QUALunsigned) f << "unsigned ";
332 if (q & QUALsigned) f << "signed ";
333 if ((ty_parameter == TYformal || ty_parameter == TYsimpleformal)
335 f << (TYCONty(REFtycon,#[ QUALty(QUALconst,t) ]));
338 if (q & QUALconst) f << " const";
340 | DATATYPEty({ id, tyvars ... }, #[]): { f << id; }
341 | DATATYPEty({ id, tyvars ... }, tys):
342 { if (! pretty_print_ty) f << "a_";
343 f << id; print_tyvars(f,tys,false);
344 if (! pretty_print_ty)
345 { if (tys == #[]) f << ' ';
349 | NESTEDty(a,b): { f << a << "::" << b; }
350 | _: { bug ("operator << (std::ostream&, Ty)"); }
352 if (this_id) f << ' ' << this_id;
357 ///////////////////////////////////////////////////////////////////////////////
359 // Method to print a pattern list.
361 ///////////////////////////////////////////////////////////////////////////////
362 void print (std::ostream& f, Pats pats, Id open, Id close,
363 Bool flex1, Pat p, Bool flex2 = false,
364 Pat len = NOpat, Pat array = NOpat)
368 if (array != NOpat) f << " : " << array;
371 if (flex2) f << " ... ";
372 for (Pats ps = pats; ps; ps = ps->#2) {
374 if (ps->#2) f << ", ";
376 if (flex1 && pats != #[] && p != NOpat) f << " ... ";
377 if (p != NOpat) f << p;
381 ///////////////////////////////////////////////////////////////////////////////
383 // Method to print a labeled pattern list.
385 ///////////////////////////////////////////////////////////////////////////////
386 void print (std::ostream& f, LabPats lab_pats, Bool flex)
388 for (LabPats ps = lab_pats; ps; ps = ps->#2) {
389 f << ps->#1.label << " = " << ps->#1.pat;
390 if (ps->#2) f << ", ";
395 ///////////////////////////////////////////////////////////////////////////////
397 // Methods extract the open and close brace of a list.
399 ///////////////////////////////////////////////////////////////////////////////
402 { ONEcons { name ... }: { char s[3];
403 s[0] = name[0]; s[1] = name[1]; s[2] = '\0';
406 | _: { return "<??>["; }
412 { ONEcons { name ... }: { return name+2; }
419 { ONEcons { name ... }: { return name+strlen(name)-2; }
424 ///////////////////////////////////////////////////////////////////////////////
426 // Method to print a pattern list.
428 ///////////////////////////////////////////////////////////////////////////////
429 std::ostream& operator << (std::ostream& f, Pats ps)
430 { print(f,ps,"","",false,NOpat); return f; }
432 ///////////////////////////////////////////////////////////////////////////////
434 // Method to print a pattern.
436 ///////////////////////////////////////////////////////////////////////////////
437 std::ostream& operator << (std::ostream& f, Pat p)
440 | WILDpat _: { f << '_'; }
441 | BACKEDGEpat (_,id,_): { f << '<' << id << '>'; }
442 | IDpat (id,_,_): { f << id; }
443 | INDpat (id,_,_): { f << '?' << id; }
444 | ASpat (id,p,_,_): { f << id << " as " << p; }
445 | TYPEDpat (p,ty): { f << p << " : " << ty; }
446 | TUPLEpat ps: { print(f,ps,"(",")",false,NOpat); }
447 | EXTUPLEpat ps: { print(f,ps,".(",")",false,NOpat); }
448 | ARRAYpat (ps,flex): { print(f,ps,"[","]",flex,NOpat); }
449 | RECORDpat (ps,flex): { print(f,ps,flex); }
450 | LOGICALpat(NOTpat,a,_): { f << "(! " << a << ")"; }
451 | LOGICALpat(ANDpat,a,b): { f << '(' << a << " && " << b << ')'; }
452 | LOGICALpat(ORpat,a,b): { f << '(' << a << " || " << b << ')'; }
453 | LOGICALpat(IMPLIESpat,a,b): { f << '(' << a << " implies: " << b << ')'; }
454 | LOGICALpat(EQUIVpat,a,b): { f << '(' << a << " equiv: " << b << ')'; }
455 | LOGICALpat(XORpat,a,b): { f << '(' << a << " xor: " << b << ')'; }
456 | GUARDpat(p,e): { f << p << " | " << e; }
457 | APPENDpat(p1,p2,_): { f << '(' << p1 << " ; " << p2 << ')'; }
458 | UNIFYpat(p,e): { f << '(' << p << " := " << e << ")"; }
459 | MARKEDpat(_,p): { f << p; }
460 | CONSpat(ONEcons { qual, alg_ty = DATATYPEty ({ id ... },_) ... })
461 | qual & QUALvariable:
463 | CONSpat(ONEcons { name ... }): { f << name; }
464 | CONSpat(NOcons): { f << "<none>"; }
465 | APPpat(p1,p2): { f << p1 << ' ' << p2; }
466 | LEXEMEpat(id, ty, n, terms): { f << "lexeme class " << id; }
467 | POLYpat(id,_,#[],p,e,_): { f << id << " = " << p; }
468 | POLYpat(id,_,vars,p,e,_): { f << id << '(' << vars << ") = " << p; }
469 | VECTORpat{cons,elements,len,array,head_flex=u,tail_flex=v}:
470 { print(f,elements,open_of(cons),close_of2(cons),v,NOpat,u,len,array); }
471 | LISTpat{nil,head,tail ...}:
472 { print(f,head,open_of(nil),close_of(nil),true,tail); }
473 | CONTEXTpat(context,pat):
475 for (Conses ids = context; ids; ids = ids->#2)
476 { if (ids->#1 != NOcons) f << ids->#1->name;
477 if (ids->#2) f << ", ";
482 { Bool save = pretty_print_pattern;
483 pretty_print_pattern = true;
485 pretty_print_pattern = save;
491 ///////////////////////////////////////////////////////////////////////////////
493 // Convert a string into a suitable encoding
495 ///////////////////////////////////////////////////////////////////////////////
496 void encode_string(char * buf, const char * s)
498 { unsigned char c = *s++;
500 { *buf++ = 'X'; *buf++ = 'X';
501 } else if (isalnum(c) || c == '_')
502 { *buf++ = '_'; *buf++ = c;
505 int lo = c % 16, hi = c / 16;
513 ///////////////////////////////////////////////////////////////////////////////
515 // Method to print the mangled name of list constructors.
517 ///////////////////////////////////////////////////////////////////////////////
518 fun mangle id | id == 0: { return "(null)"; }
519 | mangle "#[...]": Id: { return "list_1_"; }
520 | mangle "#(...)": { return "list_2_"; }
521 | mangle "#{...}": { return "list_3_"; }
522 | mangle "#[]": { return "nil_1_"; }
523 | mangle "#()": { return "nil_2_"; }
524 | mangle "#{}": { return "nil_3_"; }
525 | mangle "[|...|]": { return "vector_1_"; }
526 | mangle "(|...|)": { return "vector_2_"; }
527 | mangle "{|...|}": { return "vector_3_"; }
528 | mangle id | id[0] == '"':
529 { char buf[256]; encode_string(buf,id);
531 | mangle id: { return id; }
534 ///////////////////////////////////////////////////////////////////////////////
536 // Method to print the name of a constructor
538 ///////////////////////////////////////////////////////////////////////////////
539 std::ostream& print_cons (std::ostream& f, Cons cons)
541 { ONEcons { name, ty = NOty ... }: { f << mangle(name); }
542 | ONEcons { name, alg_ty = DATATYPEty({ opt, id ... },_) ... }:
543 { if (opt & OPTsubclassless)
546 f << id << "_" << mangle(name);
548 | _: { bug("print_cons()"); }
553 ///////////////////////////////////////////////////////////////////////////////
555 // Method to print an expression list
557 ///////////////////////////////////////////////////////////////////////////////
558 std::ostream& operator << (std::ostream& f, Exps es)
559 { for (Exps l = es; l; l = l->#2) {
560 f << l->#1; if (l->#2) f << ',';
565 ///////////////////////////////////////////////////////////////////////////////
567 // Method to print an expression.
569 ///////////////////////////////////////////////////////////////////////////////
570 std::ostream& operator << (std::ostream& f, Exp e)
573 | IDexp id: { f << id; }
574 | RELexp i | same_selectors: { f << "_0"; }
575 | RELexp i: { f << '_' << i; }
576 | MARKEDexp (_,e): { f << e; }
577 | LITERALexp l: { f << l; }
578 | ASSIGNexp (e1,e2): { f << '(' << e1 << " = " << e2 << ')'; }
579 | DOTexp(SELECTORexp(e,c,t),id) | pretty_print_exp:
580 { f << e << '!' << c->name << '.';
582 if (n > 0) f << n; else f << id;
584 | SELECTORexp(e,c,t) | pretty_print_exp:
585 { f << e << '!' << c->name; }
586 | DOTexp(SELECTORexp(e,c,t),id):
587 { f << MatchCompiler::make_select(e,c,t,id); }
588 | SELECTORexp(e,cons,t): { f << MatchCompiler::make_select(e,cons,t); }
589 | DOTexp (DEREFexp e,id): { f << e << "->" << id; }
590 | DOTexp (e,id): { f << e << '.' << id; }
591 | DEREFexp (e): { f << "(*" << e << ')'; }
592 | ARROWexp (e,id): { f << e << "->" << id; }
593 | APPexp (e1,e2): { f << e1 << '(' << e2 << ')'; }
594 | INDEXexp (e1,e2): { f << e1 << '[' << e2 << ']'; }
595 | BINOPexp (x,e1,e2): { f << '(' << e1 << ' ' << x << ' ' << e2 << ')'; }
596 | PREFIXexp (x,e): { f << '(' << x << ' ' << e << ')'; }
597 | POSTFIXexp(x,e): { f << '(' << e << ' ' << x << ')'; }
598 | CASTexp (ty,e): { Bool save = pretty_print_ty;
599 pretty_print_ty = false;
600 f << "((" << ty << ')' << e << ')';
601 pretty_print_ty = save;
603 | QUALexp (ty,e): { f << ty << "::" << e; }
604 | EQexp(_,e1,e2): { f << "equality_of(" << e1 << ',' << e2 << ')'; }
605 | UNIFYexp(_,e1,e2): { f << "unify(" << e1 << ',' << e2 << ')'; }
606 | LTexp(_,e1,e2): { f << '(' << e1 << " < " << e2 << ')'; }
607 | HASHexp(_,e): { f << "hash(" << e << ')'; }
608 | TUPLEexp es: { f << es; }
609 | EXTUPLEexp es: { f << "mkTuple" << length(es) << '(' << es << ')'; }
610 | IFexp(a,b,c): { f << '(' << a << " ? " << b << " : " << c <<')';}
611 | SYNexp (i,r,_,in_rewrite):
613 f << '_' << i << "__";
614 else if (r < 0) // parser semantic action
615 { if (i == 0) f << "syn_" << "._" << -r;
616 else f << "t__[" << i << "+to__]._" << -r;
619 f << "t__->kids[" << i << "]->u._" << r;
621 | THISSYNexp (r,_,in_rewrite):
625 f << "t__->u._" << r;
627 | COSTexp (i): { f << "t__->kids[" << i << "]->cost"; }
628 | THISCOSTexp _: { f << "t__->cost"; }
630 ONEcons { name, ty = TYCONty(RECORDtycon(labels,_),tys) ... },
631 placement, e as RECORDexp lab_exps):
632 { // rearrange arguments to
634 { f << "new (" << placement << ") "; print_cons(f,c); }
636 { f << mangle(name); }
639 { for_each (LabExp, i, lab_exps) {
640 for_each (Id, j, labels) if (i.label == j) goto next;
641 error ("%Lillegal record label '%s' in expression: %s%e\n",
646 { Bool comma = false;
648 for(is = labels, ts = tys; is; is = is->#2, ts = ts->#2) {
651 for_each (LabExp, j, lab_exps) {
654 error ("%Lduplicated label '%s' in expression: %s%e\n",
657 if (comma) f << ", "; comma = true;
662 match (default_val(ts->#1))
663 { NOexp: { error ("%Lmissing label '%s' in expression: %s%e\n",
665 | def_e: { if (comma) f << ", "; comma = true; f << def_e; }
672 | CONSexp(ONEcons { name ... }, placement, RECORDexp _):
673 { error("%Lconstructor '%s' doesn't take labeled arguments\n", name);
675 | CONSexp(ONEcons { name, ty = NOty ... },#[], NOexp):
676 { f << mangle(name); }
677 | CONSexp(cons as ONEcons { name ... }, placement, e):
679 { f << "new (" << placement << ") "; print_cons(f,cons); }
681 { f << mangle(name); }
682 f << '(' << e << ')';
686 for (LabExps l = es; l; l = l->#2) {
687 f << l->#1.label << " = " << l->#1.exp;
688 if (l->#2) f << ", ";
692 | LISTexp (cons, nil, es, e) | pretty_print_exp:
694 for(Exps exp_list = es; exp_list; exp_list = exp_list->#2)
696 if (exp_list->#2) f << ", ";
699 { f << " ... " << e; }
702 | LISTexp (ONEcons { name = cons ...}, ONEcons { name = nil ...}, es, e):
704 for(Exps exp_list = es; exp_list; exp_list = exp_list->#2)
705 { Exp exp = exp_list->#1;
706 f << mangle(cons) << '(' << exp;
707 if (exp_list->#2) f << ',';
710 if (e != NOexp) f << ',' << e;
711 else if (es == #[]) f << mangle(nil);
712 while (i-- > 0) f << ')';
715 | VECTORexp (ONEcons { name = vec ... }, es):
716 { f << mangle(vec) << '(';
717 { for(Exps exps = es; exps; exps = exps->#2)
719 if (exps->#2 != #[]) f << ',';
724 | VECTORexp _: // skip
725 | _: { bug("operator << (std::ostream&, Exp);"); }
730 ///////////////////////////////////////////////////////////////////////////////
732 // Method to print an inheritance type.
734 ///////////////////////////////////////////////////////////////////////////////
735 std::ostream& operator << (std::ostream& f, Inherit i)
736 { if (i->qualifiers & QUALvirtual) f << "virtual ";
737 return f << i->scope << ' ' << i->super_class;
740 ///////////////////////////////////////////////////////////////////////////////
742 // Method to print a class inheritance list.
744 ///////////////////////////////////////////////////////////////////////////////
745 std::ostream& operator << (std::ostream& f, Inherits i)
746 { for ( ;i; i = i->#2) {
748 if (i->#2) f << ", ";
753 ///////////////////////////////////////////////////////////////////////////////
755 // Method to print a cost expression
757 ///////////////////////////////////////////////////////////////////////////////
758 std::ostream& operator << (std::ostream& f, Cost c)
761 | EXPcost (e,_): { f << " \\ " << e; }
762 | INTcost c: { f << " \\ " << c; }
767 ///////////////////////////////////////////////////////////////////////////////
769 // Method to print a qualified identifier.
771 ///////////////////////////////////////////////////////////////////////////////
772 std::ostream& operator << (std::ostream& f, QualId id)
774 { NESTEDid(ty, id): { f << ty << "::" << id; }
775 | SIMPLEid id | isalpha(id[0]): { f << id; }
776 | SIMPLEid id: { f << "operator " << id; }
781 ///////////////////////////////////////////////////////////////////////////////
782 // Method to print a pattern match rule.
783 ///////////////////////////////////////////////////////////////////////////////
784 std::ostream& operator << (std::ostream& f, MatchRule mr)
786 { MATCHrule (non_terminal, pat, guard, cost, action):
787 { Bool save = pretty_print_exp;
788 pretty_print_exp = true;
789 if (non_terminal) f << non_terminal << " -> ";
791 if (guard != NOexp) f << " | " << guard;
792 f << cost << ": ...";
793 pretty_print_exp = save;
799 ///////////////////////////////////////////////////////////////////////////////
801 // Method to pretty print a decision tree.
803 ///////////////////////////////////////////////////////////////////////////////
804 std::ostream& operator << (std::ostream& f, Match m)
806 { FAILmatch: { f << '_'; }
807 | DONTCAREmatch: { f << '-'; }
808 | BACKEDGEmatch (_,id,_): { f << '<' << id << '>'; }
809 | SUCCESSmatch (r,_): { f << r; }
810 | GUARDmatch (e,yes,no): { f << e << '(' << yes << ',' << no << ')'; }
811 | SUCCESSESmatch (n,set,_):
814 for (int i = 0; i < n; i++)
816 if (comma) f << ", ";
822 | COSTmatch (n,costs,set,_):
825 for (int i = 0; i < n; i++)
827 if (comma) f << ", ";
828 f << costs[i] << " = " << i;
833 | TREECOSTmatch (m,set,_):
834 { f << "TREE{" << *set << "} => " << m; }
835 | TREELABELmatch (m,ty,_,k):
836 { f << "LABEL{" << ty << "(" << k << ")} => " << m; }
837 | LITERALmatch(_,_,l as [REGEXPlit _],n,m,d):
839 for (int i = 0; i < n; i++)
840 { f << " {" << i << "}" << l[i] << " => " << m[i] << ",\n";
844 | LITERALmatch(_,_,l,n,m,d):
846 for (int i = 0; i < n; i++)
847 { f << l[i] << ':' << m[i] << ", "; }
850 | CONSmatch(_,_,_,TYCONty(DATATYPEtycon { id, qualifiers ... },_),n,m,d):
852 for (int i = 0; i < n; i++) {
854 if (i < n - 1) f << ", ";
856 if (qualifiers & QUALextensible) f << ", " << d;
859 | RANGEmatch(_,_,lo,hi,y,n):
860 { f << '[' << lo << ".." << hi << ": " << y << ", " << n << ']'; }
861 | _: { bug("operator << (std::ostream&, Match);"); }