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; { Функция создания списка триад начиная от корневого символа дерева синтаксического разбора } var i: integer; Opers: TOpArray; Trd: TTriad; begin { Создаем список триад } Result:= MakeTriadListNOP(symbTop,listTriad); if Result = nil then {Если ошибка, прерываем выполнение} with listTriad do begin { Создаем пустую триаду «NOP» в конце списка } Opers[1].OpType:= OP_CONST; Opers[1].ConstVal:= 0; Opers[2].OpType:= OP_CONST; Opers[2].ConstVal:= 0; Add(TTriad.Create(TRD_NOP,Opers)); for i:=Count-1 downto 0 do begin {Для всех триад в списке расставляем флаг ссылки} Trd:= Triads[i]; if Trd.TrdType in [TRD_IF,TRD_JMP] then begin { Если триада «переход» («IF» или «JMP») ссылается на другую триаду,} if Trd.OpTypes[2] = OP_LINK then listTriad[Trd.Links[2]].IsLinked:= True; { то ту триаду надо пометить } end; end; end; end; end.
Модуль построения ассемблерного кода по списку триад