{
  "claim": "Pareas ships no test that compares its token stream against a reference. I built one. Fourteen inputs through the generated JSON lexer (the repo's own tables, driven one pair at a time through the same merge operator the GPU scan uses), against Python 3's json module as the reference decoder. Five of the fourteen disagree, which is three distinct defects.",
  "method": "lexcheck.cpp \u2014 my harness, not in the repo. It constructs pareas::lexer::ParallelLexer from src/json/json.lex exactly as src/lpg/main.cpp does, then walks the merge table sequentially, which is the same function src/compiler/lexer/lexer.fut hands to Futhark's `scan`. Input bytes are widened through `unsigned char`, matching lexer.fut's `u8.to_i64 x`; the repo's own LexerInterpreter uses a signed char and indexes out of bounds on any byte \u2265 0x80. Reference column is `json.loads` on CPython 3.11.",
  "source": "https://datatracker.ietf.org/doc/html/rfc8259",
  "captured": "2026-09-18",
  "columns": [
    { "key": "input", "label": "input" },
    { "key": "pareas", "label": "pareas json.lex" },
    { "key": "ref", "label": "python json" },
    { "key": "verdict", "label": "verdict" }
  ],
  "rows": [
    {
      "input": "{\"a\":1}",
      "pareas": "lbrace string colon number rbrace",
      "ref": "accept",
      "verdict": "agree"
    },
    {
      "input": "[1.5e+10,-0,0.25]",
      "pareas": "lbracket number comma number comma number rbracket",
      "ref": "accept",
      "verdict": "agree"
    },
    {
      "input": "[\"a\\tb\\u0041\\/\\\\\"]",
      "pareas": "lbracket string rbracket",
      "ref": "accept",
      "verdict": "agree"
    },
    {
      "input": "\"\\u00e9\"  (lowercase hex)",
      "pareas": "string",
      "ref": "accept",
      "verdict": "agree"
    },
    {
      "input": "\"\\u00E9\"  (uppercase hex)",
      "pareas": "(input error)",
      "ref": "accept",
      "verdict": "DISAGREE"
    },
    {
      "input": "\"\\u00Ff\"  (mixed hex)",
      "pareas": "(input error)",
      "ref": "accept",
      "verdict": "DISAGREE"
    },
    {
      "input": "\"\u00e9\"  (C3 A9, valid UTF-8)",
      "pareas": "string",
      "ref": "accept",
      "verdict": "agree"
    },
    {
      "input": "\"\u00ff\u00fe\"  (FF FE, invalid UTF-8)",
      "pareas": "string",
      "ref": "reject",
      "verdict": "DISAGREE"
    },
    {
      "input": "\"\u0080\"  (lone continuation byte)",
      "pareas": "string",
      "ref": "reject",
      "verdict": "DISAGREE"
    },
    {
      "input": "\"a\u007fb\"  (raw DEL, 0x7F)",
      "pareas": "(input error)",
      "ref": "accept",
      "verdict": "DISAGREE"
    },
    {
      "input": "\"a\\tb\"  (raw TAB, 0x09)",
      "pareas": "(input error)",
      "ref": "reject",
      "verdict": "agree"
    },
    {
      "input": "\"abc  (unterminated)",
      "pareas": "(input error)",
      "ref": "reject",
      "verdict": "agree"
    },
    {
      "input": "01",
      "pareas": "number number",
      "ref": "reject",
      "verdict": "deferred to parser"
    },
    {
      "input": "+1",
      "pareas": "(input error)",
      "ref": "reject",
      "verdict": "agree"
    }
  ],
  "note": "Five rows are marked DISAGREE and one is deferred. Two of the five are the same bug counted twice (uppercase hex in a \\uXXXX escape), so it is four distinct defects: uppercase hex escapes rejected, raw 0x7F rejected, and invalid UTF-8 accepted without complaint. RFC 8259 \u00a77 defines the escape as %x75 4HEXDIG, and ABNF terminals are case-insensitive; \u00a77 also permits unescaped %x20-21 / %x23-5B / %x5D-10FFFF, which includes 0x7F. The `01` row is not a lexer defect \u2014 the token stream `number number` is not a valid JSON document, so the parser rejects it downstream."
}
