#javascript #json #parsing
#javascript #json #синтаксический анализ
Вопрос:
Я долгое время смотрел на код, найденный здесь. Это функция синтаксического анализа JSON Дугласа Крокфорда (называемая анализатором рекурсивного спуска). Кто-нибудь может подробнее рассказать о механизмах этого анализатора? Я действительно не могу разобраться в этом.
Ответ №1:
Логически вы можете начать с фактических функций синтаксического анализа, которые начинаются со строки 311 (для наглядности опущена часть приемника).
function (source, reviver) {
var resu<
text = source;
at = 0;
ch = ' ';
result = value();
white();
if (ch) {
error("Syntax error");
}
return resu<
}
Инициализирует глобальные переменные функции text
исходным текстом, position at
позицией, а текущий символ ch
— пробелом. После этого он анализирует значение путем вызова функции value
.
Каждый объект, подлежащий анализу, инкапсулируется в саму функцию (в приведенном выше примере объект value). Их несколько: number
, string
, white
, …). Каждый из них в основном работает одинаково. Сначала мы рассмотрим white
в качестве базового примера:
white = function () {
// Skip whitespace.
while (ch amp;amp; ch <= ' ') {
next();
}
}
Обратите внимание, что ch
всегда содержит текущий символ. Эта переменная обновляется только при next
чтении следующей переменной. Это можно увидеть внутри, white
где каждый пробел поглощается вызовом next
. Таким образом, после вызова этой функции первый символ без пробела будет в переменной ch
.
Давайте рассмотрим более сложный пример value
:
value = function () {
// Parse a JSON value. It could be an object, an array, a string, a number,
// or a word.
white();
switch (ch) {
case '{':
return object();
case '[':
return array();
case '"':
return string();
case '-':
return number();
default:
return ch >= '0' amp;amp; ch <= '9' ? number() : word();
}
};
Сначала он анализирует пробелы путем вызова white
. Обратите внимание, что ch
теперь содержит текущий символ, подлежащий анализу. Если это a, то '{'
теперь мы узнаем, что следующим идет объект json, и вызываем соответствующую функцию object
. Если вместо этого это '['
, мы ожидаем массив json и так далее.
Все остальные функции построены таким же образом: проверяют текущий символ, решают, что должно быть следующим, а затем анализируют этот объект.
Сам объект может содержать другие значения, и поэтому вы снова обнаружите непрямой рекурсивный вызов функции value
в object
. Таким образом, рекурсивный вызов всех объектных функций json фактически анализирует их из исходной строки.