Skip to content

Commit 977cbab

Browse files
committed
Decrement errorState when recovering from -> error
It's likely that an error after -> will trigger another one due to missing semicolon without shifting a single token. We prevent an immediate failure in this case by manually setting errorState to 2, which will suppress the duplicate error message, but allow error recovery.
1 parent 09086fb commit 977cbab

File tree

6 files changed

+36
-9
lines changed

6 files changed

+36
-9
lines changed

grammar/php5.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ object_property:
915915
T_STRING { $$ = $1; }
916916
| '{' expr '}' { $$ = $2; }
917917
| variable_without_objects { $$ = $1; }
918-
| error { $$ = Expr\Error[]; }
918+
| error { $$ = Expr\Error[]; $this->errorState = 2; }
919919
;
920920

921921
list_expr:

grammar/php7.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ property_name:
793793
T_STRING { $$ = $1; }
794794
| '{' expr '}' { $$ = $2; }
795795
| simple_variable { $$ = Expr\Variable[$1]; }
796-
| error { $$ = Expr\Error[]; }
796+
| error { $$ = Expr\Error[]; $this->errorState = 2; }
797797
;
798798

799799
list_expr:

lib/PhpParser/Parser/Php5.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3009,7 +3009,7 @@ protected function reduceRule517() {
30093009
}
30103010

30113011
protected function reduceRule518() {
3012-
$this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes);
3012+
$this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2;
30133013
}
30143014

30153015
protected function reduceRule519() {

lib/PhpParser/Parser/Php7.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2619,7 +2619,7 @@ protected function reduceRule452() {
26192619
}
26202620

26212621
protected function reduceRule453() {
2622-
$this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes);
2622+
$this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2;
26232623
}
26242624

26252625
protected function reduceRule454() {

lib/PhpParser/ParserAbstract.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ abstract class ParserAbstract implements Parser
9595
protected $throwOnError;
9696
/** @var Error[] Errors collected during last parse */
9797
protected $errors;
98+
/** @var int Error state, used to avoid error floods */
99+
protected $errorState;
98100

99101
/**
100102
* Creates a parser instance.
@@ -157,7 +159,7 @@ public function parse($code) {
157159
// Current position in the stack(s)
158160
$this->stackPos = 0;
159161

160-
$errorState = 0;
162+
$this->errorState = 0;
161163

162164
for (;;) {
163165
//$this->traceNewState($state, $symbol);
@@ -216,8 +218,8 @@ public function parse($code) {
216218
$this->endAttributes = $endAttributes;
217219
$symbol = self::SYMBOL_NONE;
218220

219-
if ($errorState) {
220-
--$errorState;
221+
if ($this->errorState) {
222+
--$this->errorState;
221223
}
222224

223225
if ($action < $this->YYNLSTATES) {
@@ -274,7 +276,7 @@ public function parse($code) {
274276
$this->semStack[$this->stackPos] = $this->semValue;
275277
} else {
276278
/* error */
277-
switch ($errorState) {
279+
switch ($this->errorState) {
278280
case 0:
279281
$msg = $this->getErrorMessage($symbol, $state);
280282
$error = new Error($msg, $startAttributes + $endAttributes);
@@ -285,7 +287,7 @@ public function parse($code) {
285287
// Break missing intentionally
286288
case 1:
287289
case 2:
288-
$errorState = 3;
290+
$this->errorState = 3;
289291

290292
// Pop until error-expecting state uncovered
291293
while (!(

test/code/parser/errorHandling/recovery.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,4 +254,29 @@ array(
254254
name: Expr_Error(
255255
)
256256
)
257+
)
258+
-----
259+
<?php
260+
function foo() {
261+
$bar->
262+
}
263+
-----
264+
Syntax error, unexpected '}' from 4:1 to 4:1
265+
array(
266+
0: Stmt_Function(
267+
byRef: false
268+
name: foo
269+
params: array(
270+
)
271+
returnType: null
272+
stmts: array(
273+
0: Expr_PropertyFetch(
274+
var: Expr_Variable(
275+
name: bar
276+
)
277+
name: Expr_Error(
278+
)
279+
)
280+
)
281+
)
257282
)

0 commit comments

Comments
 (0)