@@ -557,32 +557,31 @@ module.exports = function(ast, options) {
557557 ' throw $this->peg_buildException($message, null, $this->peg_reportedPos);' ,
558558 ' }' ,
559559 '' ,
560- ' private function peg_computePosDetails($pos) {' ,
561- ' $self = $this;' ,
562- ' $advance = function(&$details, $startPos, $endPos) use($self) {' ,
563- ' for ($p = $startPos; $p < $endPos; $p++) {' ,
564- ' $ch = mb_substr($self->input, $p, 1, "UTF-8");' ,
565- ' if ($ch === "\\n") {' ,
566- ' if (!$details["seenCR"]) { $details["line"]++; }' ,
567- ' $details["column"] = 1;' ,
568- ' $details["seenCR"] = false;' ,
569- ' } else if ($ch === "\\r" || $ch === "\\u2028" || $ch === "\\u2029") {' ,
570- ' $details["line"]++;' ,
571- ' $details["column"] = 1;' ,
572- ' $details["seenCR"] = true;' ,
573- ' } else {' ,
574- ' $details["column"]++;' ,
575- ' $details["seenCR"] = false;' ,
576- ' }' ,
560+ ' private function peg_advancePos(&$details, $startPos, $endPos) {' ,
561+ ' for ($p = $startPos; $p < $endPos; $p++) {' ,
562+ ' $ch = mb_substr($this->input, $p, 1, "UTF-8");' ,
563+ ' if ($ch === "\\n") {' ,
564+ ' if (!$details["seenCR"]) { $details["line"]++; }' ,
565+ ' $details["column"] = 1;' ,
566+ ' $details["seenCR"] = false;' ,
567+ ' } else if ($ch === "\\r" || $ch === "\\u2028" || $ch === "\\u2029") {' ,
568+ ' $details["line"]++;' ,
569+ ' $details["column"] = 1;' ,
570+ ' $details["seenCR"] = true;' ,
571+ ' } else {' ,
572+ ' $details["column"]++;' ,
573+ ' $details["seenCR"] = false;' ,
577574 ' }' ,
578- ' };' ,
575+ ' }' ,
576+ ' }' ,
579577 '' ,
578+ ' private function peg_computePosDetails($pos) {' ,
580579 ' if ($this->peg_cachedPos !== $pos) {' ,
581580 ' if ($this->peg_cachedPos > $pos) {' ,
582581 ' $this->peg_cachedPos = 0;' ,
583582 ' $this->peg_cachedPosDetails = array( "line" => 1, "column" => 1, "seenCR" => false );' ,
584583 ' }' ,
585- ' $advance ($this->peg_cachedPosDetails, $this->peg_cachedPos, $pos);' ,
584+ ' $this->peg_advancePos ($this->peg_cachedPosDetails, $this->peg_cachedPos, $pos);' ,
586585 ' $this->peg_cachedPos = $pos;' ,
587586 ' }' ,
588587 '' ,
@@ -600,20 +599,23 @@ module.exports = function(ast, options) {
600599 ' $this->peg_maxFailExpected[] = $expected;' ,
601600 ' }' ,
602601 '' ,
603- ' private function peg_buildException($message, $expected, $pos) {' ,
604- ' $cleanupExpected = function (&$expected){' ,
605- ' $i = 1;' ,
602+ ' private function peg_buildException_expectedComparator($a, $b) {' ,
603+ ' if ($a["description"] < $b["description"]) {' ,
604+ ' return -1;' ,
605+ ' } else if ($a["description"] > $b["description"]) {' ,
606+ ' return 1;' ,
607+ ' } else {' ,
608+ ' return 0;' ,
609+ ' }' ,
610+ ' }' ,
606611 '' ,
607- ' usort($expected, function($a, $b) {' ,
608- ' if ($a["description"] < $b["description"]) {' ,
609- ' return -1;' ,
610- ' } else if ($a["description"] > $b["description"]) {' ,
611- ' return 1;' ,
612- ' } else {' ,
613- ' return 0;' ,
614- ' }' ,
615- ' });' ,
612+ ' private function peg_buildException($message, $expected, $pos) {' ,
613+ ' $posDetails = $this->peg_computePosDetails($pos);' ,
614+ ' $found = $pos < mb_strlen($this->input, "UTF-8") ? mb_substr($this->input, $pos, 1, "UTF-8") : null;' ,
616615 '' ,
616+ ' if ($expected !== null) {' ,
617+ ' usort($expected, array($this, "peg_buildException_expectedComparator"));' ,
618+ ' $i = 1;' ,
617619 /*
618620 * This works because the bytecode generator guarantees that every
619621 * expectation object exists only once, so it's enough to use |===| instead
@@ -626,34 +628,9 @@ module.exports = function(ast, options) {
626628 ' $i++;' ,
627629 ' }' ,
628630 ' }' ,
629- ' };' ,
630- '' ,
631- ' $buildMessage = function ($expected, $found) {' ,
632- ' $stringEscape = function ($s) {' ,
633- ' $hex = function($ch) { return strtoupper(dechex(ord($ch[0])));};' ,
634- '' ,
635- /*
636- * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string
637- * literal except for the closing quote character, backslash, carriage
638- * return, line separator, paragraph separator, and line feed. Any character
639- * may appear in the form of an escape sequence.
640- *
641- * For portability, we also escape all control and non-ASCII characters.
642- * Note that "\0" and "\v" escape sequences are not used because JSHint does
643- * not like the first and IE the second.
644- */
645- ' $s = str_replace("\\\\", "\\\\\\\\", $s);' , // backslash
646- ' $s = str_replace("\\"", "\\\\\\"", $s);' , // closing double quote
647- ' $s = str_replace(\'\\x08\', \'\\\\b\', $s);' , // backspace
648- ' $s = str_replace(\'\\t\', \'\\\\t\', $s);' , // horizontal tab
649- ' $s = str_replace(\'\\n\', \'\\\\n\', $s);' , // line feed
650- ' $s = str_replace(\'\\f\', \'\\\\f\', $s);' , // form feed
651- ' $s = str_replace(\'\\r\', \'\\\\r\', $s);' , // carriage return
652- ' $s = preg_replace_callback(\'/[\\\\x00-\\\\x07\\\\x0B\\\\x0E\\\\x0F]/u\', function($ch) use($hex) { return \'\\\\x0\' + $hex($ch[0]); }, $s);' ,
653- ' $s = preg_replace_callback(\'/[\\\\x10-\\\\x1F\\\\x80-\\\\xFF]/u\', function($ch) use($hex) { return \'\\\\x\' + $hex($ch[0]); }, $s);' ,
654- ' return $s;' ,
655- ' };' ,
631+ ' }' ,
656632 '' ,
633+ ' if ($message === null) {' ,
657634 ' $expectedDescs = array_fill(0, count($expected), null);' ,
658635 '' ,
659636 ' for ($i = 0; $i < count($expected); $i++) {' ,
@@ -666,20 +643,13 @@ module.exports = function(ast, options) {
666643 ' . $expectedDescs[count($expected) - 1]' ,
667644 ' : $expectedDescs[0];' ,
668645 '' ,
669- ' $foundDesc = $found ? "\\"" . $stringEscape($found) . "\\"" : "end of input";' ,
670- '' ,
671- ' return "Expected " . $expectedDesc . " but " . $foundDesc . " found.";' ,
672- ' };' ,
673- '' ,
674- ' $posDetails = $this->peg_computePosDetails($pos);' ,
675- ' $found = $pos < mb_strlen($this->input, "UTF-8") ? mb_substr($this->input, $pos, 1, "UTF-8") : null;' ,
646+ ' $foundDesc = $found ? json_encode($found) : "end of input";' ,
676647 '' ,
677- ' if ($expected !== null) {' ,
678- ' $cleanupExpected($expected);' ,
648+ ' $message = "Expected " . $expectedDesc . " but " . $foundDesc . " found.";' ,
679649 ' }' ,
680650 '' ,
681651 ' return new SyntaxError(' ,
682- ' $message !== null ? $message : $buildMessage($expected, $found) ,' ,
652+ ' $message,' ,
683653 ' $expected,' ,
684654 ' $found,' ,
685655 ' $pos,' ,
0 commit comments