(s: string)
| 330 | varLen: boolean; |
| 331 | } |
| 332 | function analyzeSimpleSequence(s: string): SequenceAnalysis | null { |
| 333 | let idx = 0, |
| 334 | minTotal = 0, |
| 335 | variable = false; |
| 336 | while (idx < s.length) { |
| 337 | let unitMin = 0, |
| 338 | unitVar = false; |
| 339 | const ch = s[idx]; |
| 340 | if (ch === "(") return null; |
| 341 | if (ch === "\\") { |
| 342 | idx++; |
| 343 | if (idx >= s.length) return null; |
| 344 | const esc = s[idx++]; |
| 345 | if (esc === "b" || esc === "B") { |
| 346 | unitMin = 0; |
| 347 | } else if ("wdsWDS".includes(esc)) { |
| 348 | unitMin = 1; |
| 349 | } else { |
| 350 | unitMin = 1; |
| 351 | } |
| 352 | } else if (ch === ".") { |
| 353 | idx++; |
| 354 | unitMin = 1; |
| 355 | } else if (ch === "[") { |
| 356 | const ni = parseClassInString(s, idx); |
| 357 | if (ni < 0) return null; |
| 358 | idx = ni; |
| 359 | unitMin = 1; |
| 360 | } else if (REGEX_SPECIAL.has(ch)) { |
| 361 | return null; |
| 362 | } else { |
| 363 | idx++; |
| 364 | unitMin = 1; |
| 365 | } |
| 366 | |
| 367 | if (idx < s.length) { |
| 368 | const q = s[idx]; |
| 369 | if (q === "*") { |
| 370 | idx++; |
| 371 | eatQuantMod(); |
| 372 | unitMin = 0; |
| 373 | unitVar = true; |
| 374 | } else if (q === "+") { |
| 375 | idx++; |
| 376 | eatQuantMod(); |
| 377 | unitMin = Math.max(1, unitMin); |
| 378 | unitVar = true; |
| 379 | } else if (q === "?") { |
| 380 | idx++; |
| 381 | eatQuantMod(); |
| 382 | unitMin = 0; |
| 383 | unitVar = true; |
| 384 | } else if (q === "{") { |
| 385 | const br = parseBracesQuant(s, idx); |
| 386 | if (!br.ok) return null; |
| 387 | idx = br.next; |
| 388 | if (br.type === "exact") unitMin = unitMin * (br.m || 0); |
| 389 | else if (br.type === "open") { |
no test coverage detected