Paolo Bonzini <[email protected]> writes:

> This rewrites the json-parser to use a push parser aka state machine.
> While push parsers are inherently more complex than recursive descent,
> the grammar for JSON is simple enough that the parser remains readable.
> There is therefore no need to use e.g. QEMU coroutines.
>
> Unlike the suggestion in commit 62815d85aed ("json: Redesign the callback
> to consume JSON values", 2018-08-24), I kept the json-streamer concept.
> It helps in handling input limits, it performs error recovery, and it
> converts the token-at-a-time push interface to callbacks---all things
> that are more easily done in a separate layer to keep the parser clean.
> However, there is no need anymore for it to store partial JSON objects
> in tokenized form.
>
> 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?

> 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 via email to