Для вычисления наборов FIRST вы обычно выполняете итерацию с фиксированной точкой . То есть вы начинаете с небольшого набора значений, а затем итеративно пересчитываете FIRST, пока сборы не сближаются.
В этом случае вы должны начать, отметив, что производство A → s означает, что FIRST (A) должен содержать {s}. Поэтому сначала вы устанавливаете FIRST (A) = {s}.
Теперь вы перебираете каждую продукцию A и обновляете FIRST на основе знаний о наборах FIRST, которые вы вычислили до сих пор. Например, правило
→ AAB
означает, что вы должны обновить FIRST (A), чтобы включить все элементы FIRST (AAB). Это не изменит FIRST (A). Затем вы посетите
→ Ab
Вы снова обновить FIRST (A), чтобы включить FIRST (Ab), которая не является снова не оп. Наконец, вы посетите
→ s
И так как FIRST (A) уже содержит с, это не вызывает никаких изменений.
Поскольку на этой итерации ничего не изменилось, вы получите FIRST (A) = {s}, что действительно правильно, потому что любой вывод, начинающийся с A, в конечном итоге будет производить s
в качестве его первого символа.
Для получения дополнительной информации, вы можете найти these lecture slides полезный (здесь part two). Они подробно описывают, как работает синтаксический анализ сверху вниз и как итеративно вычислять FIRST.
Надеюсь, это поможет!
@ Apalala- Вы уверены, что увидели это? Символ 'b' определенно не в FIRST (A). Алгоритм, который я знаю для вычисления FIRST-наборов, работает, посеяв FIRST-набор со всеми постановками, начиная с терминала, а затем исходя из этого. – templatetypedef
@ Apalala- Альтернативно, если вы не заселили все так, вы не вычисляете FIRST-множества, просматривая FIRST-набор нетерминала, если только этот нетерминал не сможет произвести эпсилон. Это означало бы, что правило обновления добавит FIRST (A) в FIRST (A), что добавит пустой набор в себя. – templatetypedef
Вы можете засеять FIRST терминалами для правил формы 'A -> b', но это недостаточно общее. Но причина моего понижения заключается в том, что вы предполагаете, что при вычислении FIRST из «A -> AAb» нужно смотреть только на первый «A», и это неправильно, потому что, хотя и не в этом случае, может быть, что ' A = * => ε', что сделало бы 'FIRST (A)' содержать 'b'. Пожалуйста, см. Мой ответ для общего решения * FIRST *. – Apalala