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

📄 uwdelphiparser.pas

📁 Delphi脚本控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  if Count > 0 then
    for i := 0 to Count - 1 do
      if Items[i] is TClassPropertyEntry then begin
        TClassPropertyEntry(Items[i]).IsEvent := False;
        for j := 0 to Count - 1 do
          if (Items[j] is TTypeEntry) and
             (CompareText(Items[j].Name, TClassPropertyEntry(Items[i]).TypeName) = 0) and
             ((Pos('function', LowerCase(TTypeEntry(Items[j]).ExistingType)) = 1) or
              (Pos('procedure', LowerCase(TTypeEntry(Items[j]).ExistingType)) = 1))
          then
            TClassPropertyEntry(Items[i]).IsEvent := True;
      end;
end;

function TWDelphiParser.GetCount: Integer;
begin
  Result := FItems.Count;
end;

function TWDelphiParser.GetEntry(Index: Integer): TEntry;
begin
  Result := FItems[Index];
end;

procedure TWDelphiParser.AddDefaultDelphiSymbols(
  aSybmols: array of string);
var
  i : Integer;
begin
  for i := Low(aSybmols) to High(aSybmols) do
    AddSymbolEntry(aSybmols[i], '');
end;

function TWDelphiParser.AddSymbolEntry(aName,
  aValue: String): TSymbolEntry;
begin
  Result := FindSymbolEntry(aName);
  if Result = nil then begin
    Result := TSymbolEntry.Create(aName, FRootEntry, Self);
    Result.Value := aValue;
    FItems.Add(Result);
  end;
end;

function TWDelphiParser.FindSymbolEntry(aName: String): TSymbolEntry;
var
  i : Integer;
begin
  Result := nil;
  if Count > 0 then
    for i := 0 to Count - 1 do
      if (Items[i] is TSymbolEntry) then
      if (CompareText(Items[i].Name, aName) = 0) then begin
        Result := TSymbolEntry(Items[i]);
        Break;
      end;
end;

procedure TWDelphiParser.IncludeFile(aFileName : String; var aIndex : Integer);
var
  i : Integer;
  sFileName, sDirList : String;
begin
  sDirList := GetCurrentDir;
  if FSearchPath <> '' then sDirList := ';' + FSearchPath;

  if FItems.Count > 0 then
    for i := 0 to FItems.Count - 1 do
      if TEntry(FItems[i]) is TFileEntry then begin
        if sDirList <> '' then sDirList := sDirList + ';';
        sDirList := sDirList + ExtractFilePath(TFileEntry(FItems[i]).FileName);
      end;
  sFileName := ExpandFileName(FileSearch(aFileName, sDirList));
  if sFileName = '' then begin
    FErrors.Add(Format('- Error DB96D2D1 detected in file %s [%d, %d]',
                       [FFileName, Token[aIndex].Row, Token[aIndex].Column]));
    FErrors.Add('');
    FErrors.Add(Format('Include file %s not found.', [aFileName]));
    FErrors.Add('');
    raise Exception.Create('The rest of the code ignored.');
  end;
  { Save WParser and the current position into stack }
  FWParserStack.Push(FWParser, aIndex + 1, FFileName);
  { Create a new parser and initializate it }
  FWParser := TWParser.Create(Self);
  InitWParser(FCompilerVersion, FWParser);
  FFileName := sFileName;
  FWParser.Analyze(TFileStream.Create(sFileName, fmOpenRead));
  FWParser.OwnSourceStream := True;
  aIndex := -1;
end;

procedure TWDelphiParser.StepNextToken(var aIndex: Integer);
var
  S, N, V : String;
  SymbolEntry : TSymbolEntry;
  bFinish : boolean;

  procedure StepUntilCommentToken(aNames : array of string);
  var
    i, j : Integer;
  begin
    while aIndex < (FWParser.Count - 1) do begin
      if Token[aIndex].Token = ttComment then begin

        for j := Low(aNames) to High(aNames) do
          if Pos(UpperCase(aNames[j]), UpperCase(Token[aIndex].Text)) = 1
          then begin
            aIndex := aIndex + 1;
            { ... aName <...> }
            Exit;
          end;
      end;
      Inc(aIndex);
    end;
    raise Exception.Create('Error: Unable to locate the end of $IFDEF or $IFNDEF directive.');
  end;

  procedure UndefineSymbol(aName : string);
  begin
    SymbolEntry := FindSymbolEntry(aName);
    if Assigned(SymbolEntry) then begin
      FItems.Remove(SymbolEntry);
      SymbolEntry.Free;
    end;
  end;

begin
  repeat
    { Check if end of file }
    Inc(aIndex);

    repeat
      if (Token[aIndex].Token = ttEof) or (aIndex >= (FWParser.Count - 1)) then begin
        if FWParserStack.Count > 0 then
          FWParserStack.Pop(FWParser, aIndex, FFileName);
      end;


      bFinish := True;
      if (Token[aIndex].Token = ttComment) and (Length(Token[aIndex].Text) > 1) and
         (Pos('$', Token[aIndex].Text) = 1)
      then begin
        {Symbol found}
        S := Copy(Token[aIndex].Text, 2, Length(Token[aIndex].Text) - 1);
        N := CutWord(S, ' ');
        V := Trim(S);
        if (UpperCase(N) = 'I') or (UpperCase(N) = 'INCLUDE') then
          IncludeFile(V, aIndex)
        else
        if UpperCase(N) = 'DEFINE' then AddSymbolEntry(V, '') else
        if UpperCase(N) = 'UNDEF' then UndefineSymbol(N) else
        if UpperCase(N) = 'IFDEF' then begin
          if Assigned(FindSymbolEntry(V)) then Break;
          StepUntilCommentToken(['$ELSE', '$ENDIF']);
          bFinish := False;
        end
        else
        if UpperCase(N) = 'IFNDEF' then begin
          if not Assigned(FindSymbolEntry(V)) then Break;
          StepUntilCommentToken(['$ELSE', '$ENDIF']);
          bFinish := False;
        end
        else
        if UpperCase(N) = 'ELSE' then StepUntilCommentToken(['$ENDIF']) else
        if UpperCase(N) = 'IFOPT' then else ;
      end;
    until bFinish;


  until (aIndex >= 0) and
        ( (aIndex >= (FWParser.Count - 1) ) or
          (Token[aIndex].Token <> ttComment) );
end;

procedure TWDelphiParser.ExpectToken(aIndex: Integer;
  aTokenType: TTokenType; aText, aErrorCode: String);
var
  S, sMsg : String;
  i, j, k : Integer;
begin
  if not IsToken(aIndex, aTokenType, aText) then begin
    aErrorCode := '- Error ' + aErrorCode;
    FErrors.Add(Format(aErrorCode + ' detected in file %s [%d, %d]',
                [FFileName, Token[aIndex].Row, Token[aIndex].Column]));
    FErrors.Add('');
    FErrors.Add(Format('Expected ''%s'', but ''%s'' found in the following:',
                [aText, Token[aIndex].Text]));
    S := '';
    i := aIndex;
    j := Token[i].Row;
    while (i > 0) and ((j = Token[i].Row) or (Abs(aIndex - i) < 10)) do begin
      if Token[i].Token <> ttComment then begin
        if S <> '' then S := ' ' + S;
        S := Token[i].Text + S;
      end;
      Dec(i);
    end;
    S := S + '<< Error!';
    FErrors.Add(S);
    FErrors.Add('');
    raise Exception.Create('The rest of the code ignored.');
  end;
end;

procedure TWDelphiParser.ExpectTokenBooleanValue(aIndex: Integer);
var
  S, sMsg : String;
  i, j, k : Integer;
begin
  if not (IsToken(aIndex, ttIdentifier, 'true') or
    IsToken(aIndex, ttIdentifier, 'false'))
  then begin
    (* If the value is not True or False, it can be a boolean constant declared
       somewhere. It's not actually error. So, just ignore it.
    FErrors.Add(Format('- Error 0FC4BCD8 detected in file %s [%d, %d]',
                [FFileName, Token[aIndex].Row, Token[aIndex].Column]));
    FErrors.Add('');
    FErrors.Add(Format('Expected Boolean, but ''%s'' found in the following:',
                [Token[aIndex].Text]));
    S := '';
    i := aIndex;
    j := Token[i].Row;
    while (i > 0) and ((j = Token[i].Row) or (Abs(aIndex - i) < 10)) do begin
      if Token[i].Token <> ttComment then begin
        if S <> '' then S := ' ' + S;
        S := Token[i].Text + S;
      end;
      Dec(i);
    end;
    S := S + '<< Error!';
    FErrors.Add(S);
    FErrors.Add('');
    raise Exception.Create('The rest of the code ignored.'); *)
  end;
end;

function TWDelphiParser.IsCommentTag(var aText : String; aTags : TStringList) : boolean;
var
  i : Integer;
begin
  Result := False;
  with aTags do
    if Count > 0 then
      for i := 0 to Count - 1 do
        if (Trim(Strings[i]) <> '') and
           { If aText begings from one of CommentTags words, accept it }
           (Pos(UpperCase(Strings[i]), UpperCase(aText)) = 1)
        then begin
          Result := True;
          aText := StringReplace(aText, Strings[i], '', []);
          Break;
        end;
end;

function TWDelphiParser.AcceptComment(var aText : String) : boolean;
var
  i : Integer;
begin
  { If CommentTag is empty, accept comment }
  Result := Trim(CommentTags.Text) = '';
  if not Result then
    with CommentTags do
      if Count > 0 then
        for i := 0 to Count - 1 do
          if (Trim(Strings[i]) <> '') and
             { If aText begings from one of CommentTags words, accept it }
             (Pos(UpperCase(Strings[i]), UpperCase(aText)) = 1)
          then begin
            Result := True;
            aText := StringReplace(aText, Strings[i], '', []);
            Break;
          end;
end;

function TWDelphiParser.IsCommentNewLineTag(var aText : String) : boolean;
var
  i : Integer;
begin
  Result := False;
  with CommentNewLineTags do
    if Count > 0 then
      for i := 0 to Count - 1 do
        if (Trim(Strings[i]) <> '') and
           { If aText ends in one of CommentTags words, accept it }
           (CompareText(Strings[i],
                        Copy(aText, Length(aText) - Length(Strings[i]) + 1,
                             Length(Strings[i]))) = 0)
        then begin
          Result := True;
          aText := StringReplace(aText, Strings[i], '', []);
          Break;
        end;
end;

procedure TWDelphiParser.AddComment(aText : String; var aComment : String; aAddBefore : boolean);
var
  i : Integer;
begin
  with TStringList.Create do
  try
    Text := aComment;
    //if Count = 0 then Add('');
    if aAddBefore then begin
      if (Count > 0) and (Strings[Count - 1] <> '') then
        Strings[0] := ' ' + Strings[0];
      if Trim(aText) <> '' then begin
        if Count > 0 then
          Strings[0] := Trim(aText) + Strings[0]
        else
          Add(Trim(aText));
      end
      else
        Insert(0, '');
    end
    else begin
      if (Count > 0) and (Strings[Count - 1] <> '') then
        Strings[Count - 1] := Strings[Count - 1] + ' ';
      if Trim(aText) <> '' then begin
        if Count > 0 then
          Strings[Count - 1] := Strings[Count - 1] + Trim(aText)
        else
          Add(Trim(aText));
      end
      else
        Add('');
    end;
    { Replace CommentNewLineTag if any }
    if CommentNewLineTags.Count > 0 then
      for i := 0 to CommentNewLineTags.Count - 1 do
        if Trim(CommentNewLineTags.Strings[i]) <> '' then
          Text := StringReplace(Text, CommentNewLineTags.Strings[i], #13, [rfReplaceAll]);
    if Count > 0 then
      for i := 0 to Count - 1 do
        Strings[i] := Trim(Strings[i]);
  finally
    aComment := Text;
    Free;
  end;
end;

procedure TWDelphiParser.LookBackwardForDescription(aIndex : Integer;
      var aSummary : String; var aDescription : String);
var
  CurrentSubType : TTokenSubType;
begin
  if not (poAcceptComments in Options) then Exit;
  if (aIndex <= 0) or (aIndex > FWParser.Count) then Exit;
  CurrentSubType := tsNone;
  Dec(aIndex);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -