Skip to content

Commit

Permalink
add empty subexpression grammar and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Sep 27, 2024
1 parent 6390d8d commit d79f280
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
12 changes: 7 additions & 5 deletions resources/RegexGrammar.pp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
alternation()

alternation:
concatenation() ( ::alternation:: concatenation() #alternation )*
concatenation()? ( <alternation> concatenation()? #alternation )*

concatenation:
( internal_options() | assertion() | quantification() | condition() )
Expand All @@ -154,8 +154,8 @@
<index>
| ::assertion_reference_:: alternation() #assertioncondition
)
::_capturing:: concatenation()?
( ::alternation:: concatenation()? )?
::_capturing::
alternation()
::_capturing::

assertion:
Expand All @@ -165,7 +165,8 @@
| ::lookbehind_:: #lookbehind
| ::negative_lookbehind_:: #negativelookbehind
)
alternation() ::_capturing::
alternation()
::_capturing::

quantification:
( class() | simple() ) ( quantifier() #quantification )?
Expand Down Expand Up @@ -208,7 +209,8 @@
| ::atomic_group_:: #atomicgroup
| ::capturing_::
)
alternation() ::_capturing::
alternation()
::_capturing::

non_capturing_internal_options:
<non_capturing_internal_option>
Expand Down
42 changes: 42 additions & 0 deletions tests/PHPStan/Analyser/nsrt/preg_match_shapes.php
Original file line number Diff line number Diff line change
Expand Up @@ -899,3 +899,45 @@ function bugUnescapedDashAfterRange (string $string): void {
assertType("array{string, non-empty-string}", $matches);
}
}

function bugEmptySubexpression (string $string): void {
if (preg_match('//', $string, $matches)) {
assertType("array{string}", $matches); // could be array{''}
}

if (preg_match('/()/', $string, $matches)) {
assertType("array{string, string}", $matches); // could be array{'', ''}
}

if (preg_match('/|/', $string, $matches)) {
assertType("array{string}", $matches); // could be array{''}
}

if (preg_match('~|(a)~', $string, $matches)) {
assertType("array{0: string, 1?: 'a'}", $matches);
}

if (preg_match('~(a)|~', $string, $matches)) {
assertType("array{0: string, 1?: 'a'}", $matches);
}

if (preg_match('~(a)||(b)~', $string, $matches)) {
assertType("array{0: string, 1?: 'a'}|array{string, '', 'b'}", $matches);
}

if (preg_match('~(|(a))~', $string, $matches)) {
assertType("array{0: string, 1: ''|'a', 2?: 'a'}", $matches);
}

if (preg_match('~((a)|)~', $string, $matches)) {
assertType("array{0: string, 1: ''|'a', 2?: 'a'}", $matches);
}

if (preg_match('~((a)||(b))~', $string, $matches)) {
assertType("array{0: string, 1: ''|'a'|'b', 2?: ''|'a', 3?: 'b'}", $matches);
}

if (preg_match('~((a)|()|(b))~', $string, $matches)) {
assertType("array{0: string, 1: string, 2?: ''|'a', 3?: string, 4?: 'b'}", $matches);
}
}

0 comments on commit d79f280

Please sign in to comment.