1 //  $Id$
2 // Copyright (c) 2001,2002                        RIPE NCC
3 //
4 // All Rights Reserved
5 //
6 // Permission to use, copy, modify, and distribute this software and its
7 // documentation for any purpose and without fee is hereby granted,
8 // provided that the above copyright notice appear in all copies and that
9 // both that copyright notice and this permission notice appear in
10 // supporting documentation, and that the name of the author not be
11 // used in advertising or publicity pertaining to distribution of the
12 // software without specific, written prior permission.
13 //
14 // THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 // ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
16 // AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
17 // DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
18 // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 //
21 //
22 //  Copyright (c) 1994 by the University of Southern California
23 //  All rights reserved.
24 //
25 //    Permission is hereby granted, free of charge, to any person obtaining a copy
26 //    of this software and associated documentation files (the "Software"), to deal
27 //    in the Software without restriction, including without limitation the rights
28 //    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29 //    copies of the Software, and to permit persons to whom the Software is
30 //    furnished to do so, subject to the following conditions:
31 //
32 //    The above copyright notice and this permission notice shall be included in
33 //    all copies or substantial portions of the Software.
34 //
35 //    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36 //    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37 //    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38 //    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39 //    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40 //    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41 //    THE SOFTWARE.
42 //
43 //  Questions concerning this software should be directed to
44 //  irrtoolset@cs.usc.edu.
45 //
46 //  Author(s): Cengiz Alaettinoglu <cengiz@ISI.EDU>
47 
48 #ifndef REGEXP_H
49 #define REGEXP_H
50 
51 #include "config.h"
52 #include <iostream>
53 #include <cassert>
54 #include <typeinfo>
55 #include "dataset/SetOfSymID.hh"
56 #include "List.hh"
57 #include "rangelist.hh"
58 #include "symbols.hh"
59 
60 #define REGEXP_FRIENDS \
61    friend std::ostream& operator<<(std::ostream& os, const regexp& r); \
62    friend class regexp_nf; \
63    friend class CiscoConfig;\
64    friend class CiscoXRConfig;\
65    friend class JunosConfig;
66 
67 class regexp {
68 REGEXP_FRIENDS
69 public:
regexp()70    regexp() {
71    }
regexp(const regexp &)72    regexp(const regexp&) {
73    }
operator ==(const regexp & b)74    bool operator==(const regexp &b) {
75       return equals(b);
76    }
operator !=(const regexp & b)77    bool operator!=(const regexp &b) {
78       return ! equals(b);
79    }
80    virtual regexp* dup() const = 0;
81    virtual bool equals(const regexp &b) = 0;
~regexp()82    virtual ~regexp() {}
83 };
84 
85 class regexp_empty_set : public regexp {
86 REGEXP_FRIENDS
87 public:
regexp_empty_set()88    regexp_empty_set() {
89    }
regexp_empty_set(const regexp_empty_set & r)90    regexp_empty_set(const regexp_empty_set& r) {
91    }
~regexp_empty_set()92    virtual ~regexp_empty_set() {}
93    virtual regexp* dup() const;
equals(const regexp & b)94    bool equals(const regexp &b) {
95       return typeid(b) == typeid(regexp_empty_set);
96    }
97 };
98 
99 class regexp_empty_str : public regexp {
100 REGEXP_FRIENDS
101 public:
regexp_empty_str()102    regexp_empty_str () {
103    }
regexp_empty_str(const regexp_empty_str & r)104    regexp_empty_str (const regexp_empty_str& r)  {
105    }
~regexp_empty_str()106    virtual ~regexp_empty_str () {}
107 
108    virtual regexp* dup() const;
equals(const regexp & b)109    bool equals(const regexp &b) {
110       return typeid(b) == typeid(regexp_empty_str);
111    }
112 };
113 
114 class regexp_bol : public regexp { // bol is beginning-of-line ^
115 REGEXP_FRIENDS
116 public:
regexp_bol()117    regexp_bol() {
118    }
regexp_bol(const regexp_bol &)119    regexp_bol(const regexp_bol&) {
120    }
~regexp_bol()121    virtual ~regexp_bol() {}
122    regexp* dup() const;
equals(const regexp & b)123    bool equals(const regexp &b) {
124       return typeid(b) == typeid(regexp_bol);
125    }
126 };
127 
128 class regexp_eol : public regexp { // eol is end-of-line $
129 REGEXP_FRIENDS
130 public:
regexp_eol()131    regexp_eol() {
132    }
regexp_eol(const regexp_eol &)133    regexp_eol(const regexp_eol&) {
134    }
~regexp_eol()135    virtual ~regexp_eol() {}
136    regexp* dup() const;
equals(const regexp & b)137    bool equals(const regexp &b) {
138       return typeid(b) == typeid(regexp_eol);
139    }
140 };
141 
142 class regexp_symbol : public regexp {
143 REGEXP_FRIENDS
144 friend std::ostream& operator<<(std::ostream& os, regexp_symbol& r);
145 public:
146    static ASt MIN_AS;
147    static ASt MAX_AS;
148 
149 private:
150    RangeList asnumbers;
151    SetOfSymID asSets;
152    int complemented;
153 
154 public:
regexp_symbol()155    regexp_symbol () {
156       complemented = 0;
157    }
158    // ~regexp_symbol() {   } // compiler is OK
159    // regexp_symbol(const regexp_symbol& s) {assert(0);} // compiler is OK
160 
regexp_symbol(unsigned int as1)161    regexp_symbol(unsigned int as1) {
162       complemented = 0;
163       asnumbers.add(as1, as1);
164    }
regexp_symbol(unsigned int as1,unsigned int as2)165    regexp_symbol(unsigned int as1, unsigned int as2) {
166       complemented = 0;
167       asnumbers.add(as1, as2);
168    }
regexp_symbol(SymID asset)169    regexp_symbol(SymID asset) {
170       complemented = 0;
171       asSets.add(asset);
172    }
173 
add(unsigned int as1)174    void add(unsigned int as1) {
175       asnumbers.add(as1, as1);
176    }
add(unsigned int as1,unsigned int as2)177    void add(unsigned int as1, unsigned int as2) {
178       asnumbers.add(as1, as2);
179    }
add(SymID asset)180    void add(SymID asset) {
181       asSets.add(asset);
182    }
183 
complement()184    void complement() {
185       complemented = ! complemented;
186    }
187    regexp* dup() const;
equals(const regexp & b)188    bool equals(const regexp &b) {
189       return typeid(b) == typeid(regexp_symbol)
190 	 && complemented == ((regexp_symbol &) b).complemented
191 	 && asnumbers == ((regexp_symbol &) b).asnumbers
192 	 && asSets == ((regexp_symbol &) b).asSets;
193    }
194 };
195 
196 class regexp_cat : public regexp {
197 REGEXP_FRIENDS
198 private:
199    regexp*	left;
200    regexp*	right;
201 
202 public:
regexp_cat(regexp * l,regexp * r)203    regexp_cat(regexp *l, regexp *r) {
204       left = l;
205       right = r;
206    }
207 
regexp_cat(const regexp_cat & b)208    regexp_cat(const regexp_cat &b) {
209       left = b.left->dup();
210       right = b.right->dup();
211    }
212 
~regexp_cat()213    virtual ~regexp_cat() {
214       if (left)
215 	 delete left;
216       if (right)
217 	 delete right;
218    }
219    regexp* dup() const;
equals(const regexp & b)220    bool equals(const regexp &b) {
221       return typeid(b) == typeid(regexp_cat)
222 	 && left == ((regexp_cat &) b).left
223 	 && right == ((regexp_cat &) b).right;
224    }
225 };
226 
227 class regexp_or : public regexp {
228 REGEXP_FRIENDS
229 private:
230    regexp*	left;
231    regexp*	right;
232 
233 public:
regexp_or(regexp * l,regexp * r)234    regexp_or(regexp *l, regexp *r) {
235       left = l;
236       right = r;
237    }
238 
regexp_or(const regexp_or & b)239    regexp_or(const regexp_or &b) {
240       left = b.left->dup();
241       right = b.right->dup();
242    }
243 
~regexp_or()244    virtual ~regexp_or() {
245       if (left)
246 	 delete left;
247       if (right)
248 	 delete right;
249    }
250    regexp* dup() const;
equals(const regexp & b)251    bool equals(const regexp &b) {
252       return typeid(b) == typeid(regexp_or)
253 	 && left == ((regexp_or &) b).left
254 	 && right == ((regexp_or &) b).right;
255    }
256 };
257 
258 class regexp_star : public regexp {
259 REGEXP_FRIENDS
260 private:
261    regexp*	left;
262 
263 public:
regexp_star(regexp * l)264    regexp_star(regexp *l) {
265       left = l;
266    }
regexp_star(const regexp_star & b)267    regexp_star(const regexp_star &b) {
268       left = b.left->dup();
269    }
270 
~regexp_star()271    virtual ~regexp_star() {
272       if (left)
273 	 delete left;
274    }
275    regexp* dup() const;
equals(const regexp & b)276    bool equals(const regexp &b) {
277       return typeid(b) == typeid(regexp_star)
278 	 && left == ((regexp_star &) b).left;
279    }
280 };
281 
282 class regexp_question : public regexp {
283 REGEXP_FRIENDS
284 private:
285    regexp*	left;
286 
287 public:
regexp_question(regexp * l)288    regexp_question(regexp *l) {
289       left = l;
290    }
regexp_question(const regexp_question & b)291    regexp_question(const regexp_question &b) {
292       left = b.left->dup();
293    }
~regexp_question()294    virtual ~regexp_question() {
295       if (left)
296 	 delete left;
297    }
298    regexp* dup() const;
equals(const regexp & b)299    bool equals(const regexp &b) {
300       return typeid(b) == typeid(regexp_question)
301 	 && left == ((regexp_question &) b).left;
302    }
303 };
304 
305 class regexp_plus : public regexp {
306 REGEXP_FRIENDS
307 private:
308    regexp*	left;
309 
310 public:
regexp_plus(regexp * l)311    regexp_plus(regexp *l) {
312       left = l;
313    }
regexp_plus(const regexp_plus & b)314    regexp_plus(const regexp_plus &b) {
315       left = b.left->dup();
316    }
317 
~regexp_plus()318    virtual ~regexp_plus() {
319       if (left)
320 	 delete left;
321    }
322    regexp* dup() const;
equals(const regexp & b)323    bool equals(const regexp &b) {
324       return typeid(b) == typeid(regexp_plus)
325 	 && left == ((regexp_plus &) b).left;
326    }
327 };
328 
329 class regexp_tildastar : public regexp {
330 REGEXP_FRIENDS
331 private:
332    regexp*	left;
333 
334 public:
regexp_tildastar(regexp * l)335    regexp_tildastar(regexp *l) {
336       left = l;
337    }
regexp_tildastar(const regexp_tildastar & b)338    regexp_tildastar(const regexp_tildastar &b) {
339       left = b.left->dup();
340    }
341 
~regexp_tildastar()342    virtual ~regexp_tildastar() {
343       if (left)
344 	 delete left;
345    }
346    regexp* dup() const;
equals(const regexp & b)347    bool equals(const regexp &b) {
348       return typeid(b) == typeid(regexp_tildastar)
349 	 && left == ((regexp_tildastar &) b).left;
350    }
351 };
352 
353 class regexp_tildaplus : public regexp {
354 REGEXP_FRIENDS
355 private:
356    regexp*	left;
357 
358 public:
regexp_tildaplus(regexp * l)359    regexp_tildaplus(regexp *l) {
360       left = l;
361    }
regexp_tildaplus(const regexp_tildaplus & b)362    regexp_tildaplus(const regexp_tildaplus &b) {
363       left = b.left->dup();
364    }
365 
~regexp_tildaplus()366    virtual ~regexp_tildaplus() {
367       if (left)
368 	 delete left;
369    }
370    regexp* dup() const;
equals(const regexp & b)371    bool equals(const regexp &b) {
372       return typeid(b) == typeid(regexp_tildaplus)
373 	 && left == ((regexp_tildaplus &) b).left;
374    }
375 };
376 
377 #endif   // REGEXP_H
378