All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>,
	qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [PATCH 0/5] qobject: switch JSON parser to push
Date: Tue, 10 Feb 2026 14:06:28 +0100	[thread overview]
Message-ID: <87o6lw7nor.fsf@pond.sub.org> (raw)
In-Reply-To: <CABgObfYD6cLmN_qgmro-O2wUPqnqTn3ZUYntbPrFQkX0xE=8AQ@mail.gmail.com> (Paolo Bonzini's message of "Fri, 30 Jan 2026 14:36:40 +0100")

Paolo Bonzini <pbonzini@redhat.com> writes:

> Il ven 30 gen 2026, 14:00 Markus Armbruster <armbru@redhat.com> ha scritto:
>
>> > Another benefit is that QEMU can report the first parsing error
>> > immediately, without waiting for delimiters to be balanced.
>>
>> Sounds promising!  Let's see...
>>
>> Before the series:
>>
>>      $ socat "READLINE,prompt=QMP> " UNIX-CONNECT:$HOME/work/images/test-qmp
>>     {"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major": 10}, "package": "v10.2.0-567-gfb6b66de43-dirty"}, "capabilities": ["oob"]}}
>>     QMP> [{"a"]
>>
>> Parse error not diagnosed right away, but ...
>>
>>     QMP> }
>>     {"error": {"class": "GenericError", "desc": "JSON parse error, missing : in object pair"}}
>>
>> .... only when the streamer decides the expression is complete.
>>
>> After the series:
>>
>>     QMP> [{"a"]
>>     {"error": {"class": "GenericError", "desc": "JSON parse error at line 1, column 6, expecting ':'"}}
>>
>> Cool!  However, if I do it again, things fall apart:
>>
>>     QMP> [{"a"
>>     QMP> }
>>     QMP> }
>>     QMP> }
>>     QMP> ]
>>     QMP> ]
>>     {"error": {"class": "GenericError", "desc": "JSON parse error at line 7, column 1, expecting value"}}
>>
>> Parse error recovery not quite right?
>
> Well, if you read the above very carefully :) the error is *reported*
> immediately, but recovery still waits for delimiters to be balanced.

Yes, but the recovery regressed a bit.

Having read the entire series now, I wonder whether it's related to
capping @brace_count and @bracket_count at zero [PATCH 3].

My example input [{"a"] puts the parser in error recovery state with
brace_count == 1, bracket_count == 0.  Your parser will silently throw
away further input until brace_count drops to zero.

The old parser additionally snaps out of this unresponsive state when
bracked_count goes negative.

> In testing, when I got an error I just typed a long enough variant on
> "]}]}]}" and that is enough to recover—just like in the old parser.

With the old parser, I can park my finger on ']' or '}' for a moment,
hit return, and be good.  With the new one, I have to park on both.

More seriously, the new parser seems to break a recovery technique
documented in docs/interop/qmp-spec.rst:

    Forcing the JSON parser into known-good state
    ---------------------------------------------

    Incomplete or invalid input can leave the server's JSON parser in a
    state where it can't parse additional commands.  To get it back into
    known-good state, the client should provoke a lexical error.

    The cleanest way to do that is sending an ASCII control character
    other than ``\t`` (horizontal tab), ``\r`` (carriage return), or
    ``\n`` (new line).

Works with old parser:

    QMP> [{"a"]
    QMP> ^L
    {"error": {"class": "GenericError", "desc": "JSON parse error, stray '\f'"}}
    QMP> {}
    {"error": {"class": "GenericError", "desc": "QMP input lacks member 'execute'"}}

Note: the ^L is a formfeed character.

New parser:

    QMP> [{"a"]
    {"error": {"class": "GenericError", "desc": "JSON parse error at line 1, column 6, expecting ':'"}}
    QMP> ^L
    QMP> {}

Good: the parse error is reported immediately.

Bad: the formfeed no longer forces the parser into known-good state.
This needs fixing.

>                                                                     Still
> the difference in error reporting matters, because it gives feedback that
> is immediately useful, rather than possibly delayed forever.

Reporting parse errors immediately is such a lovely quality of life
improvement.  May I have that without regressing error recovery?

> The policy is easy to change, either in v2 or in subsequent work, because
> recovery is layered on top of json-parser and its code is nothing more than
> "if you believe it's a good time to recover, reset the parser".
>
> Paolo

>> > On top of the benefits intrinsic in the push architecture, it so happens
>> > that it's really easy to add a location to JSON parsing errors now, so
>> > do that as well.
>> >
>> > Paolo
>>
>>



  reply	other threads:[~2026-02-10 13:07 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-07  8:48 [PATCH 0/5] qobject: switch JSON parser to push Paolo Bonzini
2026-01-07  8:48 ` [PATCH 1/5] json-parser: pass around lookahead token, constify Paolo Bonzini
2026-02-06 10:45   ` Markus Armbruster
2026-02-06 10:54     ` Paolo Bonzini
2026-01-07  8:48 ` [PATCH 2/5] json-parser: replace with a push parser Paolo Bonzini
2026-02-09  9:36   ` Markus Armbruster
2026-02-09 10:53     ` Paolo Bonzini
2026-02-12 13:12       ` Markus Armbruster
2026-02-16 16:41         ` Paolo Bonzini
2026-02-17  7:39           ` Markus Armbruster
2026-01-07  8:48 ` [PATCH 3/5] json-streamer: remove token queue Paolo Bonzini
2026-02-10  7:58   ` Markus Armbruster
2026-02-10  8:22     ` Paolo Bonzini
2026-02-11  7:13       ` Markus Armbruster
2026-01-07  8:48 ` [PATCH 4/5] json-streamer: do not heap-allocate JSONToken Paolo Bonzini
2026-02-10  8:30   ` Markus Armbruster
2026-01-07  8:48 ` [PATCH 5/5] json-parser: add location to JSON parsing errors Paolo Bonzini
2026-02-10  9:21   ` Markus Armbruster
2026-02-10  9:44     ` Paolo Bonzini
2026-02-11  7:18       ` Markus Armbruster
2026-01-21  5:57 ` [PATCH 0/5] qobject: switch JSON parser to push Paolo Bonzini
2026-01-30 13:00 ` Markus Armbruster
2026-01-30 13:36   ` Paolo Bonzini
2026-02-10 13:06     ` Markus Armbruster [this message]
2026-02-10 13:12       ` Paolo Bonzini
2026-02-10 15:52         ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o6lw7nor.fsf@pond.sub.org \
    --to=armbru@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.