Branch data Line data Source code
1 : : // -*- C++ -*-
2 : : // Copyright (C) 2012-2013 Red Hat Inc.
3 : : //
4 : : // This file is part of systemtap, and is free software. You can
5 : : // redistribute it and/or modify it under the terms of the GNU General
6 : : // Public License (GPL); either version 2, or (at your option) any
7 : : // later version.
8 : : //
9 : : // ---
10 : : //
11 : : // This file incorporates code from the re2c project; please see
12 : : // re2c-migrate/README for details.
13 : :
14 : : /* $Id$ */
15 : : #ifndef _re2c_regex_h
16 : : #define _re2c_regex_h
17 : :
18 : : #include <iostream>
19 : : #include <set>
20 : : #include <map>
21 : : #include <list>
22 : : #include <vector>
23 : : #include <string>
24 : : #include <iosfwd>
25 : : #include "re2c-globals.h"
26 : :
27 : : namespace re2c
28 : : {
29 : :
30 : : // moved here from ins.h
31 : :
32 : : typedef unsigned short Char;
33 : :
34 : : const unsigned CHAR = 0;
35 : : const unsigned GOTO = 1;
36 : : const unsigned FORK = 2;
37 : : const unsigned TERM = 3;
38 : : const unsigned CTXT = 4;
39 : : const unsigned INIT = 5; // for ^ operator
40 : : // TODOXXX const unsigned ENDI = 6; // for $ operator??
41 : :
42 : : union Ins {
43 : :
44 : : struct
45 : : {
46 : : unsigned char tag;
47 : : unsigned char marked;
48 : : void *link;
49 : : }
50 : :
51 : : i;
52 : :
53 : : struct
54 : : {
55 : : unsigned short value;
56 : : unsigned short bump;
57 : : void *link;
58 : : }
59 : :
60 : : c;
61 : : };
62 : :
63 : 15552 : inline bool isMarked(Ins *i)
64 : : {
65 : 15552 : return i->i.marked != 0;
66 : : }
67 : :
68 : 9574 : inline void mark(Ins *i)
69 : : {
70 : 9574 : i->i.marked = true;
71 : 9574 : }
72 : :
73 : 9550 : inline void unmark(Ins *i)
74 : : {
75 : 9550 : i->i.marked = false;
76 : 9550 : }
77 : :
78 : : // ---------------------------------------------------------------------
79 : :
80 : : // moved from token.h
81 : :
82 : : class Token
83 : : {
84 : : public:
85 : : const Str text;
86 : : const std::string newcond;
87 : : const std::string source;
88 : : unsigned line;
89 : : const bool autogen;
90 : :
91 : : public:
92 : : Token(const SubStr&, const std::string&, unsigned);
93 : : Token(const Token*, const std::string&, unsigned, const Str*);
94 : : Token(const Token& oth);
95 : : ~Token();
96 : : };
97 : :
98 : 48 : inline Token::Token(const SubStr& t, const std::string& s, unsigned l)
99 : : : text(t)
100 : : , newcond()
101 : : , source(s)
102 : : , line(l)
103 [ + - ][ + - ]: 48 : , autogen(false)
104 : : {
105 : : ;
106 : 48 : }
107 : :
108 : : inline Token::Token(const Token* t, const std::string& s, unsigned l, const Str *c)
109 : : : text(t ? t->text.to_string().c_str() : "")
110 : : , newcond(c ? c->to_string() : "")
111 : : , source(s)
112 : : , line(l)
113 : : , autogen(t == NULL)
114 : : {
115 : : ;
116 : : }
117 : :
118 : 0 : inline Token::Token(const Token& oth)
119 : : : text(oth.text.to_string().c_str())
120 : : , newcond(oth.newcond)
121 : : , source(oth.source)
122 : : , line(oth.line)
123 [ # # ][ # # ]: 0 : , autogen(oth.autogen)
[ # # ][ # # ]
124 : : {
125 : : ;
126 : 0 : }
127 : :
128 : 144 : inline Token::~Token()
129 : : {
130 [ + - ][ + - ]: 48 : }
131 : :
132 : : // ---------------------------------------------------------------------
133 : :
134 : : template<class _Ty>
135 : : class free_list: protected std::set<_Ty>
136 : : {
137 : : public:
138 : : typedef typename std::set<_Ty>::iterator iterator;
139 : : typedef typename std::set<_Ty>::size_type size_type;
140 : : typedef typename std::set<_Ty>::key_type key_type;
141 : :
142 : 4828 : free_list(): in_clear(false)
143 : : {
144 : : }
145 : :
146 : : using std::set<_Ty>::insert;
147 : :
148 : 835 : size_type erase(const key_type& key)
149 : : {
150 [ + + ][ - + ]: 835 : if (!in_clear)
151 : : {
152 : 54 : return std::set<_Ty>::erase(key);
153 : : }
154 : 835 : return 0;
155 : : }
156 : :
157 : 4828 : void clear()
158 : : {
159 : 4828 : in_clear = true;
160 : :
161 [ + - ][ + - ]: 5609 : for(iterator it = this->begin(); it != this->end(); ++it)
[ + + ][ + - ]
[ + - ][ + + ]
162 : : {
163 [ + - ][ + - ]: 781 : delete *it;
[ + - ][ + - ]
164 : : }
165 : 4828 : std::set<_Ty>::clear();
166 : :
167 : 4828 : in_clear = false;
168 : 4828 : }
169 : :
170 : 4828 : ~free_list()
171 : : {
172 [ + - ][ + - ]: 4828 : clear();
173 : 4828 : }
174 : :
175 : : protected:
176 : : bool in_clear;
177 : : };
178 : :
179 : : typedef struct extop
180 : : {
181 : : char op;
182 : : int minsize;
183 : : int maxsize;
184 : : }
185 : :
186 : : ExtOp;
187 : :
188 : : struct CharPtn
189 : : {
190 : : unsigned card;
191 : : CharPtn *fix;
192 : : CharPtn *nxt;
193 : : };
194 : :
195 : : typedef CharPtn *CharPtr;
196 : :
197 : : struct CharSet
198 : : {
199 : : CharSet();
200 : : ~CharSet();
201 : :
202 : : CharPtn *fix;
203 : : CharPtn *freeHead, **freeTail;
204 : : CharPtr *rep;
205 : : CharPtn *ptn;
206 : : };
207 : :
208 : : class Range
209 : : {
210 : :
211 : : public:
212 : : Range *next;
213 : : unsigned lb, ub; // [lb,ub)
214 : :
215 : : static free_list<Range*> vFreeList;
216 : :
217 : : public:
218 : 221 : Range(unsigned l, unsigned u) : next(NULL), lb(l), ub(u)
219 : : {
220 [ + - ]: 221 : vFreeList.insert(this);
221 : 221 : }
222 : :
223 : 12 : Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub)
224 : : {
225 [ + - ]: 12 : vFreeList.insert(this);
226 : 12 : }
227 : :
228 : 233 : ~Range()
229 : : {
230 [ + - ]: 233 : vFreeList.erase(this);
231 : 233 : }
232 : :
233 : : friend std::ostream& operator<<(std::ostream&, const Range&);
234 : : friend std::ostream& operator<<(std::ostream&, const Range*);
235 : : };
236 : :
237 : 0 : inline std::ostream& operator<<(std::ostream &o, const Range *r)
238 : : {
239 [ # # ]: 0 : return r ? o << *r : o;
240 : : }
241 : :
242 : : class RegExp
243 : : {
244 : :
245 : : public:
246 : : unsigned size;
247 : : bool anchored; // optimization flag -- always safe to set to false
248 : :
249 : : static free_list<RegExp*> vFreeList;
250 : :
251 : : public:
252 : 602 : RegExp() : size(0), anchored(false)
253 : : {
254 [ + - ]: 602 : vFreeList.insert(this);
255 : 602 : }
256 : :
257 : 602 : virtual ~RegExp()
258 : 602 : {
259 [ + - ]: 602 : vFreeList.erase(this);
260 [ - + ]: 602 : }
261 : :
262 : : virtual const char *typeOf() = 0;
263 : 378 : RegExp *isA(const char *t)
264 : : {
265 [ + + ]: 378 : return typeOf() == t ? this : NULL;
266 : : }
267 : :
268 : : virtual void split(CharSet&) = 0;
269 : : virtual void calcSize(Char*) = 0;
270 : : virtual unsigned fixedLength();
271 : : virtual void compile(Char*, Ins*) = 0;
272 : : virtual void display(std::ostream&) const = 0;
273 : : friend std::ostream& operator<<(std::ostream&, const RegExp&);
274 : : friend std::ostream& operator<<(std::ostream&, const RegExp*);
275 : : };
276 : :
277 : 0 : inline std::ostream& operator<<(std::ostream &o, const RegExp &re)
278 : : {
279 : 0 : re.display(o);
280 : 0 : return o;
281 : : }
282 : :
283 : 0 : inline std::ostream& operator<<(std::ostream &o, const RegExp *re)
284 : : {
285 : 0 : return o << *re;
286 : : }
287 : :
288 [ - + ]: 264 : class NullOp: public RegExp
289 : : {
290 : :
291 : : public:
292 : : static const char *type;
293 : :
294 : : public:
295 : 72 : const char *typeOf()
296 : : {
297 : 72 : return type;
298 : : }
299 : :
300 : : void split(CharSet&);
301 : : void calcSize(Char*);
302 : : unsigned fixedLength();
303 : : void compile(Char*, Ins*);
304 : 0 : void display(std::ostream &o) const
305 : : {
306 : 0 : o << "_";
307 : 0 : }
308 : : };
309 : :
310 [ - + ]: 432 : class MatchOp: public RegExp
311 : : {
312 : :
313 : : public:
314 : : static const char *type;
315 : : Range *match;
316 : :
317 : : public:
318 : 216 : MatchOp(Range *m) : match(m)
319 : : {
320 : 216 : }
321 : :
322 : 111 : const char *typeOf()
323 : : {
324 : 111 : return type;
325 : : }
326 : :
327 : : void split(CharSet&);
328 : : void calcSize(Char*);
329 : : unsigned fixedLength();
330 : : void compile(Char*, Ins*);
331 : : void display(std::ostream&) const;
332 : :
333 : : #ifdef PEDANTIC
334 : : private:
335 : : MatchOp(const MatchOp& oth)
336 : : : RegExp(oth)
337 : : , match(oth.match)
338 : : {
339 : : }
340 : :
341 : : MatchOp& operator = (const MatchOp& oth)
342 : : {
343 : : new(this) MatchOp(oth);
344 : : return *this;
345 : : }
346 : : #endif
347 : : };
348 : :
349 [ - + ]: 14 : class AnchorOp: public RegExp
350 : : {
351 : :
352 : : public:
353 : : static const char *type;
354 : : char atype;
355 : :
356 : : public:
357 : 7 : AnchorOp(char a): atype(a) {}
358 : :
359 : 0 : const char *typeOf()
360 : : {
361 : 0 : return type;
362 : : }
363 : :
364 : : void split(CharSet&);
365 : : void calcSize(Char*);
366 : : unsigned fixedLength();
367 : : void compile(Char*, Ins*);
368 : 0 : void display(std::ostream &o) const
369 : : {
370 : 0 : o << atype;
371 : 0 : }
372 : : };
373 : :
374 : : class RuleOp: public RegExp
375 : : {
376 : : public:
377 : : static const char *type;
378 : :
379 : : private:
380 : : RegExp *exp;
381 : :
382 : : public:
383 : : RegExp *ctx;
384 : : Ins *ins;
385 : : unsigned accept;
386 : : Token *code;
387 : : unsigned line;
388 : :
389 : : public:
390 : : RuleOp(RegExp*, RegExp*, Token*, unsigned);
391 : :
392 : 96 : ~RuleOp()
393 : 96 : {
394 [ + - ][ + - ]: 48 : delete code;
395 [ - + ]: 96 : }
396 : :
397 : 96 : const char *typeOf()
398 : : {
399 : 96 : return type;
400 : : }
401 : :
402 : : void split(CharSet&);
403 : : void calcSize(Char*);
404 : : void compile(Char*, Ins*);
405 : 0 : void display(std::ostream &o) const
406 : : {
407 : 0 : o << exp << "/" << ctx << ";";
408 : 0 : }
409 : : RuleOp* copy(unsigned) const;
410 : :
411 : : #ifdef PEDANTIC
412 : : private:
413 : : RuleOp(const RuleOp& oth)
414 : : : RegExp(oth)
415 : : , exp(oth.exp)
416 : : , ctx(oth.ctx)
417 : : , ins(oth.ins)
418 : : , accept(oth.accept)
419 : : , code(oth.code)
420 : : , line(oth.line)
421 : : {
422 : : }
423 : :
424 : : RuleOp& operator = (const RuleOp& oth)
425 : : {
426 : : new(this) RuleOp(oth);
427 : : return *this;
428 : : }
429 : : #endif
430 : : };
431 : :
432 : : RegExp *mkAlt(RegExp*, RegExp*);
433 : :
434 [ - + ]: 158 : class AltOp: public RegExp
435 : : {
436 : :
437 : : private:
438 : : RegExp *exp1, *exp2;
439 : :
440 : : public:
441 : : static const char *type;
442 : :
443 : : public:
444 : 79 : AltOp(RegExp *e1, RegExp *e2)
445 : : : exp1(e1)
446 : 79 : , exp2(e2)
447 : : {
448 : : // anchored enabled iff e1 enables it
449 : 79 : anchored = e1->anchored;
450 : 79 : }
451 : :
452 : 12 : const char *typeOf()
453 : : {
454 : 12 : return type;
455 : : }
456 : :
457 : : void split(CharSet&);
458 : : void calcSize(Char*);
459 : : unsigned fixedLength();
460 : : void compile(Char*, Ins*);
461 : 0 : void display(std::ostream &o) const
462 : : {
463 : 0 : o << exp1 << "|" << exp2;
464 : 0 : }
465 : :
466 : : friend RegExp *mkAlt(RegExp*, RegExp*);
467 : :
468 : : #ifdef PEDANTIC
469 : : private:
470 : : AltOp(const AltOp& oth)
471 : : : RegExp(oth)
472 : : , exp1(oth.exp1)
473 : : , exp2(oth.exp2)
474 : : {
475 : : }
476 : : AltOp& operator = (const AltOp& oth)
477 : : {
478 : : new(this) AltOp(oth);
479 : : return *this;
480 : : }
481 : : #endif
482 : : };
483 : :
484 [ - + ]: 252 : class CatOp: public RegExp
485 : : {
486 : :
487 : : private:
488 : : RegExp *exp1, *exp2;
489 : :
490 : : public:
491 : : static const char *type;
492 : :
493 : : public:
494 : 126 : CatOp(RegExp *e1, RegExp *e2)
495 : : : exp1(e1)
496 : 126 : , exp2(e2)
497 : : {
498 : : // anchored enabled only when both alternatives enable it
499 [ - + ][ # # ]: 126 : anchored = e1->anchored && e2->anchored;
500 : 126 : }
501 : :
502 : 62 : const char *typeOf()
503 : : {
504 : 62 : return type;
505 : : }
506 : :
507 : : void split(CharSet&);
508 : : void calcSize(Char*);
509 : : unsigned fixedLength();
510 : : void compile(Char*, Ins*);
511 : 0 : void display(std::ostream &o) const
512 : : {
513 : 0 : o << exp1 << exp2;
514 : 0 : }
515 : :
516 : : #ifdef PEDANTIC
517 : : private:
518 : : CatOp(const CatOp& oth)
519 : : : RegExp(oth)
520 : : , exp1(oth.exp1)
521 : : , exp2(oth.exp2)
522 : : {
523 : : }
524 : : CatOp& operator = (const CatOp& oth)
525 : : {
526 : : new(this) CatOp(oth);
527 : : return *this;
528 : : }
529 : : #endif
530 : : };
531 : :
532 [ - + ]: 76 : class CloseOp: public RegExp
533 : : {
534 : :
535 : : private:
536 : : RegExp *exp;
537 : :
538 : : public:
539 : : static const char *type;
540 : :
541 : : public:
542 : 38 : CloseOp(RegExp *e)
543 : 38 : : exp(e)
544 : : {
545 : : // anchored enabled iff e enables it
546 : 38 : anchored = e->anchored;
547 : 38 : }
548 : :
549 : 66 : const char *typeOf()
550 : : {
551 : 66 : return type;
552 : : }
553 : :
554 : : void split(CharSet&);
555 : : void calcSize(Char*);
556 : : void compile(Char*, Ins*);
557 : 0 : void display(std::ostream &o) const
558 : : {
559 : 0 : o << exp << "+";
560 : 0 : }
561 : :
562 : : #ifdef PEDANTIC
563 : : private:
564 : : CloseOp(const CloseOp& oth)
565 : : : RegExp(oth)
566 : : , exp(oth.exp)
567 : : {
568 : : }
569 : : CloseOp& operator = (const CloseOp& oth)
570 : : {
571 : : new(this) CloseOp(oth);
572 : : return *this;
573 : : }
574 : : #endif
575 : : };
576 : :
577 [ # # ]: 0 : class CloseVOp: public RegExp
578 : : {
579 : :
580 : : private:
581 : : RegExp *exp;
582 : : int min;
583 : : int max;
584 : :
585 : : public:
586 : : static const char *type;
587 : :
588 : : public:
589 : 0 : CloseVOp(RegExp *e, int lb, int ub)
590 : : : exp(e)
591 : : , min(lb)
592 : 0 : , max(ub)
593 : : {
594 : : // anchored enabled iff we *have* to match an anchored e
595 [ # # ][ # # ]: 0 : anchored = e->anchored && lb > 0;
596 : 0 : }
597 : :
598 : 0 : const char *typeOf()
599 : : {
600 : 0 : return type;
601 : : }
602 : :
603 : : void split(CharSet&);
604 : : void calcSize(Char*);
605 : : void compile(Char*, Ins*);
606 : 0 : void display(std::ostream &o) const
607 : : {
608 : 0 : o << exp << "+";
609 : 0 : }
610 : : #ifdef PEDANTIC
611 : : private:
612 : : CloseVOp(const CloseVOp& oth)
613 : : : RegExp(oth)
614 : : , exp(oth.exp)
615 : : , min(oth.min)
616 : : , max(oth.max)
617 : : {
618 : : }
619 : : CloseVOp& operator = (const CloseVOp& oth)
620 : : {
621 : : new(this) CloseVOp(oth);
622 : : return *this;
623 : : }
624 : : #endif
625 : : };
626 : :
627 : : typedef std::set<std::string> CondList;
628 : : typedef std::pair<unsigned, RegExp*> NRegExp;
629 : : typedef std::map<std::string, NRegExp> RegExpMap;
630 : : typedef std::vector<std::string> RegExpIndices;
631 : : typedef std::list<RuleOp*> RuleOpList;
632 : : typedef std::pair<unsigned, std::string> LineCode;
633 : : typedef std::map<std::string, LineCode> SetupMap;
634 : :
635 : : class DFA;
636 : :
637 : : extern DFA* genCode(RegExp*);
638 : : extern void genGetStateGoto(std::ostream&, unsigned&, unsigned);
639 : : extern void genCondTable(std::ostream&, unsigned, const RegExpMap&);
640 : : extern void genCondGoto(std::ostream&, unsigned, const RegExpMap&);
641 : : extern void genTypes(std::string&, unsigned, const RegExpMap&);
642 : : extern void genHeader(std::ostream&, unsigned, const RegExpMap&);
643 : :
644 : : extern RegExp *mkDiff(RegExp*, RegExp*);
645 : : extern RegExp *mkAlt(RegExp*, RegExp*);
646 : :
647 : :
648 : : // ---------------------------------------------------------------------
649 : :
650 : : // moved from scanner.h
651 : :
652 : : struct ScannerState
653 : : {
654 : : ScannerState();
655 : :
656 : : char *tok, *ptr, *cur, *pos, *ctx; // positioning
657 : : char *bot, *lim, *top, *eof; // buffer
658 : : unsigned tchar, tline, cline, iscfg, buf_size;
659 : : bool in_parse;
660 : : };
661 : :
662 : : class Scanner: private ScannerState
663 : : {
664 : : private:
665 : : std::istream& in;
666 : : std::ostream& out;
667 : :
668 : : private:
669 : : char *fill(char*, unsigned);
670 : : Scanner(const Scanner&); //unimplemented
671 : : Scanner& operator=(const Scanner&); //unimplemented
672 : : void set_sourceline(char *& cursor);
673 : :
674 : : public:
675 : : Scanner(std::istream&, std::ostream&);
676 : : virtual ~Scanner();
677 : :
678 : : enum ParseMode {
679 : : Stop,
680 : : Parse,
681 : : Reuse,
682 : : Rules
683 : : };
684 : :
685 : : ParseMode echo();
686 : : int scan();
687 : : void reuse();
688 : :
689 : : size_t get_pos() const;
690 : : void save_state(ScannerState&) const;
691 : : void restore_state(const ScannerState&);
692 : :
693 : : unsigned get_cline() const;
694 : : void set_in_parse(bool new_in_parse);
695 : : void fatal_at(unsigned line, unsigned ofs, const char *msg) const;
696 : : void fatalf_at(unsigned line, const char*, ...) const;
697 : : void fatalf(const char*, ...) const;
698 : : void fatal(const char*) const;
699 : : void fatal(unsigned, const char*) const;
700 : :
701 : : void config(const Str&, int);
702 : : void config(const Str&, const Str&);
703 : :
704 : : void check_token_length(char *pos, unsigned len) const;
705 : : SubStr token() const;
706 : : SubStr token(unsigned start, unsigned len) const;
707 : : Str raw_token(std::string enclosure) const;
708 : : virtual unsigned get_line() const;
709 : : unsigned xlat(unsigned c) const;
710 : :
711 : : unsigned unescape(SubStr &s) const;
712 : : std::string& unescape(SubStr& str_in, std::string& str_out) const;
713 : :
714 : : Range * getRange(SubStr &s) const;
715 : : RegExp * matchChar(unsigned c) const;
716 : : RegExp * strToName(SubStr s) const;
717 : : RegExp * strToRE(SubStr s) const;
718 : : RegExp * strToCaseInsensitiveRE(SubStr s) const;
719 : : RegExp * ranToRE(SubStr s) const;
720 : : RegExp * getAnyRE() const;
721 : : RegExp * invToRE(SubStr s) const;
722 : : RegExp * mkDot() const;
723 : : };
724 : :
725 : : inline size_t Scanner::get_pos() const
726 : : {
727 : : return cur - bot;
728 : : }
729 : :
730 : 0 : inline unsigned Scanner::get_line() const
731 : : {
732 : 0 : return cline;
733 : : }
734 : :
735 : : inline unsigned Scanner::get_cline() const
736 : : {
737 : : return cline;
738 : : }
739 : :
740 : : inline void Scanner::save_state(ScannerState& state) const
741 : : {
742 : : state = *this;
743 : : }
744 : :
745 : 0 : inline void Scanner::fatal(const char *msg) const
746 : : {
747 : 0 : fatal(0, msg);
748 : 0 : }
749 : :
750 : 0 : inline SubStr Scanner::token() const
751 : : {
752 : 0 : check_token_length(tok, cur - tok);
753 : 0 : return SubStr(tok, cur - tok);
754 : : }
755 : :
756 : : inline SubStr Scanner::token(unsigned start, unsigned len) const
757 : : {
758 : : check_token_length(tok + start, len);
759 : : return SubStr(tok + start, len);
760 : : }
761 : :
762 : 428 : inline unsigned Scanner::xlat(unsigned c) const
763 : : {
764 [ - + ]: 428 : return re2c::wFlag ? c : re2c::xlat[c & 0xFF];
765 : : }
766 : :
767 : : // ---------------------------------------------------------------------
768 : :
769 : : // moved from parser.h
770 : :
771 : 0 : class Symbol
772 : : {
773 : : public:
774 : :
775 : : RegExp* re;
776 : :
777 : : static Symbol *find(const SubStr&);
778 : : static void ClearTable();
779 : :
780 : : typedef std::map<std::string, Symbol*> SymbolTable;
781 : :
782 : : const Str& GetName() const
783 : : {
784 : : return name;
785 : : }
786 : :
787 : : protected:
788 : :
789 : 0 : Symbol(const SubStr& str)
790 : : : re(NULL)
791 : 0 : , name(str)
792 : : {
793 : 0 : }
794 : :
795 : : private:
796 : :
797 : : static SymbolTable symbol_table;
798 : :
799 : : Str name;
800 : :
801 : : #if PEDANTIC
802 : : Symbol(const Symbol& oth)
803 : : : re(oth.re)
804 : : , name(oth.name)
805 : : {
806 : : }
807 : : Symbol& operator = (const Symbol& oth)
808 : : {
809 : : new(this) Symbol(oth);
810 : : return *this;
811 : : }
812 : : #endif
813 : : };
814 : :
815 : : extern void parse(Scanner&, std::ostream&, std::ostream*);
816 : : extern void parse_cleanup();
817 : :
818 : :
819 : : } // end namespace re2c
820 : :
821 : : #endif
|