Skip to content

Commit 9739ba4

Browse files
Patrick LehmannPatrick Lehmann
authored andcommitted
Improved JSON parser for lone standing values: string, number, true, false, null.
1 parent 161ced8 commit 9739ba4

File tree

1 file changed

+121
-8
lines changed

1 file changed

+121
-8
lines changed

vhdl/JSON.pkg.vhdl

Lines changed: 121 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use IEEE.STD_LOGIC_1164.all;
4444

4545
package JSON is
4646
constant C_JSON_VERBOSE : BOOLEAN := FALSE;
47-
constant C_JSON_NUL : CHARACTER := '`';
47+
constant C_JSON_NUL : CHARACTER := NUL;
4848

4949
subtype T_UINT16 is NATURAL range 0 to 2**16-1;
5050
type T_NATVEC is array(NATURAL range <>) of NATURAL;
@@ -315,7 +315,7 @@ package body JSON is
315315
-- report StringBuffer(1 to StringWriter - 1) severity NOTE;
316316
end procedure;
317317

318-
constant PARSER_DEPTH : POSITIVE := 128;
318+
constant PARSER_DEPTH : POSITIVE := 1023;
319319
variable StackPointer : NATURAL range 0 to PARSER_DEPTH - 1;
320320
variable ParserStack : T_PARSER_STACK(0 to PARSER_DEPTH - 1);
321321
variable ContentWriter : T_UINT16;
@@ -376,6 +376,110 @@ package body JSON is
376376
StackPointer := StackPointer + 1;
377377
ParserStack(StackPointer).State := ST_LIST;
378378
ParserStack(StackPointer).Index := IndexWriter;
379+
when '"' => -- a single quote to restore the syntax highlighting FSM in Notepad++ "
380+
IndexWriter := IndexWriter + 1;
381+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Found: String - Add new IndexElement(STR) at pos " & INTEGER'image(IndexWriter) & " setting Start to " & INTEGER'image(ContentWriter + 1) & LF); end if;
382+
Result.Index(IndexWriter).Index := IndexWriter;
383+
Result.Index(IndexWriter).ElementType := ELEM_STRING;
384+
Result.Index(IndexWriter).StringStart := ContentWriter + 1;
385+
386+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Linking new key to index " & INTEGER'image(ParserStack(StackPointer).Index) & " as child." & LF); end if;
387+
Result.Index(ParserStack(StackPointer).Index).ChildIndex := IndexWriter;
388+
389+
StackPointer := StackPointer + 1;
390+
ParserStack(StackPointer).State := ST_STRING;
391+
ParserStack(StackPointer).Index := IndexWriter;
392+
when '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
393+
ContentWriter := ContentWriter + 1;
394+
Result.Content(ContentWriter) := CurrentChar;
395+
396+
IndexWriter := IndexWriter + 1;
397+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Found: Number - Add new IndexElement(NUM) at pos " & INTEGER'image(IndexWriter) & " setting Start to " & INTEGER'image(ContentWriter) & LF); end if;
398+
Result.Index(IndexWriter).Index := IndexWriter;
399+
Result.Index(IndexWriter).ElementType := ELEM_NUMBER;
400+
Result.Index(IndexWriter).StringStart := ContentWriter;
401+
402+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Linking new key to index " & INTEGER'image(ParserStack(StackPointer).Index) & " as child." & LF); end if;
403+
Result.Index(ParserStack(StackPointer).Index).ChildIndex := IndexWriter;
404+
405+
StackPointer := StackPointer + 1;
406+
ParserStack(StackPointer).State := ST_NUMBER;
407+
ParserStack(StackPointer).Index := IndexWriter;
408+
when 'n' | 'N' =>
409+
for k in 2 to 4 loop
410+
read(CurrentLine, CurrentChar, IsString);
411+
Debug_Column := Debug_Column + 1;
412+
if (IsString = FALSE) then
413+
Result.Error := errorMessage("Parsing List(" & printPos(Debug_Row, Debug_Column) & "): Keyword 'null' is not complete.");
414+
exit loopi;
415+
elsif (CurrentChar /= C_JSON_NULL(k)) then
416+
Result.Error := errorMessage("Parsing List(" & printPos(Debug_Row, Debug_Column) & "): Keyword 'null' has a not allowed CHARACTERs.");
417+
exit loopi;
418+
end if;
419+
end loop;
420+
IndexWriter := IndexWriter + 1;
421+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Found: NULL - Add new IndexElement(NULL) at pos " & INTEGER'image(IndexWriter) & LF); end if;
422+
Result.Index(IndexWriter).Index := IndexWriter;
423+
Result.Index(IndexWriter).ElementType := ELEM_NULL;
424+
Result.Index(IndexWriter).StringStart := 0;
425+
Result.Index(IndexWriter).StringEnd := 0;
426+
427+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Linking new key to index " & INTEGER'image(ParserStack(StackPointer).Index) & " as child." & LF); end if;
428+
Result.Index(ParserStack(StackPointer).Index).ChildIndex := IndexWriter;
429+
430+
StackPointer := StackPointer + 1;
431+
ParserStack(StackPointer).State := ST_NULL_END;
432+
ParserStack(StackPointer).Index := IndexWriter;
433+
when 't' | 'T' =>
434+
for k in 2 to 4 loop
435+
read(CurrentLine, CurrentChar, IsString);
436+
Debug_Column := Debug_Column + 1;
437+
if (IsString = FALSE) then
438+
Result.Error := errorMessage("Parsing Delimiter3(" & printPos(Debug_Row, Debug_Column) & "): Keyword 'true' is not complete.");
439+
exit loopi;
440+
elsif (CurrentChar /= C_JSON_TRUE(k)) then
441+
Result.Error := errorMessage("Parsing Delimiter3(" & printPos(Debug_Row, Debug_Column) & "): Keyword 'true' as not allowed CHARACTERs.");
442+
exit loopi;
443+
end if;
444+
end loop;
445+
IndexWriter := IndexWriter + 1;
446+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Found: TRUE - Add new IndexElement(TRUE) at pos " & INTEGER'image(IndexWriter) & LF); end if;
447+
Result.Index(IndexWriter).Index := IndexWriter;
448+
Result.Index(IndexWriter).ElementType := ELEM_TRUE;
449+
Result.Index(IndexWriter).StringStart := 0;
450+
Result.Index(IndexWriter).StringEnd := 0;
451+
452+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Linking new key to index " & INTEGER'image(ParserStack(StackPointer).Index) & " as child." & LF); end if;
453+
Result.Index(ParserStack(StackPointer).Index).ChildIndex := IndexWriter;
454+
455+
StackPointer := StackPointer + 1;
456+
ParserStack(StackPointer).State := ST_TRUE_END;
457+
ParserStack(StackPointer).Index := IndexWriter;
458+
when 'f' | 'F' =>
459+
for k in 2 to 5 loop
460+
read(CurrentLine, CurrentChar, IsString);
461+
Debug_Column := Debug_Column + 1;
462+
if (IsString = FALSE) then
463+
Result.Error := errorMessage("Parsing Delimiter3(" & printPos(Debug_Row, Debug_Column) & "): Keyword 'false' is not complete.");
464+
exit loopi;
465+
elsif (CurrentChar /= C_JSON_FALSE(k)) then
466+
Result.Error := errorMessage("Parsing Delimiter3(" & printPos(Debug_Row, Debug_Column) & "): Keyword 'false' as not allowed CHARACTERs.");
467+
exit loopi;
468+
end if;
469+
end loop;
470+
IndexWriter := IndexWriter + 1;
471+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Found: FALSE - Add new IndexElement(FALSE) at pos " & INTEGER'image(IndexWriter) & LF); end if;
472+
Result.Index(IndexWriter).Index := IndexWriter;
473+
Result.Index(IndexWriter).ElementType := ELEM_FALSE;
474+
Result.Index(IndexWriter).StringStart := 0;
475+
Result.Index(IndexWriter).StringEnd := 0;
476+
477+
if (VERBOSE = TRUE) then jsonStringAppend(StringBuffer, StringWriter, "Linking new key to index " & INTEGER'image(ParserStack(StackPointer).Index) & " as child." & LF); end if;
478+
Result.Index(ParserStack(StackPointer).Index).ChildIndex := IndexWriter;
479+
480+
StackPointer := StackPointer + 1;
481+
ParserStack(StackPointer).State := ST_FALSE_END;
482+
ParserStack(StackPointer).Index := IndexWriter;
379483
when others =>
380484
Result.Error := errorMessage("Parsing Header(" & printPos(Debug_Row, Debug_Column) & "): Char '" & CurrentChar & "' is not allowed.");
381485
exit loopi;
@@ -763,8 +867,8 @@ package body JSON is
763867
ParserStack(StackPointer).State := ST_KEY;
764868
ParserStack(StackPointer).Index := IndexWriter;
765869
when others =>
766-
printParserStack(ParserStack(0 to StackPointer), StringBuffer, StringWriter);
767-
report StringBuffer(1 to StringWriter - 1) severity NOTE;
870+
-- printParserStack(ParserStack(0 to StackPointer), StringBuffer, StringWriter);
871+
-- report StringBuffer(1 to StringWriter - 1) severity NOTE;
768872
Result.Error := errorMessage("Parsing Delimiter2(" & printPos(Debug_Row, Debug_Column) & "): Char '" & CurrentChar & "' is not allowed.");
769873
exit loopi;
770874
end case;
@@ -1254,7 +1358,7 @@ package body JSON is
12541358
if (VERBOSE = TRUE) then
12551359
printParserStack(ParserStack(0 to StackPointer), StringBuffer, StringWriter);
12561360
jsonReportIndex(Result.Index(0 to IndexWriter), Result.Content(1 to ContentWriter), StringBuffer, StringWriter);
1257-
report StringBuffer(1 to StringWriter - 1) severity NOTE;
1361+
report StringBuffer(1 to StringWriter - 1) severity NOTE;
12581362
end if;
12591363
end loop;
12601364
end loop;
@@ -1266,16 +1370,25 @@ package body JSON is
12661370
if (VERBOSE = TRUE) then
12671371
jsonStringClear(StringBuffer, StringWriter);
12681372
jsonReportIndex(Result.Index(0 to Result.IndexCount - 1), Result.Content(1 to Result.ContentCount), StringBuffer, StringWriter);
1269-
report StringBuffer(1 to StringWriter - 1) severity NOTE;
1373+
report StringBuffer(1 to StringWriter - 1) severity NOTE;
12701374
end if;
12711375

12721376
file_close(FileHandle);
12731377

12741378
if (Result.Error(1) /= C_JSON_NUL) then
12751379
return Result;
12761380
elsif ((StackPointer /= 1) or (ParserStack(StackPointer).State /= ST_CLOSED)) then
1277-
Result.Error := errorMessage("(" & printPos(Debug_Row, Debug_Column) & ") Reached end of file before end of structure.");
1278-
return Result;
1381+
case ParserStack(StackPointer).State is
1382+
when ST_FALSE_END | ST_NULL_END | ST_TRUE_END => null;
1383+
when ST_STRING_END | ST_NUMBER_END => null;
1384+
when ST_CLOSED => null;
1385+
when others =>
1386+
printParserStack(ParserStack(0 to StackPointer), StringBuffer, StringWriter);
1387+
jsonReportIndex(Result.Index(0 to IndexWriter), Result.Content(1 to ContentWriter), StringBuffer, StringWriter);
1388+
report StringBuffer(1 to StringWriter - 1) severity NOTE;
1389+
Result.Error := errorMessage("(" & printPos(Debug_Row, Debug_Column) & ") Reached end of file before end of structure.");
1390+
return Result;
1391+
end case;
12791392
end if;
12801393

12811394
return Result;

0 commit comments

Comments
 (0)