Шаг 2. Если множество первых символов содержит нетерминал В, то включить в него символы множества ПЕРВ(В), определенное на шаге 0.
ПЕРВ(1) 2 | using |
ПЕРВ(2) 2 | public |
ПЕРВ(3) 2 | ; |
ПЕРВ(4) 2 | |
ПЕРВ(5) 2 | ID |
ПЕРВ(6) 2 | . |
ПЕРВ(7) 2 | |
ПЕРВ(8) 2 | class |
ПЕРВ(9) 2 | public |
ПЕРВ(10) 2 | ; |
ПЕРВ(11) 2 | |
ПЕРВ(12) 2 | uint |
ПЕРВ(13) 2 | bool |
ПЕРВ(14) 2 | const |
ПЕРВ(15) 2 | ID |
ПЕРВ(16) 2 | ( |
ПЕРВ(17) 2 | , |
ПЕРВ(18) 2 | = |
ПЕРВ(19) 2 | |
ПЕРВ(20) 2 | ID |
ПЕРВ(21) 2 | , |
ПЕРВ(22) 2 | = |
ПЕРВ(23) 2 | |
ПЕРВ(24) 2 | for break continue write read ID |
ПЕРВ(25) 2 | ; |
ПЕРВ(26) 2 | |
ПЕРВ(27) 2 | for |
ПЕРВ(28) 2 | break |
ПЕРВ(29) 2 | continue |
ПЕРВ(30) 2 | write |
ПЕРВ(31) 2 | read |
ПЕРВ(32) 2 | ID |
ПЕРВ(33) 2 | = |
ПЕРВ(34) 2 | * |
ПЕРВ(35) 2 | / |
ПЕРВ(36) 2 | ( |
ПЕРВ(37) 2 | ID |
ПЕРВ(38) 2 | NUM |
ПЕРВ(39) 2 | + |
ПЕРВ(40) 2 | - |
ПЕРВ(41) 2 | |
ПЕРВ(42) 2 | ( |
ПЕРВ(43) 2 | ( ID NUM |
ПЕРВ(44) 2 | > |
ПЕРВ(45) 2 | < |
ПЕРВ(46) 2 | = |
ПЕРВ(47) 2 |
Шаг 3. Если ПЕРВ(n)i+1 ≠ ПЕРВ(n)i, то i = i + 1 и перейти к шагу 2, иначе закончить.
Построение множества ПЕРВ(А). Множества ПЕРВ(А) необходимо для определения множеств СЛЕД(А).
Шаг 1. Для построения множества ПЕРВ(А) = FIRST(1, A), где А - нетерминал в правой части правил, определим множества первых символов, стоящих в начале правых частей правил, для каждого нетерминала в левой части правил.
ПЕРВ(<S>) | using public |
ПЕРВ(<NEXT>) | ; |
ПЕРВ(<USING_LIST>) | ID |
ПЕРВ(<NEXT_USING>) | . |
ПЕРВ(<CLASS>) | class |
ПЕРВ(<CLASS_BODY>) | public |
ПЕРВ(<NEXT_BODY>) | ; |
ПЕРВ(<DEF>) | uint bool const |
ПЕРВ(<DEF_LIST>) | ID |
ПЕРВ(<NEXT_DEF>) | ( , = |
ПЕРВ(<VAR_LIST>) | ID |
ПЕРВ(<NEXT_VAR>) | , = |
ПЕРВ(<OPER_LIST>) | <OPERATOR> |
ПЕРВ(<NEXT_OPER>) | ; |
ПЕРВ(<OPERATOR>) | for break continue write read ID |
ПЕРВ(<LET>) | = * / |
ПЕРВ(<EXPR>) | ( ID NUM |
ПЕРВ(<OPERATION>) | + - |
ПЕРВ(<COND>) | <EXPR> ( |
ПЕРВ(<RELATION>) | > < = |
Шаг 2. Если множество первых символов содержит нетерминал В, то включить в него символы множества ПЕРВ(В), i=0.
ПЕРВ(<S>)0 | using public |
ПЕРВ(<NEXT>)0 | ; |
ПЕРВ(<USING_LIST>)0 | ID |
ПЕРВ(<NEXT_USING>)0 | . |
ПЕРВ(<CLASS>)0 | class |
ПЕРВ(<CLASS_BODY>)0 | public |
ПЕРВ(<NEXT_BODY>)0 | ; |
ПЕРВ(<DEF>)0 | uint bool const |
ПЕРВ(<DEF_LIST>)0 | ID |
ПЕРВ(<NEXT_DEF>)0 | ( , = |
ПЕРВ(<VAR_LIST>)0 | ID |
ПЕРВ(<NEXT_VAR>)0 | , = |
ПЕРВ(<OPER_LIST>)0 | for break continue write read ID |
ПЕРВ(<NEXT_OPER>)0 | ; |
ПЕРВ(<OPERATOR>)0 | for break continue write read ID |
ПЕРВ(<LET>)0 | = * / |
ПЕРВ(<EXPR>)0 | ( ID NUM |
ПЕРВ(<OPERATION>)0 | + - |
ПЕРВ(<COND>)0 | ( ID NUM |
ПЕРВ(<RELATION>)0 | > < = |
Шаг 3. Выполнение шага 2 привело к изменению множеств ПЕРВ(А), поэтому повторим шаг 2.
Шаг 2. Если множество первых символов содержит нетерминал В, то включить в него символы множества ПЕРВ(В), i=1.
ПЕРВ(<S>)1 | using public |
ПЕРВ(<NEXT>)1 | ; |
ПЕРВ(<USING_LIST>)1 | ID |
ПЕРВ(<NEXT_USING>)1 | . |
ПЕРВ(<CLASS>)1 | class |
ПЕРВ(<CLASS_BODY>)1 | public |
ПЕРВ(<NEXT_BODY>)1 | ; |
ПЕРВ(<DEF>)1 | uint bool const |
ПЕРВ(<DEF_LIST>)1 | ID |
ПЕРВ(<NEXT_DEF>)1 | ( , = |
ПЕРВ(<VAR_LIST>)1 | ID |
ПЕРВ(<NEXT_VAR>)1 | , = |
ПЕРВ(<OPER_LIST>)1 | for break continue write read ID |
ПЕРВ(<NEXT_OPER>)1 | ; |
ПЕРВ(<OPERATOR>)1 | for break continue write read ID |
ПЕРВ(<LET>)1 | = * / |
ПЕРВ(<EXPR>)1 | ( ID NUM |
ПЕРВ(<OPERATION>)1 | + - |
ПЕРВ(<COND>)1 | ( ID NUM |
ПЕРВ(<RELATION>)1 | > < = |
Шаг 3. Дальнейшее выполнения шага 2 не приведет к изменению множеств ПЕРВ(А), поэтому закончим.
Построение множества СЛЕД(А). Множества СЛЕД(А) строятся для всех нетрминальных символов грамматики методом последовательного приближения.
Шаг 1. Внесем во множество последующих символов СЛЕД(А) = FOLLOW(1, A) для каждого нетерминала А все символы, которые в правых частях правил встречаются непосредственно за символом А; i=0.
СЛЕД(<S>)0 | |
СЛЕД(<NEXT>)0 | |
СЛЕД(<USING_LIST>)0 | <NEXT> |
СЛЕД(<NEXT_USING>)0 | |
СЛЕД(<CLASS>)0 | <NEXT> |
СЛЕД(<CLASS_BODY>)0 | } |
СЛЕД(<NEXT_BODY>)0 | |
СЛЕД(<DEF>)0 | <NEXT_BODY> |
СЛЕД(<DEF_LIST>)0 | |
СЛЕД(<NEXT_DEF>)0 | |
СЛЕД(<VAR_LIST>)0 | ) |
СЛЕД(<NEXT_VAR>)0 | |
СЛЕД(<OPER_LIST>)0 | } |
СЛЕД(<NEXT_OPER>)0 | |
СЛЕД(<OPERATOR>)0 | <NEXT_OPER> |
СЛЕД(<LET>)0 | ) |
СЛЕД(<EXPR>)0 | <VAR_LIST> ; ) <RELATION> |
СЛЕД(<OPERATION>)0 | |
СЛЕД(<COND>)0 | ; ) |
СЛЕД(<RELATION>)0 |
Шаг 2. Внесем пустую цепочку (или символ конца строки) во множество последующих символов для целевого символа <S>.
СЛЕД(<S>)0 | # |
СЛЕД(<NEXT>)0 | |
СЛЕД(<USING_LIST>)0 | <NEXT> |
СЛЕД(<NEXT_USING>)0 | |
СЛЕД(<CLASS>)0 | <NEXT> |
СЛЕД(<CLASS_BODY>)0 | } |
СЛЕД(<NEXT_BODY>)0 | |
СЛЕД(<DEF>)0 | <NEXT_BODY> |
СЛЕД(<DEF_LIST>)0 | |
СЛЕД(<NEXT_DEF>)0 | |
СЛЕД(<VAR_LIST>)0 | ) |
СЛЕД(<NEXT_VAR>)0 | |
СЛЕД(<OPER_LIST>)0 | } |
СЛЕД(<NEXT_OPER>)0 | |
СЛЕД(<OPERATOR>)0 | <NEXT_OPER> |
СЛЕД(<LET>)0 | ) |
СЛЕД(<EXPR>)0 | <VAR_LIST> ; ) <RELATION> |
СЛЕД(<OPERATION>)0 | |
СЛЕД(<COND>)0 | ; ) |
СЛЕД(<RELATION>)0 |
Шаг 3. Для всех нетерминальных символов A включить во множества СЛЕД(A) множества ПЕРВ(В), где B Î СЛЕД(A).
СЛЕД(<S>)1 | # |
СЛЕД(<NEXT>)1 | |
СЛЕД(<USING_LIST>)1 | ; |
СЛЕД(<NEXT_USING>)1 | |
СЛЕД(<CLASS>)1 | ; |
СЛЕД(<CLASS_BODY>)1 | } |
СЛЕД(<NEXT_BODY>)1 | |
СЛЕД(<DEF>)1 | ; |
СЛЕД(<DEF_LIST>)1 | |
СЛЕД(<NEXT_DEF>)1 | |
СЛЕД(<VAR_LIST>)1 | ) |
СЛЕД(<NEXT_VAR>)1 | |
СЛЕД(<OPER_LIST>)1 | } |
СЛЕД(<NEXT_OPER>)1 | |
СЛЕД(<OPERATOR>)1 | ; |
СЛЕД(<LET>)1 | ) |
СЛЕД(<EXPR>)1 | ID ; ) < > = |
СЛЕД(<OPERATION>)1 | |
СЛЕД(<COND>)1 | ; ) |
СЛЕД(<RELATION>)1 |
Шаг 4. Для всех нетерминальных символов A включить во множества СЛЕД(A) множества СЛЕД (В), где B Î СЛЕД(A), если существует правило B=e.