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