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

Last change on this file was 5896, checked in by cameron, 3 months ago

Start-of-text and End-of-text boundary assertions

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_seq.h>
13#include <re/re_alt.h>
14
15namespace re {
16
17class Assertion : public RE {
18public:
19    static inline bool classof(const RE * re) {
20        return re->getClassTypeId() == ClassTypeId::Assertion;
21    }
22    static inline bool classof(const void *) {
23        return false;
24    }
25    enum class Kind {Lookbehind, Lookahead, Boundary};
26    enum class Sense {Positive, Negative};
27
28    RE * getAsserted() const {return mAsserted;}
29    Assertion::Kind getKind() const {return mKind;}
30    Assertion::Sense getSense() const {return mSense;}
31    void setAsserted(RE * r) {mAsserted = r;}
32
33    static Assertion::Kind reverseKind(Assertion::Kind k);
34    static Assertion::Sense negateSense(Assertion::Sense s);
35
36protected:
37    friend RE * makeAssertion(RE * asserted, Kind k, Sense s);
38    Assertion(RE * r, Kind k, Sense s) : RE(ClassTypeId::Assertion), mAsserted(r), mKind(k), mSense(s) {}
39    virtual ~Assertion() {}
40
41private:
42    RE * mAsserted;
43    Kind mKind;
44    Sense mSense;
45};
46
47inline Assertion::Kind Assertion::reverseKind(Assertion::Kind k) {
48    if (k == Assertion::Kind::Boundary) return k;
49    return k == Assertion::Kind::Lookahead ? Assertion::Kind::Lookbehind : Assertion::Kind::Lookahead;
50}
51
52inline Assertion::Sense Assertion::negateSense(Assertion::Sense s) {
53    return s == Assertion::Sense::Positive ? Assertion::Sense::Negative : Assertion::Sense::Positive;
54}
55
56inline RE * makeAssertion(RE * asserted, Assertion::Kind k, Assertion::Sense s) {
57    if (RE_Nullable::isNullable(asserted)) {
58        if (k == Assertion::Kind::Boundary) {
59            if (s == Assertion::Sense::Positive) return makeAlt();
60            else return makeSeq();
61        }
62        if (s == Assertion::Sense::Positive) return makeSeq();
63        else return makeAlt();
64    }
65    return new Assertion(asserted, k, s);
66}
67
68inline RE * makeLookAheadAssertion(RE * r) {
69    return makeAssertion(r, Assertion::Kind::Lookahead, Assertion::Sense::Positive);
70}
71
72inline RE * makeNegativeLookAheadAssertion(RE * r) {
73    return makeAssertion(r, Assertion::Kind::Lookahead, Assertion::Sense::Negative);
74}
75
76inline RE * makeLookBehindAssertion(RE * r) {
77    return makeAssertion(r, Assertion::Kind::Lookbehind, Assertion::Sense::Positive);
78}
79
80inline RE * makeNegativeLookBehindAssertion(RE * r) {
81    return makeAssertion(r, Assertion::Kind::Lookbehind, Assertion::Sense::Negative);
82}
83
84inline RE * makeBoundaryAssertion(RE * r) {
85    return makeAssertion(r, Assertion::Kind::Boundary, Assertion::Sense::Positive);
86}
87
88inline RE * makeNegativeBoundaryAssertion(RE * r) {
89    return makeAssertion(r, Assertion::Kind::Boundary, Assertion::Sense::Negative);
90}
91
92// Start-of-text boundary assertion.
93RE * makeSOT();
94   
95// End-of-text boundary assertion.
96RE * makeEOT();
97   
98RE * expandBoundaryAssertion(RE * r);
99}
100
101#endif // RE_ASSERTION_H
102
Note: See TracBrowser for help on using the repository browser.