Einzelnen Beitrag anzeigen

Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: SynHighlighter erweitern

  Alt 7. Sep 2012, 15:51
Also ich kenne den SynEdit schon recht lange und recht gut. Historisch war es so, dass zuerst die ANSI-Version da war und dort waren die Highlighter hartcodiert. Seit der Unicode-Version wurden die ein "bisschen" flexibler. Da gibts jetzt auch einen UniSynHighlighter, der variabel anpassbar ist zur Designtime über Properties. Aber der ist nicht 100% auf die Eigenheiten der einzelnen Sprachen anpassbar, sodass manche Feinheiten unter den Tisch fallen. Darum immernoch die spezialisieren Highlighter.

Ich denke, die brauchten einen ganz simplen Hash-Algo, der kurze INT-Hashes liefert die man als Index in einem Array missbrauchen kann. Der jetzige liefert aber nur eine Streubreite von 0..136, was bei knapp 100 Keywords nicht die Wucht ist.

Wahrscheinlich wäre es das beste, die ganze Sache mal komplett umzustricken. Wird aber wohl erst nächste Woche. Vielleicht hat ja einer von euch am Wochenende etwas Langeweile?

@shmia: Parallel zu Deiner Antwort kam ich fast zum selben Ergebnis. Hier der Source zu meinem Hash-Pascalcode-Generator:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
type
  KWRec = record
    Keyword: String;
    Hash: Integer;
  end;
  KWList = array of KWRec;

var
  I, J, iNumWords, iMaxHash: Integer;
  S, S2: String;
  C: Char;
  L: KWList;
  Indices: array of Integer;
  SL: TStringList;

begin
  I:= 0;
  iNumWords:= 0;
  iMaxHash:= 0;
  Memo1.Lines.BeginUpdate;
  try
    while I < Memo1.Lines.Count do begin
      S:= Memo1.Lines[I];
      S2:= '';
      for J:= 1 to Length(S) do begin
        C:= S[J];
        if IsIdentChar(C) then S2:= S2 + C;
      end;
      if Trim(S2) = 'then Memo1.Lines.Delete(I) else begin
        Memo1.Lines[I]:= S2;
        Inc(I);
        Inc(iNumWords);
      end;
    end;
    SL:= TStringList.Create;
    try
      SL.Assign(Memo1.Lines);
      SL.Sort;
      Memo1.Lines.Assign(SL);
    finally
      SL.Free;
    end;
    SetLength(L, iNumWords);
    for I:= Low(L) to High(L) do begin
      S:= Memo1.Lines[I];
      L[I].Keyword:= S;
      L[I].Hash:= HashKey(PChar(S));
      iMaxHash:= Max(L[I].Hash, iMaxHash);
    end;
    SetLength(Indices, iMaxHash + 1);
    for I:= Low(Indices) to High(Indices) do begin
      Indices[I]:= -1;
    end;
    Memo2.Lines.BeginUpdate;
    try
    Memo2.Lines.Add(' KeyWords: array[0..' + IntToStr(iNumWords - 1) + '] of UnicodeString = (');
      for I:= Low(L) to High(L) do begin
        Indices[L[I].Hash]:= I;
        S:= ' ''' + L[I].Keyword + '''';
        S:= S + StringOfChar(' ', Max(25 - Length(S), 0));
        S:= S + '{ Index: ' + IntToStr(I);
        S:= S + StringOfChar(' ', Max(35 - Length(S), 0));
        S:= S + ' | Hash: ' + IntToStr(L[I].Hash);
        S:= S + StringOfChar(' ', Max(49 - Length(S), 0));
        S:= S + '}';
        if I < High(L) then S:= S + ',';
        Memo2.Lines.Add(S);
      end;
      Memo2.Lines.Add(' );');
      Memo2.Lines.Add('');
      Memo2.Lines.Add(' KeyIndices: array[0..' + IntToStr(iMaxHash) + '] of Integer = (');
      for I:= Low(Indices) to High(Indices) do begin
        S:= ' ' + IntToStr(Indices[I]);
        S:= S + StringOfChar(' ', Max(8 - Length(S), 0));
        S:= S + ' { Index: ' + IntToStr(I) + ' }';
        if I < High(Indices) then S:= S + ',';
        Memo2.Lines.Add(S);
      end;
      Memo2.Lines.Add(' );');
    finally
      Memo2.Lines.EndUpdate;
    end;
  finally
    Memo1.Lines.EndUpdate;
  end;
end;
Schönes WE
Cody

Geändert von Codehunter ( 8. Sep 2012 um 09:13 Uhr)
  Mit Zitat antworten Zitat