=======================
Parser JSON Common Lisp
=======================
Testato con SBCL, Clisp e LispWorks.
L'elaborato è stato prodotto in autonomia da Davide Mereu Depau.
Scelte implementative
=====================
Le specifiche non prevedevano il parsing dei valori JSON true, false e null;
ho per cui considerato il loro comportamento implementation-defined e il parser
li interpreta nel seguente modo:
- true -> T
- false -> NIL
- null -> 'jsonnull
Le specifiche inoltre considerano opzionale il parsing dei caratteri Unicode.
Il comportamento in presenza di tale escape sequence è pertanto implementation-
defined e si comporta in questo modo:
- Deserializzazione:
- Escape Unicode `\u` viene letto come `u`
- I caratteri Unicode fanno fallire il parsing
- Serializzazione:
- Non essendo interpretato, `\u` diviene `u`
- Non essendo accettati, i caratteri Unicode non vengono emessi
Il parser non è infine in grado di deserializzare numeri decimali con precisione
superiore a double (123.456e78 viene rigettato).
Ci tenevo a essere compliant fatta esclusione delle eccezioni di cui sopra, per
cui ho utilizzato la test suite [1] per validare l'implementazione.
Ho deciso di verificare in maniera "strict" la complessa grammatica dei numeri
JSON. Il seguente flowchart MermaidJS [2] rappresenta la macchina a stati
finiti che ho implementato.
flowchart TD
start(( ))
accept((( )))
start -- - --> negative
start -- 0 --> leading_zero
start -- 1-9 --> integer
negative -- 0 --> leading_zero
negative -- 1-9 --> integer
leading_zero -- . --> incomplete_float
leading_zero -- "e|E\nEmit .0d" --> incomplete_exponent
leading_zero -- "*|NIL" --> accept
integer -- . --> incomplete_float
integer -- 0-9 --> integer
integer -- "e|E\nEmit .0d" --> incomplete_exponent
integer -- "*|NIL" --> accept
incomplete_float -- 0-9 --> float
float -- 0-9 --> float
float -- "e|E\nEmit d" --> incomplete_exponent
float -- "*|NIL\nAdd d0" --> accept
incomplete_exponent -- "+|-" --> incomplete_exponent_sign
incomplete_exponent -- 0-9 --> exponent
incomplete_exponent_sign -- 0-9 --> exponent
exponent -- 0-9 --> exponent
exponent -- "*|NIL" --> accept
Riferimenti:
[1] https://github.com/nst/JSONTestSuite
[2] https://mermaid.live