Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace PhpParser\Parser;
|
Chris@0
|
4
|
Chris@0
|
5 use PhpParser\Error;
|
Chris@0
|
6 use PhpParser\ErrorHandler;
|
Chris@0
|
7 use PhpParser\Parser;
|
Chris@0
|
8
|
Chris@0
|
9 class Multiple implements Parser {
|
Chris@0
|
10 /** @var Parser[] List of parsers to try, in order of preference */
|
Chris@0
|
11 private $parsers;
|
Chris@0
|
12
|
Chris@0
|
13 /**
|
Chris@0
|
14 * Create a parser which will try multiple parsers in an order of preference.
|
Chris@0
|
15 *
|
Chris@0
|
16 * Parsers will be invoked in the order they're provided to the constructor. If one of the
|
Chris@0
|
17 * parsers runs without throwing, it's output is returned. Otherwise the exception that the
|
Chris@0
|
18 * first parser generated is thrown.
|
Chris@0
|
19 *
|
Chris@0
|
20 * @param Parser[] $parsers
|
Chris@0
|
21 */
|
Chris@0
|
22 public function __construct(array $parsers) {
|
Chris@0
|
23 $this->parsers = $parsers;
|
Chris@0
|
24 }
|
Chris@0
|
25
|
Chris@0
|
26 public function parse($code, ErrorHandler $errorHandler = null) {
|
Chris@0
|
27 if (null === $errorHandler) {
|
Chris@0
|
28 $errorHandler = new ErrorHandler\Throwing;
|
Chris@0
|
29 }
|
Chris@0
|
30
|
Chris@0
|
31 list($firstStmts, $firstError) = $this->tryParse($this->parsers[0], $errorHandler, $code);
|
Chris@0
|
32 if ($firstError === null) {
|
Chris@0
|
33 return $firstStmts;
|
Chris@0
|
34 }
|
Chris@0
|
35
|
Chris@0
|
36 for ($i = 1, $c = count($this->parsers); $i < $c; ++$i) {
|
Chris@0
|
37 list($stmts, $error) = $this->tryParse($this->parsers[$i], $errorHandler, $code);
|
Chris@0
|
38 if ($error === null) {
|
Chris@0
|
39 return $stmts;
|
Chris@0
|
40 }
|
Chris@0
|
41 }
|
Chris@0
|
42
|
Chris@0
|
43 throw $firstError;
|
Chris@0
|
44 }
|
Chris@0
|
45
|
Chris@0
|
46 private function tryParse(Parser $parser, ErrorHandler $errorHandler, $code) {
|
Chris@0
|
47 $stmts = null;
|
Chris@0
|
48 $error = null;
|
Chris@0
|
49 try {
|
Chris@0
|
50 $stmts = $parser->parse($code, $errorHandler);
|
Chris@0
|
51 } catch (Error $error) {}
|
Chris@0
|
52 return [$stmts, $error];
|
Chris@0
|
53 }
|
Chris@0
|
54 }
|