Skip to content

Commit b6990e1

Browse files
committed
Simplify SQLite parser regex using PCRE DEFINE
Factor out inner construct bodies (sqI, dqI, btI, bkI, bcI) and reusable sub-patterns (skip, stmt, lc) into a DEFINE block, replacing the $simpleQuery string concatenation hack with a single self-contained pattern. (*PRUNE) remains inline at the call sites because PCRE confines backtracking verbs to subroutine scope.
1 parent 5a4022d commit b6990e1

1 file changed

Lines changed: 41 additions & 32 deletions

File tree

src/SqliteMultiQueryParser.php

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,45 +21,54 @@ public function parseStringStream(Iterator $stream): Iterator
2121

2222
private function getQueryPattern(): string
2323
{
24-
$simpleQuery = /** @lang PhpRegExp */ '~
25-
(?:
26-
\s
27-
| /\* (*PRUNE) (?: [^*]++ | \*(?!/) )*+ \*/
28-
| -- [^\n]*+
29-
)*+
30-
(?<simplequery>
31-
(?:
32-
[^;\'"`[/-]++
33-
| \' (*PRUNE) (?: \'\' | [^\'] )*+ \'
34-
| " (*PRUNE) (?: "" | [^"] )*+ "
35-
| ` (*PRUNE) (?: `` | [^`] )*+ `
36-
| \[ (*PRUNE) [^\]]*+ (?: \]\] [^\]]*+ )* \]
37-
| /\* (*PRUNE) (?: [^*]++ | \*(?!/) )*+ \*/
38-
| -- [^\n]*+
39-
| (?!;) .
40-
)++
41-
)
42-
;
43-
~x';
24+
// (*PRUNE) must appear inline (not inside DEFINE subroutines) because PCRE confines
25+
// backtracking verbs to the subroutine scope. The inner bodies are defined once in
26+
// DEFINE and referenced after the inline (*PRUNE) to avoid pattern duplication.
4427
return /** @lang PhpRegExp */ '~
45-
(?:
46-
\s
47-
| /\* (*PRUNE) (?: [^*]++ | \*(?!/) )*+ \*/
48-
| -- [^\n]*+
49-
)*+
28+
(?(DEFINE)
29+
(?<sqI> (?: \'\' | [^\'] )*+ \' )
30+
(?<dqI> (?: "" | [^"] )*+ " )
31+
(?<btI> (?: `` | [^`] )*+ ` )
32+
(?<bkI> [^\]]*+ (?: \]\] [^\]]*+ )* \] )
33+
(?<bcI> (?: [^*]++ | \*(?!/) )*+ \*/ )
34+
(?<lc> -- [^\n]*+ )
35+
(?<skip>
36+
(?:
37+
\s
38+
| /\* (*PRUNE) (?&bcI)
39+
| (?&lc)
40+
)*+
41+
)
42+
(?<stmt>
43+
(?&skip)
44+
(?:
45+
[^;\'"`[/-]++
46+
| \' (*PRUNE) (?&sqI)
47+
| " (*PRUNE) (?&dqI)
48+
| ` (*PRUNE) (?&btI)
49+
| \[ (*PRUNE) (?&bkI)
50+
| /\* (*PRUNE) (?&bcI)
51+
| (?&lc)
52+
| (?!;) .
53+
)++
54+
;
55+
)
56+
)
57+
58+
(?&skip)
5059
5160
(?:
5261
(?:
5362
(?<query>
5463
(?:
5564
[^bB;\'"`[/-]++
56-
| \' (*PRUNE) (?: \'\' | [^\'] )*+ \'
57-
| " (*PRUNE) (?: "" | [^"] )*+ "
58-
| ` (*PRUNE) (?: `` | [^`] )*+ `
59-
| \[ (*PRUNE) [^\]]*+ (?: \]\] [^\]]*+ )* \]
60-
| /\* (*PRUNE) (?: [^*]++ | \*(?!/) )*+ \*/
61-
| (?i:BEGIN) (?!\s*(?:(?i:TRANSACTION|DEFERRED|IMMEDIATE|EXCLUSIVE)\b|;|\z)) (*PRUNE) (?: (?i:\s*END)\s*| ' . substr($simpleQuery, 1, -2) . ')*
62-
| -- [^\n]*+
65+
| \' (*PRUNE) (?&sqI)
66+
| " (*PRUNE) (?&dqI)
67+
| ` (*PRUNE) (?&btI)
68+
| \[ (*PRUNE) (?&bkI)
69+
| /\* (*PRUNE) (?&bcI)
70+
| (?i:BEGIN) (?!\s*(?:(?i:TRANSACTION|DEFERRED|IMMEDIATE|EXCLUSIVE)\b|;|\z)) (*PRUNE) (?: (?i:\s*END)\s* | (?&stmt) )*
71+
| (?&lc)
6372
| (?!;) .
6473
)*+
6574
)

0 commit comments

Comments
 (0)