| 221 | bool Accepts(wchar32 c) const { return c == '[' || c == (Control | '[') || c == (Control | ']'); } |
| 222 | |
| 223 | Term Lex() |
| 224 | { |
| 225 | static const char* controls = "^[]-\\"; |
| 226 | static const char* controls2 = "*+{}()$?.&~"; |
| 227 | wchar32 ch = CorrectChar(GetChar(), controls); |
| 228 | if (ch == '[' || ch == ']') |
| 229 | return Term::Character(ch); |
| 230 | |
| 231 | Term::CharacterRange cs; |
| 232 | ch = CorrectChar(GetChar(), controls); |
| 233 | if (ch == (Control | '^')) { |
| 234 | cs.second = true; |
| 235 | ch = CorrectChar(GetChar(), controls); |
| 236 | } |
| 237 | |
| 238 | bool firstUnicode; |
| 239 | wchar32 unicodeSymbol = 0; |
| 240 | |
| 241 | for (; ch != End && ch != (Control | ']'); ch = CorrectChar(GetChar(), controls)) { |
| 242 | if (ch == (Control | 'x')) { |
| 243 | UngetChar(ch); |
| 244 | firstUnicode = true; |
| 245 | unicodeSymbol = ReadUnicodeCharacter(); |
| 246 | } else { |
| 247 | firstUnicode = false; |
| 248 | } |
| 249 | |
| 250 | if (((ch & ControlMask) != Control || firstUnicode) && CorrectChar(PeekChar(), controls) == (Control | '-')) { |
| 251 | GetChar(); |
| 252 | wchar32 current = GetChar(); |
| 253 | |
| 254 | bool secondUnicode = (current == (Control | 'x')); |
| 255 | |
| 256 | wchar32 begin = (firstUnicode) ? unicodeSymbol : ch; |
| 257 | wchar32 end; |
| 258 | if (secondUnicode) { |
| 259 | UngetChar(current); |
| 260 | end = ReadUnicodeCharacter(); |
| 261 | } else { |
| 262 | end = CorrectChar(current, controls); |
| 263 | if ((end & ControlMask) == Control) |
| 264 | Error("Wrong character range"); |
| 265 | } |
| 266 | |
| 267 | for (ch = begin; ch <= end; ++ch) { |
| 268 | cs.first.insert(Term::String(1, ch)); |
| 269 | } |
| 270 | } else if (ch == (Control | '-')) { |
| 271 | cs.first.insert(Term::String(1, '-')); |
| 272 | } |
| 273 | else if ((ch & ControlMask) == Control && (strchr(controls2, ch & ~ControlMask) || strchr(controls, ch & ~ControlMask))) { |
| 274 | cs.first.insert(Term::String(1, ch & ~ControlMask)); |
| 275 | } |
| 276 | else if ((ch & ControlMask) != Control || !strchr(controls, ch & ~ControlMask)) { |
| 277 | cs.first.insert(Term::String(1, (firstUnicode) ? unicodeSymbol : ch)); |
| 278 | } else { |
| 279 | Error("Wrong character in range"); |
| 280 | } |