$line) { preg_match_all('/@(if|elseif|else|endif|foreach|endforeach|for|endfor|while|endwhile|section|endsection|push|endpush)\b/', $line, $matches); foreach ($matches[1] as $directive) { if (in_array($directive, ['if', 'foreach', 'for', 'while', 'section', 'push'])) { $stack[] = ['type' => $directive, 'line' => $num + 1]; } elseif (in_array($directive, ['endif', 'endforeach', 'endfor', 'endwhile', 'endsection', 'endpush'])) { $mapping = [ 'endif' => 'if', 'endforeach' => 'foreach', 'endfor' => 'for', 'endwhile' => 'while', 'endsection' => 'section', 'endpush' => 'push' ]; $expected = $mapping[$directive]; $last = array_pop($stack); if (!$last || $last['type'] !== $expected) { echo "Mismatch at line " . ($num + 1) . ": got @" . $directive . ", but last was " . json_encode($last) . "\n"; } } } } if (!empty($stack)) { echo "Unclosed directives remaining in stack:\n"; print_r($stack); } else { echo "All blade directives matched!\n"; }