Multiple.php 1.8 KB

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