| Conditions | 44 |
| Paths | 506 |
| Total Lines | 200 |
| Code Lines | 105 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 7 | ||
| Bugs | 0 | Features | 1 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 130 | public function parse($code) { |
||
| 131 | $this->lexer->startLexing($code); |
||
| 132 | $this->errors = array(); |
||
| 133 | |||
| 134 | // We start off with no lookahead-token |
||
| 135 | $symbol = self::SYMBOL_NONE; |
||
| 136 | |||
| 137 | // The attributes for a node are taken from the first and last token of the node. |
||
| 138 | // From the first token only the startAttributes are taken and from the last only |
||
| 139 | // the endAttributes. Both are merged using the array union operator (+). |
||
| 140 | $startAttributes = '*POISON'; |
||
| 141 | $endAttributes = '*POISON'; |
||
| 142 | $this->endAttributes = $endAttributes; |
||
|
|
|||
| 143 | |||
| 144 | // In order to figure out the attributes for the starting token, we have to keep |
||
| 145 | // them in a stack |
||
| 146 | $this->startAttributeStack = array(); |
||
| 147 | |||
| 148 | // Start off in the initial state and keep a stack of previous states |
||
| 149 | $state = 0; |
||
| 150 | $stateStack = array($state); |
||
| 151 | |||
| 152 | // Semantic value stack (contains values of tokens and semantic action results) |
||
| 153 | $this->semStack = array(); |
||
| 154 | |||
| 155 | // Current position in the stack(s) |
||
| 156 | $this->stackPos = 0; |
||
| 157 | |||
| 158 | $errorState = 0; |
||
| 159 | |||
| 160 | for (;;) { |
||
| 161 | //$this->traceNewState($state, $symbol); |
||
| 162 | |||
| 163 | if ($this->actionBase[$state] == 0) { |
||
| 164 | $rule = $this->actionDefault[$state]; |
||
| 165 | } else { |
||
| 166 | if ($symbol === self::SYMBOL_NONE) { |
||
| 167 | // Fetch the next token id from the lexer and fetch additional info by-ref. |
||
| 168 | // The end attributes are fetched into a temporary variable and only set once the token is really |
||
| 169 | // shifted (not during read). Otherwise you would sometimes get off-by-one errors, when a rule is |
||
| 170 | // reduced after a token was read but not yet shifted. |
||
| 171 | $tokenId = $this->lexer->getNextToken($tokenValue, $startAttributes, $endAttributes); |
||
| 172 | |||
| 173 | // map the lexer token id to the internally used symbols |
||
| 174 | $symbol = $tokenId >= 0 && $tokenId < $this->tokenToSymbolMapSize |
||
| 175 | ? $this->tokenToSymbol[$tokenId] |
||
| 176 | : $this->invalidSymbol; |
||
| 177 | |||
| 178 | if ($symbol === $this->invalidSymbol) { |
||
| 179 | throw new \RangeException(sprintf( |
||
| 180 | 'The lexer returned an invalid token (id=%d, value=%s)', |
||
| 181 | $tokenId, $tokenValue |
||
| 182 | )); |
||
| 183 | } |
||
| 184 | |||
| 185 | // This is necessary to assign some meaningful attributes to /* empty */ productions. They'll get |
||
| 186 | // the attributes of the next token, even though they don't contain it themselves. |
||
| 187 | $this->startAttributeStack[$this->stackPos+1] = $startAttributes; |
||
| 188 | |||
| 189 | //$this->traceRead($symbol); |
||
| 190 | } |
||
| 191 | |||
| 192 | $idx = $this->actionBase[$state] + $symbol; |
||
| 193 | if ((($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $symbol) |
||
| 194 | || ($state < $this->YY2TBLSTATE |
||
| 195 | && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $symbol) >= 0 |
||
| 196 | && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $symbol)) |
||
| 197 | && ($action = $this->action[$idx]) != $this->defaultAction) { |
||
| 198 | /* |
||
| 199 | * >= YYNLSTATES: shift and reduce |
||
| 200 | * > 0: shift |
||
| 201 | * = 0: accept |
||
| 202 | * < 0: reduce |
||
| 203 | * = -YYUNEXPECTED: error |
||
| 204 | */ |
||
| 205 | if ($action > 0) { |
||
| 206 | /* shift */ |
||
| 207 | //$this->traceShift($symbol); |
||
| 208 | |||
| 209 | ++$this->stackPos; |
||
| 210 | $stateStack[$this->stackPos] = $state = $action; |
||
| 211 | $this->semStack[$this->stackPos] = $tokenValue; |
||
| 212 | $this->startAttributeStack[$this->stackPos] = $startAttributes; |
||
| 213 | $this->endAttributes = $endAttributes; |
||
| 214 | $symbol = self::SYMBOL_NONE; |
||
| 215 | |||
| 216 | if ($errorState) { |
||
| 217 | --$errorState; |
||
| 218 | } |
||
| 219 | |||
| 220 | if ($action < $this->YYNLSTATES) { |
||
| 221 | continue; |
||
| 222 | } |
||
| 223 | |||
| 224 | /* $yyn >= YYNLSTATES means shift-and-reduce */ |
||
| 225 | $rule = $action - $this->YYNLSTATES; |
||
| 226 | } else { |
||
| 227 | $rule = -$action; |
||
| 228 | } |
||
| 229 | } else { |
||
| 230 | $rule = $this->actionDefault[$state]; |
||
| 231 | } |
||
| 232 | } |
||
| 233 | |||
| 234 | for (;;) { |
||
| 235 | if ($rule === 0) { |
||
| 236 | /* accept */ |
||
| 237 | //$this->traceAccept(); |
||
| 238 | return $this->semValue; |
||
| 239 | } elseif ($rule !== $this->unexpectedTokenRule) { |
||
| 240 | /* reduce */ |
||
| 241 | //$this->traceReduce($rule); |
||
| 242 | |||
| 243 | try { |
||
| 244 | $this->{'reduceRule' . $rule}(); |
||
| 245 | } catch (Error $e) { |
||
| 246 | if (-1 === $e->getStartLine() && isset($startAttributes['startLine'])) { |
||
| 247 | $e->setStartLine($startAttributes['startLine']); |
||
| 248 | } |
||
| 249 | |||
| 250 | $this->errors[] = $e; |
||
| 251 | if ($this->throwOnError) { |
||
| 252 | throw $e; |
||
| 253 | } else { |
||
| 254 | // Currently can't recover from "special" errors |
||
| 255 | return null; |
||
| 256 | } |
||
| 257 | } |
||
| 258 | |||
| 259 | /* Goto - shift nonterminal */ |
||
| 260 | $this->stackPos -= $this->ruleToLength[$rule]; |
||
| 261 | $nonTerminal = $this->ruleToNonTerminal[$rule]; |
||
| 262 | $idx = $this->gotoBase[$nonTerminal] + $stateStack[$this->stackPos]; |
||
| 263 | if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] == $nonTerminal) { |
||
| 264 | $state = $this->goto[$idx]; |
||
| 265 | } else { |
||
| 266 | $state = $this->gotoDefault[$nonTerminal]; |
||
| 267 | } |
||
| 268 | |||
| 269 | ++$this->stackPos; |
||
| 270 | $stateStack[$this->stackPos] = $state; |
||
| 271 | $this->semStack[$this->stackPos] = $this->semValue; |
||
| 272 | } else { |
||
| 273 | /* error */ |
||
| 274 | switch ($errorState) { |
||
| 275 | case 0: |
||
| 276 | $msg = $this->getErrorMessage($symbol, $state); |
||
| 277 | $error = new Error($msg, $startAttributes + $endAttributes); |
||
| 278 | $this->errors[] = $error; |
||
| 279 | if ($this->throwOnError) { |
||
| 280 | throw $error; |
||
| 281 | } |
||
| 282 | // Break missing intentionally |
||
| 283 | case 1: |
||
| 284 | case 2: |
||
| 285 | $errorState = 3; |
||
| 286 | |||
| 287 | // Pop until error-expecting state uncovered |
||
| 288 | while (!( |
||
| 289 | (($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 |
||
| 290 | && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol) |
||
| 291 | || ($state < $this->YY2TBLSTATE |
||
| 292 | && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $this->errorSymbol) >= 0 |
||
| 293 | && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol) |
||
| 294 | ) || ($action = $this->action[$idx]) == $this->defaultAction) { // Not totally sure about this |
||
| 295 | if ($this->stackPos <= 0) { |
||
| 296 | // Could not recover from error |
||
| 297 | return null; |
||
| 298 | } |
||
| 299 | $state = $stateStack[--$this->stackPos]; |
||
| 300 | //$this->tracePop($state); |
||
| 301 | } |
||
| 302 | |||
| 303 | //$this->traceShift($this->errorSymbol); |
||
| 304 | $stateStack[++$this->stackPos] = $state = $action; |
||
| 305 | break; |
||
| 306 | |||
| 307 | case 3: |
||
| 308 | if ($symbol === 0) { |
||
| 309 | // Reached EOF without recovering from error |
||
| 310 | return null; |
||
| 311 | } |
||
| 312 | |||
| 313 | //$this->traceDiscard($symbol); |
||
| 314 | $symbol = self::SYMBOL_NONE; |
||
| 315 | break 2; |
||
| 316 | } |
||
| 317 | } |
||
| 318 | |||
| 319 | if ($state < $this->YYNLSTATES) { |
||
| 320 | break; |
||
| 321 | } |
||
| 322 | |||
| 323 | /* >= YYNLSTATES means shift-and-reduce */ |
||
| 324 | $rule = $state - $this->YYNLSTATES; |
||
| 325 | } |
||
| 326 | } |
||
| 327 | |||
| 328 | throw new \RuntimeException('Reached end of parser loop'); |
||
| 329 | } |
||
| 330 | |||
| 495 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..