Follow устанавливает парсинг сверху вниз

У меня есть вопрос для Follow наборов следующих правил:

L -> CL'
L' -> epsilon
       | ; L
C -> id:=G
      |if GC
      |begin L end

Я вычислил, что Follow(L) находится в Follow(L'). Также Follow(L') находится в Follow(L), поэтому они оба будут содержать: {end, $}. Однако, поскольку L' имеет значение Nullable, будет ли Follow(L) содержать также Follow(C)?

Я вычислил, что Follow(C) = First(L'), а также Follow(C) subset Follow(L) = { ; $ end}.

В ответе Follow(L) и Follow(L') содержат только {end, $}, но разве он не должен содержать ; из Follow(C), поскольку L' может быть нулевым?

Спасибо


person user3603634    schedule 08.05.2014    source источник


Ответы (1)


Однако, поскольку L' имеет значение Nullable, будет ли Follow(L) содержать также Follow(C)?

Противоположный. Follow(C) будет содержать Follow(L). Подумайте о следующем предложении:

...Lx...

где X - некоторый терминал и, следовательно, находится в Follow(L). Это может быть расширено до:

...CL'x...

и далее к:

...Cx...

Итак, то, что следует за L, также может следовать за C. Обратное не обязательно верно.


Чтобы вычислить следующее, представьте граф, где узлы (NT, n), что означает нетерминал NT с длиной маркеров, как показано ниже (в LL (1), n равно 1 или 0). График для вас будет выглядеть так:

     _______
   |/_      \
(L, 1)----->(L', 1)         _(C, 1)
 |  \__________|____________/| |
 |             |               |
 |             |               |
 |   _______   |               |
 V |/_      \  V               V
(L, 0)----->(L', 0)         _(C, 0)
    \_______________________/|

Где (X, n)--->(Y, m) означает, что длина n из X зависит от длины m из Y (конечно, m <= n). То есть, чтобы вычислить (X, n), сначала вы должны вычислить (Y, m), а затем вы должны просмотреть каждое правило, которое содержит X в правой части и Y в левой части, например:

Y -> ... X REST

возьмите то, что REST расширяется до длины n - m для каждого m в [0, n), а затем объедините каждый результат с каждым последующим из набора (Y, m). Вы можете рассчитать, до чего расширяется REST, при вычислении первых чисел REST, просто удерживая флаг, указывающий, расширяется ли REST полностью до этого первого или частично. Кроме того, добавьте первые числа REST с длиной n, как следует из X. Например:

S -> A a b c
A -> B C d
C -> epsilon | e | f g h i

Затем, чтобы найти следы B с длиной 3 (это e d a, d a b и f g h), мы смотрим на правило:

A -> B C d

возьмем предложение C d и посмотрим, что оно может дать:

"C d" with length 0 (complete):
"C d" with length 1 (complete):
    d
"C d" with length 2 (complete):
    e d
"C d" with length 3 (complete or not):
    f g h

Теперь мы берем их и объединяем с follow(A, m):

follow(A, 0):
    epsilon
follow(A, 1):
    a
follow(A, 2):
    a b
follow(A, 3):
    a b c

"C d" with length 0 (complete) concat follow(A, 3):
"C d" with length 1 (complete) concat follow(A, 2):
    d a b
"C d" with length 2 (complete) concat follow(A, 1):
    e d a
"C d" with length 3 (complete or not) concat follow(A, 0) (Note: follow(X, 0) is always epsilon):
    f g h

Именно тот набор, который мы искали. Итак, вкратце, алгоритм становится таким:

  • Создайте график следующих зависимостей
  • Найдите связанные компоненты и создайте DAG из него.
  • Пройдите через DAG с конца (от узлов, которые не имеют никакой зависимости) и вычислите последующие с помощью приведенного выше алгоритма, предварительно рассчитав первые.

Стоит отметить, что приведенный выше алгоритм подходит для любого LL(K). Для LL(1) ситуация намного проще.

person Shahbaz    schedule 08.05.2014
comment
— Скажи мне, Джеймс, ты все еще спишь с книгой о драконах под подушкой? +1 за ясность, детализацию. - person user1666959; 08.05.2014
comment
@user1666959, многие летние ночи были потрачены на разработку этих алгоритмов. - person Shahbaz; 08.05.2014
comment
@ user1666959 Кроме того, я не могу найти эту цитату, откуда она? - person Shahbaz; 08.05.2014
comment
«Завтра не умрет никогда», — рассказывает Пэрис Карвер (Тери Хэтчер) Бонду на вечеринке, слегка перефразируя, в знак признания того, что вы, вероятно, знаете о конструкции компилятора столько же, сколько Бонд знает о своем Walther PPK. - person user1666959; 08.05.2014
comment
@ user1666959, спасибо за дополнение и информацию;) - person Shahbaz; 08.05.2014