Files
freeCodeCamp/curriculum/challenges/russian/08-coding-interview-prep/rosetta-code/s-expressions.russian.md

5.8 KiB
Raw Blame History

title, id, challengeType, forumTopicId, localeTitle
title id challengeType forumTopicId localeTitle
S-Expressions 59667989bf71cf555dd5d2ff 5 302303 S-выражение

Description

S-выражения - один из удобных способов анализа и хранения данных.

Задача:

Напишите простой читатель / парсер для S-Expressions, который обрабатывает строки с кавычками и без кавычек, целые числа и поплавки.

Функция должна читать одно, но вложенное S-выражение из строки и возвращать его как (вложенный) массив.

Новые строки и другие пробелы могут игнорироваться, если они не содержатся в цитируемой строке.

" () " Внутри цитируемых строк не интерпретируются, а рассматриваются как часть строки.

Обработка скрытых кавычек внутри строки необязательна; таким образом " (foo" bar) "может рассматриваться как строка" foo "bar " или как ошибка.

Для этого читатель не должен распознавать « \ » для экранирования, но должен, кроме того, распознавать номера, если язык имеет соответствующие типы данных.

Обратите внимание, что за исключением « (» « » (« \ », если поддерживается escaping) и пробелов нет специальных символов. Все остальное разрешено без кавычек.

Читатель должен уметь читать следующий ввод

 ((данные «котируемые данные» 123 4.5)
    (данные (! @ # (4.5) "(более" "данные)")))

и превратить его в родную структуру данных. (см. реализации Pike , Python и Ruby для примеров встроенных структур данных.)

Instructions

Write a simple reader/parser for S-Expressions that handles quoted and unquoted strings, integers and floats. The function should read a single but nested S-Expression from a string and return it as a (nested) array. Newlines and other whitespace may be ignored unless contained within a quoted string. "()" inside quoted strings are not interpreted, but treated as part of the string. Handling escaped quotes inside a string is optional; thus "(foo"bar)" may be treated as a string "foo"bar", or as an error. For this, the reader need not recognize "\" for escaping, but should, in addition, recognize numbers if the language has appropriate data types. Note that with the exception of "()"" ("\" if escaping is supported) and whitespace there are no special characters. Anything else is allowed without quotes. The reader should be able to read the following input
((data "quoted data" 123 4.5)
(data (!@# (4.5) "(more" "data)")))
and turn it into a native data structure. (See the Pike, Python and Ruby implementations for examples of native data structures.)

Tests

tests:
  - text: <code>parseSexpr</code> is a function.
    testString: assert(typeof parseSexpr === 'function');
  - text: <code>parseSexpr('(data1 data2 data3)')</code> should return <code>['data1', 'data2', 'data3']</code>
    testString: assert.deepEqual(parseSexpr(simpleSExpr), simpleSolution);
  - text: <code>parseSexpr('(data1 data2 data3)')</code> should return an array with 3 elements.
    testString: assert.deepEqual(parseSexpr(basicSExpr), basicSolution);

Challenge Seed

function parseSexpr(str) {
  // Good luck!
  return true;
}

After Tests

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)\""]]];

Solution

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(''));
}