📄 synhighlighterpython.pas
字号:
fCommentAttri := TSynHighlighterAttributes.Create(SYNS_AttrComment);
fCommentAttri.Foreground := clGray;
fCommentAttri.Style := [fsItalic];
AddAttribute(fCommentAttri);
fIdentifierAttri := TSynHighlighterAttributes.Create(SYNS_AttrIdentifier);
AddAttribute(fIdentifierAttri);
fKeyAttri := TSynHighlighterAttributes.Create(SYNS_AttrReservedWord);
fKeyAttri.Style := [fsBold];
AddAttribute(fKeyAttri);
fNonKeyAttri := TSynHighlighterAttributes.Create (SYNS_AttrNonReservedKeyword);
fNonKeyAttri.Foreground := clNavy;
fNonKeyAttri.Style := [fsBold];
AddAttribute (fNonKeyAttri);
fSystemAttri := TSynHighlighterAttributes.Create (SYNS_AttrSystem);
fSystemAttri.Style := [fsBold];
AddAttribute (fSystemAttri);
fNumberAttri := TSynHighlighterAttributes.Create(SYNS_AttrNumber);
fNumberAttri.Foreground := clBlue;
AddAttribute(fNumberAttri);
fHexAttri := TSynHighlighterAttributes.Create(SYNS_AttrHexadecimal);
fHexAttri.Foreground := clBlue;
AddAttribute(fHexAttri);
fOctalAttri := TSynHighlighterAttributes.Create(SYNS_AttrOctal);
fOctalAttri.Foreground := clBlue;
AddAttribute(fOctalAttri);
fFloatAttri := TSynHighlighterAttributes.Create(SYNS_AttrFloat);
fFloatAttri.Foreground := clBlue;
AddAttribute(fFloatAttri);
fSpaceAttri := TSynHighlighterAttributes.Create(SYNS_AttrSpace);
AddAttribute(fSpaceAttri);
fStringAttri := TSynHighlighterAttributes.Create(SYNS_AttrString);
fStringAttri.Foreground := clBlue;
AddAttribute(fStringAttri);
fDocStringAttri := TSynHighlighterAttributes.Create(SYNS_AttrDocumentation);
fDocStringAttri.Foreground := clTeal;
AddAttribute(fDocStringAttri);
fSymbolAttri := TSynHighlighterAttributes.Create(SYNS_AttrSymbol);
AddAttribute(fSymbolAttri);
fErrorAttri := TSynHighlighterAttributes.Create(SYNS_AttrSyntaxError);
fErrorAttri.Foreground := clRed;
AddAttribute(fErrorAttri);
SetAttributesOnChange(DefHighlightChange);
MakeMethodTables;
fDefaultFilter := SYNS_FilterPython;
end; { Create }
destructor TSynPythonSyn.Destroy;
begin
FKeywords.Free;
inherited;
end;
procedure TSynPythonSyn.SetLine(NewValue: string; LineNumber: Integer);
begin
fLine := PChar(NewValue);
Run := 0;
fLineNumber := LineNumber;
Next;
end; { SetLine }
procedure TSynPythonSyn.SymbolProc;
begin
inc(Run);
fTokenID := tkSymbol;
end;
procedure TSynPythonSyn.CRProc;
begin
fTokenID := tkSpace;
case FLine[Run + 1] of
#10: inc(Run, 2);
else
inc(Run);
end;
end;
procedure TSynPythonSyn.CommentProc;
begin
fTokenID := tkComment;
inc(Run);
while not (FLine[Run] in [#13, #10, #0]) do
inc(Run);
end;
procedure TSynPythonSyn.GreaterProc;
begin
case FLine[Run + 1] of
'=': begin
inc(Run, 2);
fTokenID := tkSymbol;
end;
else begin
inc(Run);
fTokenID := tkSymbol;
end;
end;
end;
procedure TSynPythonSyn.IdentProc;
begin
fTokenID := IdentKind((fLine + Run));
inc(Run, fStringLen);
end;
procedure TSynPythonSyn.LFProc;
begin
fTokenID := tkSpace;
inc(Run);
end;
procedure TSynPythonSyn.LowerProc;
begin
case FLine[Run + 1] of
'=': begin
inc(Run, 2);
fTokenID := tkSymbol;
end;
'>': begin
inc(Run, 2);
fTokenID := tkSymbol;
end
else begin
inc(Run);
fTokenID := tkSymbol;
end;
end;
end;
procedure TSynPythonSyn.NullProc;
begin
fTokenID := tkNull;
end;
procedure TSynPythonSyn.NumberProc;
const
INTCHARS = ['0' .. '9'];
HEXCHARS = ['a' .. 'f', 'A' .. 'F'] + INTCHARS;
OCTCHARS = ['0' .. '7'];
HEXINDICATOR = ['x', 'X'];
LONGINDICATOR = ['l', 'L'];
IMAGINARYINDICATOR = ['j', 'J'];
EXPONENTINDICATOR = ['e', 'E'];
EXPONENTSIGN = ['+', '-'];
DOT = '.';
ZERO = '0';
type
TNumberState =
(
nsStart,
nsDotFound,
nsFloatNeeded,
nsHex,
nsOct,
nsExpFound
);
var
temp: Char;
State: TNumberState;
function CheckSpecialCases: Boolean;
begin
case temp of
// Look for dot (.)
DOT: begin
// .45
if FLine[Run] in INTCHARS then begin
Inc (Run);
fTokenID := tkFloat;
State := nsDotFound;
// Non-number dot
end else begin
// Ellipsis
if (FLine[Run] = DOT) and (FLine[Run+1] = DOT) then
Inc (Run, 2);
fTokenID := tkSymbol;
Result := False;
Exit;
end; // if
end; // DOT
// Look for zero (0)
ZERO: begin
temp := FLine[Run];
// 0x123ABC
if temp in HEXINDICATOR then begin
Inc (Run);
fTokenID := tkHex;
State := nsHex;
// 0.45
end else if temp = DOT then begin
Inc (Run);
State := nsDotFound;
fTokenID := tkFloat;
end else if temp in INTCHARS then begin
Inc (Run);
// 0123 or 0123.45
if temp in OCTCHARS then begin
fTokenID := tkOct;
State := nsOct;
// 0899.45
end else begin
fTokenID := tkFloat;
State := nsFloatNeeded;
end; // if
end; // if
end; // ZERO
end; // case
Result := True;
end; // CheckSpecialCases
function HandleBadNumber: Boolean;
begin
Result := False;
fTokenID := tkUnknown;
// Ignore all tokens till end of "number"
while FLine[Run] in (IDENTIFIER_CHARS + ['.']) do
Inc (Run);
end; // HandleBadNumber
function HandleExponent: Boolean;
begin
State := nsExpFound;
fTokenID := tkFloat;
// Skip e[+/-]
if FLine[Run+1] in EXPONENTSIGN then
Inc (Run);
// Invalid token : 1.0e
if not (FLine[Run+1] in INTCHARS) then begin
Inc (Run);
Result := HandleBadNumber;
Exit;
end; // if
Result := True;
end; // HandleExponent
function HandleDot: Boolean;
begin
// Check for ellipsis
Result := (FLine[Run+1] <> DOT) or (FLine[Run+2] <> DOT);
if Result then begin
State := nsDotFound;
fTokenID := tkFloat;
end; // if
end; // HandleDot
function CheckStart: Boolean;
begin
// 1234
if temp in INTCHARS then begin
Result := True;
//123e4
end else if temp in EXPONENTINDICATOR then begin
Result := HandleExponent;
// 123.45j
end else if temp in IMAGINARYINDICATOR then begin
Inc (Run);
fTokenID := tkFloat;
Result := False;
// 123.45
end else if temp = DOT then begin
Result := HandleDot;
// Error!
end else if temp in IDENTIFIER_CHARS then begin
Result := HandleBadNumber;
// End of number
end else begin
Result := False;
end; // if
end; // CheckStart
function CheckDotFound: Boolean;
begin
// 1.0e4
if temp in EXPONENTINDICATOR then begin
Result := HandleExponent;
// 123.45
end else if temp in INTCHARS then begin
Result := True;
// 123.45j
end else if temp in IMAGINARYINDICATOR then begin
Inc (Run);
Result := False;
// 123.45.45: Error!
end else if temp = DOT then begin
Result := False;
if HandleDot then
HandleBadNumber;
// Error!
end else if temp in IDENTIFIER_CHARS then begin
Result := HandleBadNumber;
// End of number
end else begin
Result := False;
end; // if
end; // CheckDotFound
function CheckFloatNeeded: Boolean;
begin
// 091.0e4
if temp in EXPONENTINDICATOR then begin
Result := HandleExponent;
// 0912345
end else if temp in INTCHARS then begin
Result := True;
// 09123.45
end else if temp = DOT then begin
Result := HandleDot or HandleBadNumber; // Bad octal
// 09123.45j
end else if temp in IMAGINARYINDICATOR then begin
Inc (Run);
Result := False;
// End of number (error: Bad oct number) 0912345
end else begin
Result := HandleBadNumber;
end;
end; // CheckFloatNeeded
function CheckHex: Boolean;
begin
// 0x123ABC
if temp in HEXCHARS then begin
Result := True;
// 0x123ABCL
end else if temp in LONGINDICATOR then begin
Inc (Run);
Result := False;
// 0x123.45: Error!
end else if temp = DOT then begin
Result := False;
if HandleDot then
HandleBadNumber;
// Error!
end else if temp in IDENTIFIER_CHARS then begin
Result := HandleBadNumber;
// End of number
end else begin
Result := False;
end; // if
end; // CheckHex
function CheckOct: Boolean;
begin
// 012345
if temp in INTCHARS then begin
if not (temp in OCTCHARS) then begin
State := nsFloatNeeded;
fTokenID := tkFloat;
end; // if
Result := True;
// 012345L
end else if temp in LONGINDICATOR then begin
Inc (Run);
Result := False;
// 0123e4
end else if temp in EXPONENTINDICATOR then begin
Result := HandleExponent;
// 0123j
end else if temp in IMAGINARYINDICATOR then begin
Inc (Run);
fTokenID := tkFloat;
Result := False;
// 0123.45
end else if temp = DOT then begin
Result := HandleDot;
// Error!
end else if temp in IDENTIFIER_CHARS then begin
Result := HandleBadNumber;
// End of number
end else begin
Result := False;
end; // if
end; // CheckOct
function CheckExpFound: Boolean;
begin
// 1e+123
if temp in INTCHARS then begin
Result := True;
// 1e+123j
end else if temp in IMAGINARYINDICATOR then begin
Inc (Run);
Result := False;
// 1e4.5: Error!
end else if temp = DOT then begin
Result := False;
if HandleDot then
HandleBadNumber;
// Error!
end else if temp in IDENTIFIER_CHARS then begin
Result := HandleBadNumber;
// End of number
end else begin
Result := False;
end; // if
end; // CheckExpFound
begin
State := nsStart;
fTokenID := tkNumber;
temp := FLine[Run];
Inc (Run);
// Special cases
if not CheckSpecialCases then
Exit;
// Use a state machine to parse numbers
while True do begin
temp := FLine[Run];
case State of
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -