| 111 | int Priority() const { return 10; } |
| 112 | |
| 113 | void Alter(Term& t) |
| 114 | { |
| 115 | if (t.Value().IsA<Term::CharacterRange>()) { |
| 116 | const Term::CharacterRange& range = t.Value().As<Term::CharacterRange>(); |
| 117 | typedef Term::CharacterRange::first_type CharSet; |
| 118 | const CharSet& old = range.first; |
| 119 | CharSet altered; |
| 120 | bool pos = false; |
| 121 | bool neg = false; |
| 122 | for (auto&& i : old) |
| 123 | if (i.size() == 1 && (i[0] & ControlMask) == Control && m_table->Has(i[0])) { |
| 124 | if (is_upper(i[0] & ~ControlMask)) |
| 125 | neg = true; |
| 126 | else |
| 127 | pos = true; |
| 128 | |
| 129 | TSet<wchar32> klass = m_table->Get(i[0]); |
| 130 | for (auto&& j : klass) |
| 131 | altered.insert(Term::String(1, j)); |
| 132 | } else |
| 133 | altered.insert(i); |
| 134 | |
| 135 | if (neg && (pos || range.second)) |
| 136 | Error("Positive and negative character ranges mixed"); |
| 137 | t = Term(t.Type(), Term::CharacterRange(altered, neg || range.second)); |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | private: |
| 142 | CharClassesTable* m_table; |