freeCodeCamp/curriculum/challenges/portuguese/10-coding-interview-prep/rosetta-code/s-expressions.md

3.1 KiB

id title challengeType forumTopicId dashedName
59667989bf71cf555dd5d2ff Expressões S 5 302303 s-expressions

--description--

Expressões S são uma maneira conveniente de analisar e armazenar dados.

--instructions--

Escreva um leitor/analisador simples para Expressões S que lide com strings entre aspas ou não, números inteiros e flutuantes (decimais).

A função deve ler uma única Expressão S, porém aninhada, de uma string e retorná-la como um array (aninhado).

Novas linhas e outros tipos de espaço em branco devem ser ignorados a menos que estejam contidos em uma string entre aspas.

"()" em strings entre aspas não são interpretados, mas tratados como parte da string.

Tratar de aspas com escape dentro de uma string é opcional. Assim, "(foo"bar)" pode ser tratado como uma string "foo"bar" ou como um erro.

Para isso, o leitor não precisa reconhecer \ para escape, mas deve, além disso, reconhecer números se a linguagem tiver tipos de dados apropriados.

Observe que, com a exceção de ()" (\, se houver suporte a escape) e do espaço em branco, não há caracteres especiais. Todo o resto é permitido sem aspas.

O leitor deve poder ler a entrada a seguir

((data "quoted data" 123 4.5)
(data (!@# (4.5) "(more" "data)")))

e transformá-la em uma estrutura de dados nativa. (veja as implementações em Pike, Python e Ruby para obter exemplos de estruturas de dados nativas.)

--hints--

parseSexpr deve ser uma função.

assert(typeof parseSexpr === 'function');

parseSexpr('(data1 data2 data3)') deve retornar ['data1', 'data2', 'data3']

assert.deepEqual(parseSexpr(simpleSExpr), simpleSolution);

parseSexpr('((data "quoted data" 123 4.5) (data (!@# (4.5) "(more" "data)")))') deve retornar [['data', '"quoted data"', 123, 4.5], ['data', ['!@#', [4.5], '"(more"', '"data)"']]].

assert.deepEqual(parseSexpr(basicSExpr), basicSolution);

--seed--

--after-user-code--

const simpleSExpr = '(data1 data2 data3)';
const simpleSolution = ['data1', 'data2', 'data3'];

const basicSExpr = '((data "quoted data" 123 4.5) (data (!@# (4.5) "(more" "data)")))';
const basicSolution = [["data","\"quoted data\"",123,4.5],["data",["!@#",[4.5],"\"(more\"","\"data)\""]]];

--seed-contents--

function parseSexpr(str) {

  return true;
}

--solutions--

function parseSexpr(str) {
  const t = str.match(/\s*("[^"]*"|\(|\)|"|[^\s()"]+)/g);
  for (var o, c = 0, i = t.length - 1; i >= 0; i--) {
    var n,
      ti = t[i].trim();
    if (ti == '"') return;
    else if (ti == '(') t[i] = '[', c += 1;
    else if (ti == ')') t[i] = ']', c -= 1;
    else if ((n = +ti) == ti) t[i] = n;
    else t[i] = `'${ti.replace('\'', '\\\'')}'`;
    if (i > 0 && ti != ']' && t[i - 1].trim() != '(') t.splice(i, 0, ',');
    if (!c) if (!o) o = true; else return;
  }
  return c ? undefined : eval(t.join(''));
}