source: icGREP/icgrep-devel/icgrep/re/re_assertion.h

Last change on this file was 6256, checked in by cameron, 5 months ago

Fixes for contextual simplification

File size: 3.0 KB
Line 
1/*
2 *  Copyright (c) 2017 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#ifndef RE_ASSERTION_H
8#define RE_ASSERTION_H
9
10#include <re/re_re.h>
11#include <re/re_nullable.h>
12#include <re/re_empty_set.h>
13#include <re/re_seq.h>
14#include <re/re_alt.h>
15
16namespace re {
17
18class Assertion : public RE {
19public:
20    enum class Kind {Lookbehind, Lookahead, Boundary};
21    enum class Sense {Positive, Negative};
22   
23    RE * getAsserted() const {return mAsserted;}
24    Assertion::Kind getKind() const {return mKind;}
25    Assertion::Sense getSense() const {return mSense;}
26   
27    static Assertion::Kind reverseKind(Assertion::Kind k);
28    static Assertion::Sense negateSense(Assertion::Sense s);
29    static Assertion * Create(RE * asserted, Kind k, Sense s) {
30        return new Assertion(asserted, k, s);
31    }
32    RE_SUBTYPE(Assertion)
33private:
34    Assertion(RE * r, Kind k, Sense s) : RE(ClassTypeId::Assertion), mAsserted(r), mKind(k), mSense(s) {}
35    RE * mAsserted;
36    Kind mKind;
37    Sense mSense;
38};
39
40inline Assertion::Kind Assertion::reverseKind(Assertion::Kind k) {
41    if (k == Assertion::Kind::Boundary) return k;
42    return k == Assertion::Kind::Lookahead ? Assertion::Kind::Lookbehind : Assertion::Kind::Lookahead;
43}
44
45inline Assertion::Sense Assertion::negateSense(Assertion::Sense s) {
46    return s == Assertion::Sense::Positive ? Assertion::Sense::Negative : Assertion::Sense::Positive;
47}
48
49inline RE * makeAssertion(RE * asserted, Assertion::Kind k, Assertion::Sense s) {
50    if (isEmptySet(asserted)) {
51        if (s == Assertion::Sense::Negative) return makeSeq();
52        else return makeAlt();
53    }
54    if (isNullable(asserted)) {
55        if (k == Assertion::Kind::Boundary) {
56            if (s == Assertion::Sense::Positive) return makeAlt();
57            else return makeSeq();
58        }
59        if (s == Assertion::Sense::Positive) return makeSeq();
60        else return makeAlt();
61    }
62    return Assertion::Create(asserted, k, s);
63}
64
65inline RE * makeLookAheadAssertion(RE * r) {
66    return makeAssertion(r, Assertion::Kind::Lookahead, Assertion::Sense::Positive);
67}
68
69inline RE * makeNegativeLookAheadAssertion(RE * r) {
70    return makeAssertion(r, Assertion::Kind::Lookahead, Assertion::Sense::Negative);
71}
72
73inline RE * makeLookBehindAssertion(RE * r) {
74    return makeAssertion(r, Assertion::Kind::Lookbehind, Assertion::Sense::Positive);
75}
76
77inline RE * makeNegativeLookBehindAssertion(RE * r) {
78    return makeAssertion(r, Assertion::Kind::Lookbehind, Assertion::Sense::Negative);
79}
80
81inline RE * makeBoundaryAssertion(RE * r) {
82    return makeAssertion(r, Assertion::Kind::Boundary, Assertion::Sense::Positive);
83}
84
85inline RE * makeNegativeBoundaryAssertion(RE * r) {
86    return makeAssertion(r, Assertion::Kind::Boundary, Assertion::Sense::Negative);
87}
88
89// Start-of-text boundary assertion.
90RE * makeSOT();
91   
92// End-of-text boundary assertion.
93RE * makeEOT();
94   
95RE * expandBoundaryAssertion(RE * r);
96   
97RE * lookaheadPromotion(RE * r);
98}
99
100#endif // RE_ASSERTION_H
101
Note: See TracBrowser for help on using the repository browser.