Допустим, у меня есть эта грамматика:
A: ε
| B 'a'
B: ε
| B 'b'
Что считается замыканием элемента A: • B 'a'
?
Другими словами, как мне работать с эпсилон-переходами при вычислении замыканий?
Допустим, у меня есть эта грамматика:
A: ε
| B 'a'
B: ε
| B 'b'
Что считается замыканием элемента A: • B 'a'
?
Другими словами, как мне работать с эпсилон-переходами при вычислении замыканий?
Это довольно просто. Входит в состав закрытия
A = ... <dot> X ... ;
все правила
X = <dot> R1 R2 R3 ... ;
где first(R1) не пусто. Для каждого (непустого) токена K в первом (R1) вам нужно (транзитивно!) включить
R1 = <dot> k ... ;
и т. д., но, по-видимому, вы уже поняли это.
Ваш конкретный вопрос: что произойдет, если R1 может быть пустым? Тогда вам также нужно включить
X = R1 <dot> R2 ... ;
Аналогично для пустого R2, если R1 может быть пустым, и аналогично для Ri пустого, если R1 .. Ri-1 может быть пустым. В экстремальных обстоятельствах все Ri могут быть пустыми (множество необязательных подпунктов в вашей грамматике), и вы можете в конечном итоге включить
X = R1 R2 ... Rn <dot> ;
Обратите внимание, что определение того, что first(R1) «может быть пустым», само по себе является вопросом транзитивного закрытия.
Генератор синтаксического анализатора GLR, который я создал для DMS, предварительно вычисляет first_can_be_empty, используя алгоритм Уоршалла, а затем использует его в построении замыкания.