⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unitmain.pas

📁 词法.语法编译器 to 汇编语言 附带一个测试程序
💻 PAS
📖 第 1 页 / 共 3 页
字号:
    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 + -