[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Chunk Exception 5 * 6 * @package Less 7 * @subpackage exception 8 */ 9 class Less_Exception_Chunk extends Less_Exception_Parser{ 10 11 12 protected $parserCurrentIndex = 0; 13 14 protected $emitFrom = 0; 15 16 protected $input_len; 17 18 19 /** 20 * Constructor 21 * 22 * @param string $input 23 * @param Exception $previous Previous exception 24 * @param integer $index The current parser index 25 * @param Less_FileInfo|string $currentFile The file 26 * @param integer $code The exception code 27 */ 28 public function __construct($input, Exception $previous = null, $index = null, $currentFile = null, $code = 0){ 29 30 $this->message = 'ParseError: Unexpected input'; //default message 31 32 $this->index = $index; 33 34 $this->currentFile = $currentFile; 35 36 $this->input = $input; 37 $this->input_len = strlen($input); 38 39 $this->Chunks(); 40 $this->genMessage(); 41 } 42 43 44 /** 45 * See less.js chunks() 46 * We don't actually need the chunks 47 * 48 */ 49 protected function Chunks(){ 50 $level = 0; 51 $parenLevel = 0; 52 $lastMultiCommentEndBrace = null; 53 $lastOpening = null; 54 $lastMultiComment = null; 55 $lastParen = null; 56 57 for( $this->parserCurrentIndex = 0; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++ ){ 58 $cc = $this->CharCode($this->parserCurrentIndex); 59 if ((($cc >= 97) && ($cc <= 122)) || ($cc < 34)) { 60 // a-z or whitespace 61 continue; 62 } 63 64 switch ($cc) { 65 66 // ( 67 case 40: 68 $parenLevel++; 69 $lastParen = $this->parserCurrentIndex; 70 continue; 71 72 // ) 73 case 41: 74 $parenLevel--; 75 if( $parenLevel < 0 ){ 76 return $this->fail("missing opening `(`"); 77 } 78 continue; 79 80 // ; 81 case 59: 82 //if (!$parenLevel) { $this->emitChunk(); } 83 continue; 84 85 // { 86 case 123: 87 $level++; 88 $lastOpening = $this->parserCurrentIndex; 89 continue; 90 91 // } 92 case 125: 93 $level--; 94 if( $level < 0 ){ 95 return $this->fail("missing opening `{`"); 96 97 } 98 //if (!$level && !$parenLevel) { $this->emitChunk(); } 99 continue; 100 // \ 101 case 92: 102 if ($this->parserCurrentIndex < $this->input_len - 1) { $this->parserCurrentIndex++; continue; } 103 return $this->fail("unescaped `\\`"); 104 105 // ", ' and ` 106 case 34: 107 case 39: 108 case 96: 109 $matched = 0; 110 $currentChunkStartIndex = $this->parserCurrentIndex; 111 for ($this->parserCurrentIndex = $this->parserCurrentIndex + 1; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++) { 112 $cc2 = $this->CharCode($this->parserCurrentIndex); 113 if ($cc2 > 96) { continue; } 114 if ($cc2 == $cc) { $matched = 1; break; } 115 if ($cc2 == 92) { // \ 116 if ($this->parserCurrentIndex == $this->input_len - 1) { 117 return $this->fail("unescaped `\\`"); 118 } 119 $this->parserCurrentIndex++; 120 } 121 } 122 if ($matched) { continue; } 123 return $this->fail("unmatched `" . chr($cc) . "`", $currentChunkStartIndex); 124 125 // /, check for comment 126 case 47: 127 if ($parenLevel || ($this->parserCurrentIndex == $this->input_len - 1)) { continue; } 128 $cc2 = $this->CharCode($this->parserCurrentIndex+1); 129 if ($cc2 == 47) { 130 // //, find lnfeed 131 for ($this->parserCurrentIndex = $this->parserCurrentIndex + 2; $this->parserCurrentIndex < $this->input_len; $this->parserCurrentIndex++) { 132 $cc2 = $this->CharCode($this->parserCurrentIndex); 133 if (($cc2 <= 13) && (($cc2 == 10) || ($cc2 == 13))) { break; } 134 } 135 } else if ($cc2 == 42) { 136 // /*, find */ 137 $lastMultiComment = $currentChunkStartIndex = $this->parserCurrentIndex; 138 for ($this->parserCurrentIndex = $this->parserCurrentIndex + 2; $this->parserCurrentIndex < $this->input_len - 1; $this->parserCurrentIndex++) { 139 $cc2 = $this->CharCode($this->parserCurrentIndex); 140 if ($cc2 == 125) { $lastMultiCommentEndBrace = $this->parserCurrentIndex; } 141 if ($cc2 != 42) { continue; } 142 if ($this->CharCode($this->parserCurrentIndex+1) == 47) { break; } 143 } 144 if ($this->parserCurrentIndex == $this->input_len - 1) { 145 return $this->fail("missing closing `*/`", $currentChunkStartIndex); 146 } 147 } 148 continue; 149 150 // *, check for unmatched */ 151 case 42: 152 if (($this->parserCurrentIndex < $this->input_len - 1) && ($this->CharCode($this->parserCurrentIndex+1) == 47)) { 153 return $this->fail("unmatched `/*`"); 154 } 155 continue; 156 } 157 } 158 159 if( $level !== 0 ){ 160 if( ($lastMultiComment > $lastOpening) && ($lastMultiCommentEndBrace > $lastMultiComment) ){ 161 return $this->fail("missing closing `}` or `*/`", $lastOpening); 162 } else { 163 return $this->fail("missing closing `}`", $lastOpening); 164 } 165 } else if ( $parenLevel !== 0 ){ 166 return $this->fail("missing closing `)`", $lastParen); 167 } 168 169 170 //chunk didn't fail 171 172 173 //$this->emitChunk(true); 174 } 175 176 public function CharCode($pos){ 177 return ord($this->input[$pos]); 178 } 179 180 181 public function fail( $msg, $index = null ){ 182 183 if( !$index ){ 184 $this->index = $this->parserCurrentIndex; 185 }else{ 186 $this->index = $index; 187 } 188 $this->message = 'ParseError: '.$msg; 189 } 190 191 192 /* 193 function emitChunk( $force = false ){ 194 $len = $this->parserCurrentIndex - $this->emitFrom; 195 if ((($len < 512) && !$force) || !$len) { 196 return; 197 } 198 $chunks[] = substr($this->input, $this->emitFrom, $this->parserCurrentIndex + 1 - $this->emitFrom ); 199 $this->emitFrom = $this->parserCurrentIndex + 1; 200 } 201 */ 202 203 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |