📄 unitmain.pas
字号:
CodeList[CodeCount].Ins := sIns;
CodeList[CodeCount].ParamA := iParamA;
CodeList[CodeCount].ParamB := iParamB;
end;
//*************************************************************************
// var_table
//*************************************************************************
//得到变量位置
function TMainForm.GetVarIndex(AVarName: TWordName): Integer;
var
iIndex: Word;
begin
Result := -1;
for iIndex := 1 to VarCount do
begin
if VarData[iIndex].FIdent = AVarName then
begin
Result := iIndex;
Break;
end; //end of If
end; //end of For
end;
//放入变量表
procedure TMainForm.EnterVar(AKind: TObjekt; AVarName: TWordName);
begin
Inc(VarCount);
with VarData[VarCount] do
begin
FType := AKind;
FIdent := AVarName;
FValue := 0;
FOffset := VarCount;
end;
end;
//是否重复声明
function TMainForm.IsDeclared(AVarName: TWordName): Boolean;
begin
if GetVarIndex(AVarName) < 0 then
Result := False
else
Result := True;
end;
//获得变量信息
function TMainForm.GetVarInfo(AVarName: TWordName): TVarRecord;
begin
if IsDeclared(AVarName) then
Result := VarData[GetVarIndex(AVarName)];
end;
//--------------------------------------------------
// main_program
//--------------------------------------------------
procedure TMainForm.Main_Program(AFollowSet: TSymbolSet);
var
iIntCodeIndex: Word;
begin
GetSym;
if Sym = ProgSym then
begin
iIntCodeIndex := CodeCount + 1;
Gen('INT',0,0);
GetSym;
Ds([BeginSym]);
if Sym = BeginSym then
begin
GetSym;
Ss([EndSym]);
if Sym = EndSym then
begin
GetSym;
if Sym = Period then
else
PutErrorToList(4);
end
else
PutErrorToList(3);
CodeList[iIntCodeIndex].ParamB := VarCount ;
//结束符号
Gen('OPR',0,0);
end
else
PutErrorToList(2);
end
else
PutErrorToList(1);
end;
//--------------------------------------------------
// Ds
//--------------------------------------------------
procedure TMainForm.DS(AFollowSet: TSymbolSet);
begin
De(AFollowSet + [Semicolon]);
while Sym = Semicolon do
begin
GetSym;
De(AFollowSet + [Semicolon]);
end;
// 现在的变量是调用不是声明
VarParseStatus := Statement;
end;
//--------------------------------------------------
// de
//--------------------------------------------------
procedure TMainForm.De(AFollowSet: TSymbolSet);
begin
GrammarTest([IntegerSym, LogicalSym, BeginSym], AFollowSet, 6);
case Sym of
IntegerSym:
begin
VarParseStatus := DeInteger;
repeat
GetSym;
if Sym = Aident then
GetSym
else PutErrorToList(5);
until Sym <> Comma;
end; //end of IntegerSym
LogicalSym:
begin
VarParseStatus := DeLogical ;
repeat
GetSym;
if Sym = Bident then
GetSym
else PutErrorToList(20);
until Sym <> Comma;
end; //end of LogicalSym
else
end; //end of case
end;
//--------------------------------------------------
// ss
//--------------------------------------------------
procedure TMainForm.Ss(AFollowSet: TSymbolSet);
begin
St(AFollowSet + [Semicolon]);
while Sym = Semicolon do
begin
GetSym;
St(AFollowSet + [Semicolon]);
end;
end;
//--------------------------------------------------
// st
//--------------------------------------------------
procedure TMainForm.St(AFollowSet: TSymbolSet);
var
LastVarName: TWordName;
iLastVarOffset: Word;
iJpcCodeIndex, iJmpCodeIndex: Word;
begin
case Sym of
Aident:
begin
LastVarName := LastVar;
GetSym;
if Sym = Eql then
begin
Sym :=Becomes;
end; //end of Equal
if Sym = Becomes then
begin
GetSym;
Ae(AFollowSet);
//获得最近解析到的变量的存储地址
iLastVarOffset := GetVarInfo(LastVarName).FOffset ;
//生成中间代码:赋值
Gen('STO',0, iLastVarOffset);
end //end of Becomes
else
begin
GrammarTest([], StartState, 7);
end; //end of skip grammar error
end; // sbAIdent
Bident:
begin
LastVarName := LastVar;
GetSym ;
if Sym = Eql then
begin
Sym := Becomes ;
end; //end of Equal
if Sym = Becomes then
begin
GetSym;
Be(AFollowSet );
iLastVarOffset := GetVarInfo(LastVarName).FOffset ;
Gen('STO',0, iLastVarOffset);
end //end of Becomes
else
begin
GrammarTest([], StartState, 9)
end; //end of skip grammar error
end; // sbBIdent
IfSym:
begin
GetSym;
Be(AFollowSet + [ThenSym] ) ;
if Sym = ThenSym then
begin
GetSym;
//jpc指令的位置
iJpcCodeIndex := CodeCount + 1;
Gen('JPC',0, 0);
//if..then部分
Ss([ElseSym, EndSym]) ;
if Sym = ElseSym then
begin
//[JMP]
iJmpCodeIndex := CodeCount + 1;
//[JMP]
Gen('JMP',0, 0);
//[JPC]
CodeList[iJpcCodeIndex].ParamB := CodeCount + 1;
//编译else..end部分
GetSym;
Ss([ElseSym, EndSym]);
//[JMP]
CodeList[iJmpCodeIndex].ParamB := CodeCount + 1;
end //end of if 'sbElseSym'
else
begin
//[JPC]
CodeList[iJpcCodeIndex].ParamB := CodeCount + 1;
end;
if Sym = EndSym then GetSym else PutErrorToList(11);
end //end of If
else
PutErrorToList(10);
end;
WhileSym :
begin
//[JMP]
iJmpCodeIndex:= CodeCount + 1;
GetSym ;
Be(AFollowSet + [DoSym] ) ;
//[JPC]
iJpcCodeIndex := CodeCount + 1;
//[JPC]
Gen('JPC',0, 0);
if Sym = DoSym then
begin
GetSym;
Ss([EndSym]);
if Sym = EndSym then GetSym else PutErrorToList(13);
//[JMP]
Gen('JMP',0, iJmpCodeIndex);
end //end of if
else
PutErrorToList(12);
//[JPC]
CodeList[iJpcCodeIndex].ParamB := CodeCount + 1;
end; // sbWhileSym
RepeatSym :
begin
//[JPC
iJpcCodeIndex := CodeCount + 1;
GetSym ;
Ss([UntilSym]);
if Sym = UntilSym then
begin
GetSym ;
Be(AFollowSet) ;
//[JPC]
Gen('JPC',0, iJpcCodeIndex);
end //end of if
else
PutErrorToList(14);
end;
WriteSym :
begin
GetSym;
Ae(AFollowSet);
Gen('OUT',0, 0);
end;
end;
end;
//--------------------------------------------------
// ae
//--------------------------------------------------
procedure TMainForm.Ae(AFollowSet: TSymbolSet);
var
op: Symbol;
begin
if Sym = Minus then
begin
op := Sym;
GetSym;
end; //End of If
At(AFollowSet + [Plus, Minus]);
if op = Minus then Gen('OPR',0, 1);
while Sym in [Plus, Minus] do
begin
op := Sym ;
GetSym;
At(AFollowSet) ;
case op of
Plus: Gen('OPR',0, 2);
Minus: Gen('OPR',0, 3);
end; //End of Case
end; //End of While
end;
//--------------------------------------------------
// at
//--------------------------------------------------
procedure TMainForm.At(AFollowSet: TSymbolSet);
var
op: Symbol;
begin
Af(AFollowSet + [Times, Slash]);
while Sym in [Times, Slash] do
begin
op := Sym;
GetSym;
Af(AFollowSet + [Times, Slash]);
case op of
Times: Gen('OPR',0, 4);
Slash: Gen('OPR',0, 5);
end; //End of Case
end; //end of while
end;
//--------------------------------------------------
// af
//--------------------------------------------------
procedure TMainForm.Af(AFollowSet: TSymbolSet);
var
iLastVarOffset: Word;
begin
GrammarTest(StartArithm, AFollowSet, 16);
while (Sym in StartArithm) do
begin
case Sym of
Aident:
begin
//得到最近的那个变量位置
iLastVarOffset := GetVarInfo(LastVar).FOffset ;
Gen('LOD',0, iLastVarOffset);
GetSym;
end; // sbAIdent
Number:
begin
Gen('LIT',0, num);
GetSym;
end;
Lparen:
begin
GetSym;
Ae(AFollowSet + [Rparen]);
if Sym = Rparen then GetSym else PutErrorToList(15);
end;
else
PutErrorToList(16);
end; //end of case
GrammarTest(AFollowSet, [Lparen], 16);
end; //end of while
end;
//--------------------------------------------------
// be
//--------------------------------------------------
procedure TMainForm.Be(AFollowSet: TSymbolSet);
begin
Bt(AFollowSet + [OrSym]);
while Sym = OrSym do
begin
GetSym;
Bt(AFollowSet + [OrSym]);
Gen('OPR',0, 15);
end;
end;
//--------------------------------------------------
// bt
//--------------------------------------------------
procedure TMainForm.Bt(AFollowSet: TSymbolSet);
begin
Bf(AFollowSet + [AndSym]);
while Sym = AndSym do
begin
GetSym;
Bf(AFollowSet + [AndSym]);
Gen('OPR',0, 14);
end;
end;
//--------------------------------------------------
// bf
//--------------------------------------------------
procedure TMainForm.Bf(AFollowSet: TSymbolSet);
var
iLastVarOffset: Word;
begin
GrammarTest(StartBool, AFollowSet, 24);
while (Sym in StartBool) do
begin
case Sym of
Bident:
begin
iLastVarOffset := GetVarInfo(LastVar).FOffset ;
Gen('LOD',0, iLastVarOffset);
GetSym;
end;
TrueSym:
begin
Gen('LIT',0, 1);
GetSym;
end;
FalseSym:
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -