listTriad[iIns2].Links[2]:= iIns3;
end;
6:{'if(B)E'} { Неполный условный оператор }
begin { Запоминаем ссылку на первый операнд
(условие «if(B)») }
Result:= MakeOperand(1{op},2{sym},listTriad.Count,
1{sym err},iIns1);
{ Если произошла ошибка, прерываем выполнение }
if Result <> nil then Exit;
Opers[2].OpType:= OP_LINK; { Второй операнд – }
Opers[2].TriadNum:= 0; {ссылка на триаду, номер
которой пока не известен}
{ Создаем триаду типа «IF» }
listTriad.Add(TTriad.Create(TRD_IF,Opers));
{ Запоминаем ссылку на второй операнд (раздел «(B)E») }
Result:= MakeOperand(2{op},4{sym},iIns1,
3{sym err},iIns2);
{ Если произошла ошибка, прерываем выполнение }
if Result <> nil then Exit;
{ Для созданной ранее триады «IF» ставим ссылку
в конец последовательности триад раздела «(B)E» }
listTriad[iIns1].Links[2]:= iIns2;
end;
8:{'while(B)doE'} { Оператор цикла «while» }
begin { Запоминаем ссылку на первый операнд
(условие «while(B)») }
iIns3:= listTriad.Count;
Result:= MakeOperand(1{op},2{sym},iIns3,
1{sym err},iIns1);
{ Если произошла ошибка, прерываем выполнение }
if Result <> nil then Exit;
Opers[2].OpType:= OP_LINK; { Второй операнд – }
Opers[2].TriadNum:= 0; {ссылка на триаду, номер
которой пока не известен}
{ Создаем триаду типа «IF» }
listTriad.Add(TTriad.Create(TRD_IF,Opers));
{ Запоминаем ссылку на второй операнд (раздел «doE») }
Result:= MakeOperand(2{op},5{sym},iIns1,
4{sym err},iIns2);
{ Если произошла ошибка, прерываем выполнение }
if Result <> nil then Exit;
Opers[1].OpType:= OP_CONST; {Заполняем операнды}
Opers[1].ConstVal:= 1; { для триады типа «JMP»,
которая должна быть в конце раздела «doE» }
{ Второй операнд – ссылка на начало списка триад }
Opers[2].OpType:= OP_LINK;
Opers[2].TriadNum:= iIns3;
{ Создаем триаду типа «JMP» }
listTriad.Add(TTriad.Create(TRD_JMP,Opers));
{ Для созданной ранее триады «IF» ставим ссылку
в конец последовательности триад раздела «doE» }
listTriad[iIns1].Links[2]:= iIns2+1;
end;
9:{'a:=E'} { Оператор присвоения }
begin { Если первый операнд не является переменной,
то это ошибка }
if symbTop[0].Lexem.LexType <> LEX_VAR then
begin
Result:= symbTop[0].Lexem; Exit;
end; { Если имя первого операнда совпадает с именем
параметра, то это семантическая ошибка }
if (symbTop[0].Lexem.VarName = NAME_INPVAR)
or (symbTop[0].Lexem.VarName = NAME_RESULT) then
begin
Result:= symbTop[0].Lexem; Exit;
end;
{ Создаем ссылку на первый операнд – переменную }
Opers[1].OpType:= OP_VAR;
Opers[1].VarLink:= symbTop[0].Lexem.VarInfo;
{ Создаем ссылку на второй операнд }
Result:= MakeOperand(2{op},2{sym},listTriad.Count,
1{sym err},iIns1);
{ Если произошла ошибка, прерываем выполнение }
if Result <> nil then Exit;
{ Создаем триаду типа «присваивание» }
listTriad.Add(TTriad.Create(TRD_ASSIGN,Opers));
end;
{ Генерация списка триад для линейных операций }
10:{'BorB'} Result:= MakeOperation(TRD_OR);
11:{'BxorB'} Result:= MakeOperation(TRD_XOR);
13:{'BandB'} Result:= MakeOperation(TRD_AND);
15:{'E
16:{'E>E'} Result:= MakeOperation(TRD_GT);
17:{'E=E'} Result:= MakeOperation(TRD_EQ);
18:{'E<>E'} Result:= MakeOperation(TRD_NEQ);
21:{'E-E'} Result:= MakeOperation(TRD_SUB);
22:{'E+E'} Result:= MakeOperation(TRD_ADD);
20:{not(B)}
begin { Создаем ссылку на первый операнд }
Result:= MakeOperand(1{op},2{sym},listTriad.Count,
1{sym err},iIns1);
{ Если произошла ошибка, прерываем выполнение }
if Result <> nil then Exit;
Opers[2].OpType:= OP_CONST; {Второй операнд для}
Opers[2].ConstVal:= 0; { NOT не имеет значения }
{ Создаем триаду типа «NOT» }
listTriad.Add(TTriad.Create(TRD_NOT,Opers));
end;
24:{uminE}
begin { Создаем ссылку на второй операнд }
Result:= MakeOperand(2{op},1{sym},listTriad.Count,
0{sym err},iIns1);
{ Если произошла ошибка, прерываем выполнение }
if Result <> nil then Exit;
Opers[1].OpType:= OP_CONST; {Первый операнд для}
Opers[1].ConstVal:= 0; { унарной операции "-"
должен быть 0 }
{ Создаем триаду типа «UMIN» }
listTriad.Add(TTriad.Create(TRD_UMIN,Opers));
end;
{ Для логических, арифметических или операторных скобок
рекурсивно вызываем функцию для второго символа }
1,7,19,26:{'progEend.,'beginEend', (E), (B) }
Result:= MakeTriadListNOP(symbTop[1],listTriad);
3:{E;E Для списка операторов нужно рекурсивно вызвать}
begin { функцию два раза }
Result:= MakeTriadListNOP(symbTop[0],listTriad);
if Result <> nil then Exit;
Result:= MakeTriadListNOP(symbTop[2],listTriad);
end;
27,28: Result:= nil; { Для лексем ничего не нужно }
{ Во всех остальных случаях нужно рекурсивно вызвать
функцию для первого символа }
else Result:= MakeTriadListNOP(symbTop[0],listTriad);
end{case Rule};
end;
function MakeTriadList(symbTop: TSymbol;
listTriad: TTriadList): TLexem;
{ Функция создания списка триад начиная от корневого
Читать дальше
Конец ознакомительного отрывка
Купить книгу