Ответ 1
Взгляды, используемые в парсере LR (1), вычисляются следующим образом. Во-первых, состояние начала имеет элемент вида
S -> .w ($)
для каждого произведения S → w, где S - стартовый символ. Здесь маркер $обозначает конец ввода.
Далее, для любого состояния, которое содержит элемент формы A → x.By(t), где x - произвольная строка терминалов и нетерминалов, а B - нетерминал, вы добавляете элемент формы B → .w(s) для каждого произведения B → w и для каждого терминала в наборе FIRST (yt). (Здесь FIRST ссылается на FIRST sets, которые обычно вводятся, когда речь идет о парсерах LL. Если вы их раньше не видели, я бы занял несколько минут, чтобы посмотреть над этими лекциями).
Попробуй это на своей грамматике. Начнем с создания набора элементов, содержащего
S -> .AB ($)
Затем, используя наше второе правило, для каждого произведения A добавим новый элемент, соответствующий этой продукции, и с просмотрами каждого терминала в FIRST (B $). Так как B всегда создает строку d, FIRST (B $) = d, так что все производственные операции, которые мы вводим, будут иметь вид d. Это дает
S -> .AB ($)
A -> .aAb (d)
A -> .a (d)
Теперь создадим состояние, соответствующее видению "а" в этом начальном состоянии. Начнем с перемещения точки на один шаг для каждого производства, которое начинается с:
A -> a.Ab (d)
A -> a. (d)
Теперь, поскольку первый элемент имеет точку перед нетерминалом, мы используем наше правило, чтобы добавить один элемент для каждого произведения A, давая этим элементам представление FIRST (bd) = b. Это дает
A -> a.Ab (d)
A -> a. (d)
A -> .aAb (b)
A -> .a (b)
В продолжение этого процесса в конечном итоге будут построены все LR (1) состояния для этого парсера LR (1). Это показано здесь:
[0]
S -> .AB ($)
A -> .aAb (d)
A -> .a (d)
[1]
A -> a.Ab (d)
A -> a. (d)
A -> .aAb (b)
A -> .a (b)
[2]
A -> a.Ab (b)
A -> a. (b)
A -> .aAb (b)
A -> .a (b)
[3]
A -> aA.b (d)
[4]
A -> aAb. (d)
[5]
S -> A.B ($)
B -> .d ($)
[6]
B -> d. ($)
[7]
S -> AB. ($)
[8]
A -> aA.b (b)
[9]
A -> aAb. (b)
В случае, если это помогает, я преподавал курс компиляторов прошлым летом и имел все слайды лекций, доступные в Интернете. Слайды при синтаксическом анализе снизу вверх должны охватывать все детали построения пар Ling и parse table, и я надеюсь, что вы найдете их полезными!
Надеюсь, это поможет!