diff --git a/syntax/parser.go b/syntax/parser.go index c11afa7f..17541b29 100644 --- a/syntax/parser.go +++ b/syntax/parser.go @@ -1721,10 +1721,11 @@ func (p *Parser) getStmt(readEnd, binCmd, fnBody bool) *Stmt { b.Y = p.getStmt(false, true, false) if b.Y == nil || p.err != nil { if p.recoverError() { - return &Stmt{Position: recoveredPos} + b.Y = &Stmt{Position: recoveredPos} + } else { + p.followErr(b.OpPos, b.Op.String(), "a statement") + return nil } - p.followErr(b.OpPos, b.Op.String(), "a statement") - return nil } s = &Stmt{Position: s.Position} s.Cmd = b @@ -1897,10 +1898,11 @@ func (p *Parser) gotStmtPipe(s *Stmt, binCmd bool) *Stmt { p.got(_Newl) if b.Y = p.gotStmtPipe(&Stmt{Position: p.pos}, true); b.Y == nil || p.err != nil { if p.recoverError() { - return &Stmt{Position: recoveredPos} + b.Y = &Stmt{Position: recoveredPos} + } else { + p.followErr(b.OpPos, b.Op.String(), "a statement") + break } - p.followErr(b.OpPos, b.Op.String(), "a statement") - break } s = &Stmt{Position: s.Position} s.Cmd = b diff --git a/syntax/parser_test.go b/syntax/parser_test.go index 9ddfb02a..416342c8 100644 --- a/syntax/parser_test.go +++ b/syntax/parser_test.go @@ -2618,12 +2618,21 @@ func TestParseRecoverErrors(t *testing.T) { printer := NewPrinter() for _, tc := range tests { t.Run("", func(t *testing.T) { + t.Logf("input: %s", tc.src) r := strings.NewReader(tc.src) f, err := parser.Parse(r, "") if tc.wantErr { qt.Assert(t, qt.Not(qt.IsNil(err))) } else { qt.Assert(t, qt.IsNil(err)) + switch len(f.Stmts) { + case 0: + t.Fatalf("result has no statements") + case 1: + if f.Stmts[0].Pos().IsRecovered() { + t.Fatalf("result is only a recovered statement") + } + } } qt.Assert(t, qt.Equals(countRecoveredPositions(reflect.ValueOf(f)), tc.wantMissing))