Files

3.8 KiB
Raw Permalink Blame History

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
59667989bf71cf555dd5d2ff S-вирази 5 302303 s-expressions

--description--

S-вирази - це зручний спосіб для аналізу та зберігання даних.

--instructions--

Напишіть простий синтаксичний аналізатор для S-виразів, який зможе опрацьовувати рядки та цілі числа в лапках та без них.

Функція має зчитувати один, але конкретний S-вираз з рядка і повертати його (конкретним) масивом.

За межами лапок символи розриву строки та інші пробіли можуть бути проігноровані.

"()" всередині лапок не інтерпретуються, а розглядається як частина рядка.

Обробка пропущених лапок всередині рядка не є обов'язковою; таким чином "(foo"bar)" може розглядатися як рядок "foo"bar", або як помилка.

Для цього не потрібно розпізнавати \ для екранування, але окрім того варто розгледіти цифри, якщо мова має відповідні типи даних.

Зверніть увагу, що, за винятком пробілів та ()" (\, якщо екранування підтримується), спеціальних символів немає. Все інше можна використовувати без лапок.

Читач має вміти прочитати наступні вхідні дані

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

і перетворити його на початкову структуру даних. (Дивіться Pike, Python and Ruby implementations задля прикладів початкових структур даних.)

--hints--

parseSexpr має бути функцією.

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

parseSexpr('(data1 data2 data3)') має повернути ['data1', 'data2', 'data3']

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

parseSexpr('((data "quoted data" 123 4.5) (data (!@# (4.5) "(more" "data)")))') має повернути [['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(''));
}