class_docstr: For JSON data structures.
  
  Javascript-style comments are supported (like ``/* */`` and ``//``),
  though comments are not part of the JSON specification.
  This allows users to highlight JSON as it is used in the wild.
  
  No validation is performed on the input JSON document.
  
  .. versionadded:: 1.5
class_docstr_tok: ["For","JSON","data","structures",".","Javascript-style","comments","are","supported","(","like","``","\/","*","*","\/","``","and","``","\/\/","``",")",",","though","comments","are","not","part","of","the","JSON","specification",".","This","allows","users","to","highlight","JSON","as","it","is","used","in","the","wild",".","No","validation","is","performed","on","the","input","JSON","document",".","..","versionadded",":",":","1.5"]
docstr: Parse JSON data.
docstr_tok: ["Parse","JSON","data","."]
code: def get_tokens_unprocessed(self, text):
      """Parse JSON data."""
  
      in_string = False
      in_escape = False
      in_unicode_escape = 0
      in_whitespace = False
      in_constant = False
      in_number = False
      in_float = False
      in_punctuation = False
      in_comment_single = False
      in_comment_multiline = False
      expecting_second_comment_opener = False  # // or /*
      expecting_second_comment_closer = False  # */
  
      start = 0
  
      # The queue is used to store data that may need to be tokenized
      # differently based on what follows. In particular, JSON object
      # keys are tokenized differently than string values, but cannot
      # be distinguished until punctuation is encountered outside the
      # string.
      #
      # A ":" character after the string indicates that the string is
      # an object key; any other character indicates the string is a
      # regular string value.
      #
      # The queue holds tuples that contain the following data:
      #
      #     (start_index, token_type, text)
      #
      # By default the token type of text in double quotes is
      # String.Double. The token type will be replaced if a colon
      # is encountered after the string closes.
      #
      queue = []
  
      for stop, character in enumerate(text):
          if in_string:
              if in_unicode_escape:
                  if character in self.hexadecimals:
                      in_unicode_escape -= 1
                      if not in_unicode_escape:
                          in_escape = False
                  else:
                      in_unicode_escape = 0
                      in_escape = False
  
              elif in_escape:
                  if character == "u":
                      in_unicode_escape = 4
                  else:
                      in_escape = False
  
              elif character == "\\":
                  in_escape = True
  
              elif character == '"':
                  queue.append(
                      (start, String.Double, text[start : stop + 1])
                  )
                  in_string = False
                  in_escape = False
                  in_unicode_escape = 0
  
              continue
  
          elif in_whitespace:
              if character in self.whitespaces:
                  continue
  
              if queue:
                  queue.append((start, Whitespace, text[start:stop]))
              else:
                  yield start, Whitespace, text[start:stop]
              in_whitespace = False
              # Fall through so the new character can be evaluated.
  
          elif in_constant:
              if character in self.constants:
                  continue
  
              yield start, Keyword.Constant, text[start:stop]
              in_constant = False
              # Fall through so the new character can be evaluated.
  
          elif in_number:
              if character in self.integers:
                  continue
              elif character in self.floats:
                  in_float = True
                  continue
  
              if in_float:
                  yield start, Number.Float, text[start:stop]
              else:
                  yield start, Number.Integer, text[start:stop]
              in_number = False
              in_float = False
              # Fall through so the new character can be evaluated.
  
          elif in_punctuation:
              if character in self.punctuations:
                  continue
  
              yield start, Punctuation, text[start:stop]
              in_punctuation = False
              # Fall through so the new character can be evaluated.
  
          elif in_comment_single:
              if character != "\n":
                  continue
  
              if queue:
                  queue.append(
                      (start, Comment.Single, text[start:stop])
                  )
              else:
                  yield start, Comment.Single, text[start:stop]
  
              in_comment_single = False
              # Fall through so the new character can be evaluated.
  
          elif in_comment_multiline:
              if character == "*":
                  expecting_second_comment_closer = True
              elif expecting_second_comment_closer:
                  expecting_second_comment_closer = False
                  if character == "/":
                      if queue:
                          queue.append(
                              (
                                  start,
                                  Comment.Multiline,
                                  text[start : stop + 1],
                              )
                          )
                      else:
                          yield start, Comment.Multiline, text[
                              start : stop + 1
                          ]
  
                      in_comment_multiline = False
  
              continue
  
          elif expecting_second_comment_opener:
              expecting_second_comment_opener = False
              if character == "/":
                  in_comment_single = True
                  continue
              elif character == "*":
                  in_comment_multiline = True
                  continue
  
              # Exhaust the queue. Accept the existing token types.
              yield from queue
              queue.clear()
  
              yield start, Error, text[start:stop]
              # Fall through so the new character can be evaluated.
  
          start = stop
  
          if character == '"':
              in_string = True
  
          elif character in self.whitespaces:
              in_whitespace = True
  
          elif character in {
              "f",
              "n",
              "t",
          }:  # The first letters of true|false|null
              # Exhaust the queue. Accept the existing token types.
              yield from queue
              queue.clear()
  
              in_constant = True
  
          elif character in self.integers:
              # Exhaust the queue. Accept the existing token types.
              yield from queue
              queue.clear()
  
              in_number = True
  
          elif character == ":":
              # Yield from the queue. Replace string token types.
              for _start, _token, _text in queue:
                  # There can be only three types of tokens before a ':':
                  # Whitespace, Comment, or a quoted string.
                  #
                  # If it's a quoted string we emit Name.Tag.
                  # Otherwise, we yield the original token.
                  #
                  # In all other cases this would be invalid JSON,
                  # but this is not a validating JSON lexer, so it's OK.
                  if _token is String.Double:
                      yield _start, Name.Tag, _text
                  else:
                      yield _start, _token, _text
              queue.clear()
  
              in_punctuation = True
  
          elif character in self.punctuations:
              # Exhaust the queue. Accept the existing token types.
              yield from queue
              queue.clear()
  
              in_punctuation = True
  
          elif character == "/":
              # This is the beginning of a comment.
              expecting_second_comment_opener = True
  
          else:
              # Exhaust the queue. Accept the existing token types.
              yield from queue
              queue.clear()
  
              yield start, Error, character
  
      # Yield any remaining text.
      yield from queue
      if in_string:
          yield start, Error, text[start:]
      elif in_float:
          yield start, Number.Float, text[start:]
      elif in_number:
          yield start, Number.Integer, text[start:]
      elif in_constant:
          yield start, Keyword.Constant, text[start:]
      elif in_whitespace:
          yield start, Whitespace, text[start:]
      elif in_punctuation:
          yield start, Punctuation, text[start:]
      elif in_comment_single:
          yield start, Comment.Single, text[start:]
      elif in_comment_multiline:
          yield start, Error, text[start:]
      elif expecting_second_comment_opener:
          yield start, Error, text[start:]
  
imports: from pygments.lexer import Lexer, ExtendedRegexLexer, LexerContext, include, bygroups
  from pygments.token import Comment, Error, Keyword, Literal, Name, Number, Punctuation, String, Whitespace
label_desc: Use image node_id 1 for calling the JsonLexer obj's underlying member method code with example usage: obj.get_tokens_unprocessed(text) without return types