Implementar meu próprio JSON parser, dicas de algoritmos

Preciso implementar meu próprio parser de JSON, ele recebe uma String json e retorna um objeto, como mostra a assinatura abaixo:

public static MyObject(String myObjectJson){...}

Sim, estou ciente que existem diversas APIs que já fazem isso, mas por força maior preciso implementar na mão. Alguém tem dicas de algoritmos ou alguma referencia pra fazer isso?

obrigado!

Você precisa tomar cuidado com alguns aspectos do JSON:

  • Você pode ter objetos como atributos {"endereco" : {"logradouro": "Avenida Brasil"}}
  • Você pode ter vetores: {"itens": [{"id": 1, "categoria":"Vestuário"}, {"id":2, "categoria":"Banho"}]}
  • Você pode ter atributos nulos e/ou ausentes: {"nome": "Astolpho Pamphilo", "idade": 60} e {"nome":"Maria Nazaré", "idade" : 27, "numeroDeDependentes":2}
  • Nem sempre as aspas estarão ali e pode ser que alguém tenha tido a brilhante ideia de usar aspas simples: {codigo: 1, item: 292, quantidade: 100} e {'codigo' : 1, 'item': 292, 'quantidade' : 100} e {"codigo" : 1, "item": 292, "quantidade" : 100}

Com relação a algoritmos, eu não sei quão eficaz seria aplicar um algoritmo que empilhasse as diversas partes, até encontrar um elemento de fechamento, desempilhando tudo o que foi armazenado e processando o que existe naquele trecho da String. É um exercício muito comum, quando se aprende a programar.
De mais a mais, não me recordo de algum algoritmo que te permita manipular essas informações de maneira mais rápida.
Talvez, seria bacana usar um script externo para ganhar em performance.

2 curtidas

Tarefa interessante.

Encontrei esse projeto no GitHub: https://github.com/ralfstx/minimal-json

Eu sei que vc não quer usar código externo, mas este é um projeto pequeno e fácil de ler pra poder aprender.

Para vc ter uma idéia, veja este trecho: https://github.com/ralfstx/minimal-json/blob/master/com.eclipsesource.json/src/main/java/com/eclipsesource/json/JsonParser.java#L159

É onde começa o método readValue(). Ali tem um switch que determina que tipo de objeto JSON é o item atual com base no primeiro caracter, olha:

switch (current) {
  case 'n':
    readNull();
    break;
  case 't':
    readTrue();
    break;
  case 'f':
    readFalse();
    break;
  case '"':
    readString();
    break;
  case '[':
    readArray();
    break;
  case '{':
    readObject();
    break;
  case '-':
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
    readNumber();
    break;
  default:
    throw expected("value");
}

A partir deste trecho vc pode ir estudando os outros métodos pra enteder como funcionam e poder fazer sua própria implementação! Eu sugiro que vc clone o repositório e vá fazendo modificações, debugando e até inserindo println() em tudo que é lugar pra visualizar melhor o fluxo de execução.

Pode tentar adaptar o algoritmo recursive descend parser.