Multiple.php 1.6 KB

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