Почему синтаксический анализатор с рекурсивным спуском не может обработать левую рекурсию

Следующая демонстрация может связать несколько элементов с любым применимым событием и обратным вызовом.

Демо

Модифицированная версия кода, представленная в этой статье

class Binder {

  constructor(selector) {
    const elements = document.querySelectorAll(selector);
    this.length = elements.length;
    Object.assign(this, elements);
  }

  each(callback) {
    for (let node of Array.from(this)) {
      callback.call(node);
    }
    return this;
  }

  bind(event, callback) {
    return this.each(function() {
      this.addEventListener(event, callback, false);
    });
  }
};


const eH = selector => new Binder(selector);
const eL = element => new Binder(element);

let count = 0;

const clickCount = e => {
  const eTgt = e.currentTarget.children[0];
  count++;
  eTgt.textContent = count;
};

const colorRed = e => {
  e.target.style.color = 'red';
};

eH('.node').bind('click', clickCount);

eL('.tag').bind('click', colorRed);
[111 ]
0
TAG
TAG

23
задан Simon Johnson 11 May 2009 в 10:04
поделиться

2 ответа

учтите:

A ::= A B

эквивалентный код

boolean A() {
    if (A()) {
        return B();
    }
    return false;
}

видите бесконечную рекурсию?

30
ответ дан 29 November 2019 в 01:43
поделиться

Для всех, кому интересно,

 A ::= A B | A C | D | E

можно переписать как:

 A ::= (D | E) (B | C)*

Общая форма преобразования: любой из нерекурсивных дизъюнктов, за которым следует любое количество леворекурсивных дизъюнктов без первого элемента.

Реформирование кода действия - это немного уловка, но я думаю, что это тоже может быть пустяком.

17
ответ дан 29 November 2019 в 01:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: