mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-10-25 12:41:31 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			1234 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			1234 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| {-------------------------------------------------------------------------------
 | |
| The contents of this file are subject to the Mozilla Public License
 | |
| Version 1.1 (the "License"); you may not use this file except in compliance
 | |
| with the License. You may obtain a copy of the License at
 | |
| http://www.mozilla.org/MPL/
 | |
| 
 | |
| Software distributed under the License is distributed on an "AS IS" basis,
 | |
| WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 | |
| the specific language governing rights and limitations under the License.
 | |
| 
 | |
| The Original Code is: SynHighlighterPython.pas, released 2000-06-23.
 | |
| The Original Code is based on the odPySyn.pas file from the
 | |
| mwEdit component suite by Martin Waldenburg and other developers, the Initial
 | |
| Author of this file is Olivier Deckmyn.
 | |
| Portions created by M.Utku Karatas and Dennis Chuah.
 | |
| All Rights Reserved.
 | |
| 
 | |
| Contributors to the SynEdit and mwEdit projects are listed in the
 | |
| Contributors.txt file.
 | |
| 
 | |
| Alternatively, the contents of this file may be used under the terms of the
 | |
| GNU General Public License Version 2 or later (the "GPL"), in which case
 | |
| the provisions of the GPL are applicable instead of those above.
 | |
| If you wish to allow use of your version of this file only under the terms
 | |
| of the GPL and not to allow others to use your version of this file
 | |
| under the MPL, indicate your decision by deleting the provisions above and
 | |
| replace them with the notice and other provisions required by the GPL.
 | |
| If you do not delete the provisions above, a recipient may use your version
 | |
| of this file under either the MPL or the GPL.
 | |
| 
 | |
| $Id$
 | |
| 
 | |
| You may retrieve the latest version of this file at the SynEdit home page,
 | |
| located at http://SynEdit.SourceForge.net
 | |
| 
 | |
| Known Issues:
 | |
| -------------------------------------------------------------------------------}
 | |
| {
 | |
| @abstract(A Python language highlighter for SynEdit)
 | |
| @author(Olivier Deckmyn, converted to SynEdit by David Muir <dhmn@dmsoftware.co.uk>)
 | |
| @created(unknown, converted to SynEdit on 2000-06-23)
 | |
| @lastmod(2003-02-13)
 | |
| The SynHighlighterPython implements a highlighter for Python for the SynEdit projects.
 | |
| }
 | |
| unit SynHighlighterPython;
 | |
| 
 | |
| {$I SynEdit.inc}
 | |
| 
 | |
| interface
 | |
| 
 | |
| uses
 | |
|   IniFiles, //THashedStringList
 | |
|   LCLIntf, LCLType,
 | |
|   SynEditHighlighter, SynEditTypes,
 | |
|   Graphics, SysUtils, Classes;
 | |
| 
 | |
| const
 | |
|   ALPHA_CHARS = ['_', 'a'..'z', 'A'..'Z'];
 | |
|   IDENTIFIER_CHARS = ['0'..'9'] + ALPHA_CHARS;
 | |
| 
 | |
| type
 | |
|   TtkTokenKind = (tkComment, tkIdentifier, tkKey, tkNull, tkNumber, tkSpace,
 | |
|     tkString, tkSymbol, tkNonKeyword, tkTripleQuotedString,
 | |
|     tkSystemDefined, tkHex, tkOct, tkFloat, tkUnknown);
 | |
| 
 | |
|   TRangeState = (rsANil, rsComment, rsUnKnown, rsMultilineString, rsMultilineString2,
 | |
|                  rsMultilineString3 //this is to indicate if a string is made multiline by backslash char at line end (as in C++ highlighter)
 | |
|                 );
 | |
| 
 | |
|   TProcTableProc = procedure of object;
 | |
| 
 | |
| type
 | |
|   TSynPythonSyn = class(TSynCustomHighLighter)
 | |
|   private
 | |
|     fStringStarter: char;  // used only for rsMultilineString3 stuff
 | |
|     fRange: TRangeState;
 | |
|     fLine: PChar;
 | |
|     fLineNumber: Integer;
 | |
|     fProcTable: array[#0..#255] of TProcTableProc;
 | |
|     fToIdent: PChar;
 | |
|     fTokenPos: Integer;
 | |
|     FTokenID: TtkTokenKind;
 | |
|     FKeywords: TStringList;
 | |
| 
 | |
|     fStringAttri: TSynHighlighterAttributes;
 | |
|     fDocStringAttri: TSynHighlighterAttributes;
 | |
|     fNumberAttri: TSynHighlighterAttributes;
 | |
|     fHexAttri: TSynHighlighterAttributes;
 | |
|     fOctalAttri: TSynHighlighterAttributes;
 | |
|     fFloatAttri: TSynHighlighterAttributes;
 | |
|     fKeyAttri: TSynHighlighterAttributes;
 | |
|     fNonKeyAttri: TSynHighlighterAttributes;
 | |
|     fSystemAttri: TSynHighlighterAttributes;
 | |
|     fSymbolAttri: TSynHighlighterAttributes;
 | |
|     fCommentAttri: TSynHighlighterAttributes;
 | |
|     fIdentifierAttri: TSynHighlighterAttributes;
 | |
|     fSpaceAttri: TSynHighlighterAttributes;
 | |
|     fErrorAttri: TSynHighlighterAttributes;
 | |
| 
 | |
|     procedure SymbolProc;
 | |
|     procedure CRProc;
 | |
|     procedure CommentProc;
 | |
|     procedure GreaterProc;
 | |
|     procedure IdentProc;
 | |
|     procedure LFProc;
 | |
|     procedure LowerProc;
 | |
|     procedure NullProc;
 | |
|     procedure NumberProc;
 | |
|     procedure SpaceProc;
 | |
|     procedure PreStringProc;
 | |
|     procedure UnicodeStringProc;
 | |
|     procedure StringProc;
 | |
|     procedure String2Proc;
 | |
|     procedure StringEndProc(EndChar:char);
 | |
|     procedure UnknownProc;
 | |
|     procedure MakeMethodTables;
 | |
| 
 | |
|   protected
 | |
|     Run: LongInt;
 | |
|     fStringLen: Integer;
 | |
| 
 | |
|     function GetIdentChars: TSynIdentChars; override;
 | |
|     function GetSampleSource: string; override;
 | |
|     function IdentKind(MayBe: PChar): TtkTokenKind; virtual;
 | |
|     function GetKeywordIdentifiers: TStringList; virtual;
 | |
|     property Keywords: TStringlist read FKeywords;
 | |
|     property TokenID: TtkTokenKind read FTokenID;
 | |
| 
 | |
|   public
 | |
|     class function GetLanguageName: string; override;
 | |
|   public
 | |
|     constructor Create(AOwner: TComponent); override;
 | |
|     destructor Destroy; override;
 | |
|     function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
 | |
|       override;
 | |
|     function GetEol: Boolean; override;
 | |
|     function GetRange: Pointer; override;
 | |
|     function GetTokenID: TtkTokenKind;
 | |
|     procedure SetLine(const NewValue: string;
 | |
|                       LineNumber: Integer); override;
 | |
|     function GetToken: string; override;
 | |
|     function GetTokenAttribute: TSynHighlighterAttributes; override;
 | |
|     function GetTokenKind: integer; override;
 | |
|     function GetTokenPos: Integer; override;
 | |
|     procedure Next; override;
 | |
|     property IdentChars;
 | |
|     procedure SetRange(Value: Pointer); override;
 | |
|     procedure ResetRange; override;
 | |
|     procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
 | |
|   published
 | |
|     property CommentAttri: TSynHighlighterAttributes read fCommentAttri
 | |
|     write fCommentAttri;
 | |
|     property IdentifierAttri: TSynHighlighterAttributes read fIdentifierAttri
 | |
|     write fIdentifierAttri;
 | |
|     property KeyAttri: TSynHighlighterAttributes read fKeyAttri write fKeyAttri;
 | |
|     property NonKeyAttri: TSynHighlighterAttributes read fNonKeyAttri
 | |
|       write fNonKeyAttri;
 | |
|     property SystemAttri: TSynHighlighterAttributes read fSystemAttri
 | |
|       write fSystemAttri;
 | |
|     property NumberAttri: TSynHighlighterAttributes read fNumberAttri
 | |
|     write fNumberAttri;
 | |
|     property HexAttri: TSynHighlighterAttributes read fHexAttri
 | |
|       write fHexAttri;
 | |
|     property OctalAttri: TSynHighlighterAttributes read fOctalAttri
 | |
|       write fOctalAttri;
 | |
|     property FloatAttri: TSynHighlighterAttributes read fFloatAttri
 | |
|       write fFloatAttri;
 | |
|     property SpaceAttri: TSynHighlighterAttributes read fSpaceAttri
 | |
|     write fSpaceAttri;
 | |
|     property StringAttri: TSynHighlighterAttributes read fStringAttri
 | |
|     write fStringAttri;
 | |
|     property DocStringAttri: TSynHighlighterAttributes read fDocStringAttri
 | |
|       write fDocStringAttri;
 | |
|     property SymbolAttri: TSynHighlighterAttributes read fSymbolAttri
 | |
|     write fSymbolAttri;
 | |
|     property ErrorAttri: TSynHighlighterAttributes read fErrorAttri
 | |
|       write fErrorAttri;
 | |
|   end;
 | |
| 
 | |
| implementation
 | |
| 
 | |
| uses
 | |
|   SynEditStrConst;
 | |
| 
 | |
| var
 | |
|   GlobalKeywords: TStringList;
 | |
| 
 | |
| function TSynPythonSyn.GetKeywordIdentifiers: TStringList;
 | |
| const
 | |
|   // No need to localise keywords!
 | |
| 
 | |
|   // List of keywords
 | |
|   KEYWORDCOUNT = 29;
 | |
|   KEYWORDSIdents: array [1..KEYWORDCOUNT] of string =
 | |
|     (
 | |
|     'and',
 | |
|     'assert',
 | |
|     'break',
 | |
|     'class',
 | |
|     'continue',
 | |
|     'def',
 | |
|     'del',
 | |
|     'elif',
 | |
|     'else',
 | |
|     'except',
 | |
|     'exec',
 | |
|     'finally',
 | |
|     'for',
 | |
|     'from',
 | |
|     'global',
 | |
|     'if',
 | |
|     'import',
 | |
|     'in',
 | |
|     'is',
 | |
|     'lambda',
 | |
|     'not',
 | |
|     'or',
 | |
|     'pass',
 | |
|     'print',
 | |
|     'raise',
 | |
|     'return',
 | |
|     'try',
 | |
|     'while',
 | |
|     'yield'
 | |
|     );
 | |
| 
 | |
|   // List of non-keyword identifiers
 | |
|   NONKEYWORDCOUNT = 66;
 | |
|   NONKEYWORDS: array [1..NONKEYWORDCOUNT] of string =
 | |
|     (
 | |
|     '__future__',
 | |
|     '__import__',
 | |
|     'abs',
 | |
|     'apply',
 | |
|     'as',
 | |
|     'buffer',
 | |
|     'callable',
 | |
|     'chr',
 | |
|     'cmp',
 | |
|     'coerce',
 | |
|     'compile',
 | |
|     'complex',
 | |
|     'delattr',
 | |
|     'dict',
 | |
|     'dir',
 | |
|     'divmod',
 | |
|     'eval',
 | |
|     'execfile',
 | |
|     'False',
 | |
|     'file',
 | |
|     'filter',
 | |
|     'float',
 | |
|     'getattr',
 | |
|     'globals',
 | |
|     'hasattr',
 | |
|     'hash',
 | |
|     'help',
 | |
|     'hex',
 | |
|     'id',
 | |
|     'input',
 | |
|     'int',
 | |
|     'intern',
 | |
|     'isinstance',
 | |
|     'issubclass',
 | |
|     'iter',
 | |
|     'len',
 | |
|     'list',
 | |
|     'locals',
 | |
|     'long',
 | |
|     'None',
 | |
|     'NotImplemented',
 | |
|     'map',
 | |
|     'max',
 | |
|     'min',
 | |
|     'oct',
 | |
|     'open',
 | |
|     'ord',
 | |
|     'pow',
 | |
|     'range',
 | |
|     'raw_input',
 | |
|     'reduce',
 | |
|     'reload',
 | |
|     'repr',
 | |
|     'round',
 | |
|     'self',
 | |
|     'setattr',
 | |
|     'slice',
 | |
|     'str',
 | |
|     'True',
 | |
|     'tuple',
 | |
|     'type',
 | |
|     'unichr',
 | |
|     'unicode',
 | |
|     'vars',
 | |
|     'xrange',
 | |
|     'zip'
 | |
|     );
 | |
| var
 | |
|   f: Integer;
 | |
| begin
 | |
|   if not Assigned (GlobalKeywords) then begin
 | |
|     // Create the string list of keywords - only once
 | |
|     GlobalKeywords := TStringList.Create;
 | |
| 
 | |
|     for f := 1 to KEYWORDCOUNT do
 | |
|       GlobalKeywords.AddObject (KEYWORDSIdents[f],
 | |
|         TObject(Ord(tkKey)));
 | |
|     for f := 1 to NONKEYWORDCOUNT do
 | |
|       GlobalKeywords.AddObject (NONKEYWORDS[f],
 | |
|         TObject(Ord(tkNonKeyword)));
 | |
|   end; // if
 | |
|   Result := GlobalKeywords;
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.IdentKind(MayBe: PChar): TtkTokenKind;
 | |
| var
 | |
|   index: Integer;
 | |
|   temp: PChar;
 | |
|   s: string;
 | |
| 
 | |
| begin
 | |
|   // Extract the identifier out - it is assumed to terminate in a
 | |
|   //   non-alphanumeric character
 | |
|   fToIdent := MayBe;
 | |
|   temp := MayBe;
 | |
|   while temp^ in IDENTIFIER_CHARS do
 | |
|     Inc (temp);
 | |
|   fStringLen := temp - fToIdent;
 | |
| 
 | |
|   // Check to see if it is a keyword
 | |
|   SetString (s, fToIdent, fStringLen);
 | |
|   index := FKeywords.IndexOf (s);
 | |
| 
 | |
|   if index <> -1 then
 | |
|     Result := TtkTokenKind (PtrInt(FKeywords.Objects[index]))
 | |
| 
 | |
|   // Check if it is a system identifier (__*__)
 | |
|   else if (fStringLen >= 5) and
 | |
|      (MayBe[0] = '_') and (MayBe[1] = '_') and (MayBe[2] <> '_') and
 | |
|      (MayBe[fStringLen-1] = '_') and (MayBe[fStringLen-2] = '_') and
 | |
|      (MayBe[fStringLen-3] <> '_') then
 | |
|     Result := tkSystemDefined
 | |
| 
 | |
|   // Else, hey, it is an ordinary run-of-the-mill identifier!
 | |
|   else
 | |
|     Result := tkIdentifier;
 | |
| end;
 | |
|   
 | |
| procedure TSynPythonSyn.MakeMethodTables;
 | |
| var
 | |
|   I: Char;
 | |
| begin
 | |
|   for I := #0 to #255 do
 | |
|     case I of
 | |
|       '&', '}', '{', ':', ',', ']', '[', '*', '`',
 | |
|       '^', ')', '(', ';', '/', '=', '-', '+', '!', '\',
 | |
|       '%', '|', '~' :
 | |
|         fProcTable[I] := @SymbolProc;
 | |
|       #13: fProcTable[I] := @CRProc;
 | |
|       '#': fProcTable[I] := @CommentProc;
 | |
|       '>': fProcTable[I] := @GreaterProc;
 | |
|       'A'..'Q', 'S', 'T', 'V'..'Z', 'a'..'q', 's', 't', 'v'..'z', '_': fProcTable[I] := @IdentProc;
 | |
|       #10: fProcTable[I] := @LFProc;
 | |
|       '<': fProcTable[I] := @LowerProc;
 | |
|       #0: fProcTable[I] := @NullProc;
 | |
|       '.', '0'..'9': fProcTable[I] := @NumberProc;
 | |
|       #1..#9, #11, #12, #14..#32:
 | |
|         fProcTable[I] := @SpaceProc;
 | |
|       'r', 'R': fProcTable[I] := @PreStringProc;
 | |
|       'u', 'U': fProcTable[I] := @UnicodeStringProc;
 | |
|       '''': fProcTable[I] := @StringProc;
 | |
|       '"': fProcTable[I] := @String2Proc;
 | |
|     else
 | |
|       fProcTable[I] := @UnknownProc;
 | |
|     end;
 | |
| end;
 | |
| 
 | |
| constructor TSynPythonSyn.Create(AOwner: TComponent);
 | |
| begin
 | |
|   inherited Create(AOwner);
 | |
|   
 | |
|   FKeywords := THashedStringList.Create;
 | |
|   FKeywords.CaseSensitive := True;
 | |
|   FKeywords.Duplicates := dupError;
 | |
|   FKeywords.Assign (GetKeywordIdentifiers);
 | |
| 
 | |
|   fRange := rsUnknown;
 | |
|   fCommentAttri := TSynHighlighterAttributes.Create(@SYNS_AttrComment, SYNS_XML_AttrComment);
 | |
|   fCommentAttri.Foreground := clGray;
 | |
|   fCommentAttri.Style := [fsItalic];
 | |
|   AddAttribute(fCommentAttri);
 | |
|   fIdentifierAttri := TSynHighlighterAttributes.Create(@SYNS_AttrIdentifier, SYNS_XML_AttrIdentifier);
 | |
|   AddAttribute(fIdentifierAttri);
 | |
|   fKeyAttri := TSynHighlighterAttributes.Create(@SYNS_AttrReservedWord, SYNS_XML_AttrReservedWord);
 | |
|   fKeyAttri.Style := [fsBold];
 | |
|   AddAttribute(fKeyAttri);
 | |
|   fNonKeyAttri := TSynHighlighterAttributes.Create(@SYNS_AttrNonReservedKeyword, SYNS_XML_AttrNonReservedKeyword);
 | |
|   fNonKeyAttri.Foreground := clNavy;
 | |
|   fNonKeyAttri.Style := [fsBold];
 | |
|   AddAttribute (fNonKeyAttri);
 | |
|   fSystemAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSystem, SYNS_XML_AttrSystem);
 | |
|   fSystemAttri.Style := [fsBold];
 | |
|   AddAttribute (fSystemAttri);
 | |
|   fNumberAttri := TSynHighlighterAttributes.Create(@SYNS_AttrNumber, SYNS_XML_AttrNumber);
 | |
|   fNumberAttri.Foreground := clBlue;
 | |
|   AddAttribute(fNumberAttri);
 | |
|   fHexAttri := TSynHighlighterAttributes.Create(@SYNS_AttrHexadecimal, SYNS_XML_AttrHexadecimal);
 | |
|   fHexAttri.Foreground := clBlue;
 | |
|   AddAttribute(fHexAttri);
 | |
|   fOctalAttri := TSynHighlighterAttributes.Create(@SYNS_AttrOctal, SYNS_XML_AttrOctal);
 | |
|   fOctalAttri.Foreground := clBlue;
 | |
|   AddAttribute(fOctalAttri);
 | |
|   fFloatAttri := TSynHighlighterAttributes.Create(@SYNS_AttrFloat, SYNS_XML_AttrFloat);
 | |
|   fFloatAttri.Foreground := clBlue;
 | |
|   AddAttribute(fFloatAttri);
 | |
|   fSpaceAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSpace, SYNS_XML_AttrSpace);
 | |
|   AddAttribute(fSpaceAttri);
 | |
|   fStringAttri := TSynHighlighterAttributes.Create(@SYNS_AttrString, SYNS_XML_AttrString);
 | |
|   fStringAttri.Foreground := clBlue;
 | |
|   AddAttribute(fStringAttri);
 | |
|   fDocStringAttri := TSynHighlighterAttributes.Create(@SYNS_AttrDocumentation, SYNS_XML_AttrDocumentation);
 | |
|   fDocStringAttri.Foreground := clTeal;
 | |
|   AddAttribute(fDocStringAttri);
 | |
|   fSymbolAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSymbol, SYNS_XML_AttrSymbol);
 | |
|   AddAttribute(fSymbolAttri);
 | |
|   fErrorAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSyntaxError, SYNS_XML_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(const NewValue: string;
 | |
|   LineNumber: Integer);
 | |
| begin
 | |
|   inherited;
 | |
|   fLine := PChar(NewValue);
 | |
|   Run := 0;
 | |
|   fLineNumber := LineNumber;
 | |
|   Next;
 | |
| end; { SetLine }
 | |
| 
 | |
| procedure TSynPythonSyn.GetTokenEx(out TokenStart: PChar;
 | |
|   out TokenLength: integer);
 | |
| begin
 | |
|   TokenLength:=Run-fTokenPos;
 | |
|   TokenStart:=FLine + fTokenPos;
 | |
| end;
 | |
| 
 | |
| 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
 | |
|       nsStart:
 | |
|         if not CheckStart then Exit;
 | |
|       nsDotFound:
 | |
|         if not CheckDotFound then Exit;
 | |
|       nsFloatNeeded:
 | |
|         if not CheckFloatNeeded then Exit;
 | |
|       nsHex:
 | |
|         if not CheckHex then Exit;
 | |
|       nsOct:
 | |
|         if not CheckOct then Exit;
 | |
|       nsExpFound:
 | |
|         if not CheckExpFound then Exit;
 | |
|     end; // case
 | |
| 
 | |
|     Inc (Run);
 | |
|   end; // while
 | |
| 
 | |
| {
 | |
| begin
 | |
|   while FLine[Run] in ['0'..'9', '.', 'e', 'E'] do begin
 | |
|     case FLine[Run] of
 | |
|       '.':
 | |
|         if FLine[Run + 1] = '.' then break;
 | |
|     end;
 | |
|     inc(Run);
 | |
|   end;
 | |
| }
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.SpaceProc;
 | |
| begin
 | |
|   inc(Run);
 | |
|   fTokenID := tkSpace;
 | |
|   while FLine[Run] in [#1..#9, #11, #12, #14..#32] do
 | |
|     inc(Run);
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.String2Proc;
 | |
| var fBackslashCount:integer;
 | |
| begin
 | |
|   fTokenID := tkString;
 | |
|   if (FLine[Run + 1] = '"') and (FLine[Run + 2] = '"') then begin
 | |
|     fTokenID := tkTripleQuotedString;
 | |
|     inc(Run, 3);
 | |
| 
 | |
|     fRange:=rsMultilineString2;
 | |
|     while fLine[Run] <> #0 do begin
 | |
|       case fLine[Run] of
 | |
| 
 | |
|         '\':begin
 | |
|                { If we're looking at a backslash, and the following character is an
 | |
|                end quote, and it's preceeded by an odd number of backslashes, then
 | |
|                it shouldn't mark the end of the string.  If it's preceeded by an
 | |
|                even number, then it should. !!!THIS RULE DOESNT APPLY IN RAW STRINGS}
 | |
|                if FLine[Run + 1] = '"' then
 | |
|                  begin
 | |
|                    fBackslashCount := 1;
 | |
| 
 | |
|                    while ((Run > fBackslashCount) and (FLine[Run - fBackslashCount] = '\')) do
 | |
|                      fBackslashCount := fBackslashCount + 1;
 | |
| 
 | |
|                    if (fBackslashCount mod 2 = 1) then inc(Run)
 | |
|                end;
 | |
|                inc(Run);
 | |
|             end;// '\':
 | |
| 
 | |
|         '"':
 | |
|           if (fLine[Run + 1] = '"') and (fLine[Run + 2] = '"') then begin
 | |
|             fRange := rsUnKnown;
 | |
|             inc(Run, 3);
 | |
|             EXIT;
 | |
|           end else
 | |
|             inc(Run);
 | |
|         #10:EXIT;
 | |
|         #13:EXIT;
 | |
|         else
 | |
|           inc(Run);
 | |
|       end;
 | |
|     end;
 | |
|   end
 | |
|       else //if short string
 | |
|   repeat
 | |
|     case FLine[Run] of
 | |
|       #0, #10, #13 : begin
 | |
|         if FLine[Run-1] = '\' then begin
 | |
|           fStringStarter := '"';
 | |
|           fRange := rsMultilineString3;
 | |
|         end;
 | |
|         BREAK;
 | |
|         end;
 | |
|       {The same backslash stuff above...}
 | |
|       '\':begin
 | |
|              if FLine[Run + 1] = '"' then
 | |
|                begin
 | |
|                  fBackslashCount := 1;
 | |
| 
 | |
|                  while ((Run > fBackslashCount) and (FLine[Run - fBackslashCount] = '\')) do
 | |
|                    fBackslashCount := fBackslashCount + 1;
 | |
| 
 | |
|                  if (fBackslashCount mod 2 = 1) then inc(Run)
 | |
|              end;
 | |
|              inc(Run);
 | |
|           end;// '\':
 | |
| 
 | |
|       else inc(Run);
 | |
|     end; //case
 | |
|   until (FLine[Run] = '"');
 | |
|   if FLine[Run] <> #0 then inc(Run);
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.PreStringProc;
 | |
| var
 | |
|   temp: Char;
 | |
| 
 | |
| begin
 | |
|   // Handle python raw strings
 | |
|   // r""
 | |
|   temp := FLine[Run + 1];
 | |
|   if temp = '''' then begin
 | |
|     Inc (Run);
 | |
|     StringProc;
 | |
|   end else if temp = '"' then begin
 | |
|     Inc (Run);
 | |
|     String2Proc;
 | |
|   end else begin
 | |
|     // If not followed by quote char, must be ident
 | |
|     IdentProc;
 | |
|   end; // if
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.UnicodeStringProc;
 | |
| begin
 | |
|   // Handle python raw and unicode strings
 | |
|   // Valid syntax: u"", or ur""
 | |
|   if (FLine[Run + 1] in ['r', 'R']) and (FLine[Run + 2] in ['''', '"']) then
 | |
|     // for ur, Remove the "u" and...
 | |
|     Inc (Run);
 | |
|   // delegate to raw strings
 | |
|   PreStringProc;
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.StringProc;
 | |
| var fBackslashCount:integer;
 | |
| begin
 | |
|   fTokenID := tkString;
 | |
|   if (FLine[Run + 1] = #39) and (FLine[Run + 2] = #39) then begin
 | |
|     fTokenID := tkTripleQuotedString;
 | |
|     inc(Run, 3);
 | |
| 
 | |
|     fRange:=rsMultilineString;
 | |
|     while fLine[Run] <> #0 do begin
 | |
|       case fLine[Run] of
 | |
| 
 | |
|         '\': begin
 | |
|              { If we're looking at a backslash, and the following character is an
 | |
|              end quote, and it's preceeded by an odd number of backslashes, then
 | |
|              it shouldn't mark the end of the string.  If it's preceeded by an
 | |
|              even number, then it should. !!!THIS RULE DOESNT APPLY IN RAW STRINGS}
 | |
|               if FLine[Run + 1] = #39 then
 | |
|                 begin
 | |
|                   fBackslashCount := 1;
 | |
| 
 | |
|                   while ((Run > fBackslashCount) and (FLine[Run - fBackslashCount] = '\')) do
 | |
|                     fBackslashCount := fBackslashCount + 1;
 | |
| 
 | |
|                   if (fBackslashCount mod 2 = 1) then inc(Run)
 | |
|               end;
 | |
|               inc(Run);
 | |
|             end;// '\':
 | |
| 
 | |
|         #39:
 | |
|           if (fLine[Run + 1] = #39) and (fLine[Run + 2] = #39) then begin
 | |
|             fRange := rsUnKnown;
 | |
|             inc(Run, 3);
 | |
|             EXIT;
 | |
|           end else
 | |
|             inc(Run);
 | |
|         #10: EXIT;
 | |
|         #13: EXIT;
 | |
|         else
 | |
|           inc(Run);
 | |
|       end;
 | |
|     end;
 | |
|   end
 | |
|       else //if short string
 | |
|   repeat
 | |
|     case FLine[Run] of
 | |
|       #0, #10, #13 : begin
 | |
|         if FLine[Run-1] = '\' then begin
 | |
|           fStringStarter := #39;
 | |
|           fRange := rsMultilineString3;
 | |
|         end;
 | |
|         BREAK;
 | |
|         end;
 | |
| 
 | |
|       {The same backslash stuff above...}
 | |
|       '\':begin
 | |
|              if FLine[Run + 1] = #39 then
 | |
|                begin
 | |
|                  fBackslashCount := 1;
 | |
| 
 | |
|                  while ((Run > fBackslashCount) and (FLine[Run - fBackslashCount] = '\')) do
 | |
|                    fBackslashCount := fBackslashCount + 1;
 | |
| 
 | |
|                  if (fBackslashCount mod 2 = 1) then inc(Run)
 | |
|              end;
 | |
|              inc(Run);
 | |
|           end;// '\':
 | |
| 
 | |
|       else inc(Run);
 | |
|     end; //case
 | |
|   until (FLine[Run] = #39);
 | |
|   if FLine[Run] <> #0 then inc(Run);
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.StringEndProc(EndChar:char);
 | |
| var fBackslashCount:integer;
 | |
| begin
 | |
|   if fRange = rsMultilineString3 then
 | |
|     fTokenID := tkString
 | |
|   else
 | |
|     fTokenID := tkTripleQuotedString;
 | |
| 
 | |
|   case FLine[Run] of
 | |
|     #0:
 | |
|       begin
 | |
|         NullProc;
 | |
|         EXIT;
 | |
|       end;
 | |
|     #10:
 | |
|       begin
 | |
|         LFProc;
 | |
|         EXIT;
 | |
|     end;
 | |
|     #13:
 | |
|       begin
 | |
|         CRProc;
 | |
|         EXIT;
 | |
|       end;
 | |
|   end;
 | |
| 
 | |
|   if fRange = rsMultilineString3 then begin
 | |
|     repeat
 | |
|       if FLine[Run]=fStringStarter then begin
 | |
|         inc(Run);
 | |
|         fRange:=rsUnknown;
 | |
|         EXIT;
 | |
|       end else if FLine[Run]='\' then ;  {The same backslash stuff above...}
 | |
|           begin
 | |
|              if FLine[Run + 1] = fStringStarter then
 | |
|                begin
 | |
|                  fBackslashCount := 1;
 | |
| 
 | |
|                  while ((Run > fBackslashCount) and (FLine[Run - fBackslashCount] = '\')) do
 | |
|                    fBackslashCount := fBackslashCount + 1;
 | |
| 
 | |
|                  if (fBackslashCount mod 2 = 1) then inc(Run);
 | |
|              end;
 | |
|            end;// if FLine[Run]...
 | |
| 
 | |
|       inc(Run);
 | |
|     until (FLine[Run] in [#0, #10, #13]);
 | |
|     if FLine[Run-1]<>'\' then begin
 | |
|       fRange:=rsUnknown;
 | |
|       EXIT;
 | |
|     end;
 | |
|   end else
 | |
|   repeat
 | |
|     if FLine[Run] = '\' then
 | |
|     begin
 | |
|        if FLine[Run + 1] = EndChar then
 | |
|          begin
 | |
|            fBackslashCount := 1;
 | |
| 
 | |
|            while ((Run > fBackslashCount) and (FLine[Run - fBackslashCount] = '\')) do
 | |
|              fBackslashCount := fBackslashCount + 1;
 | |
| 
 | |
|            if (fBackslashCount mod 2 = 1) then inc(Run,2);
 | |
|        end;
 | |
|      end;// if FLine[Run]...
 | |
|     if (FLine[Run]=EndChar) and (FLine[Run+1]=EndChar) and (FLine[Run+2]=EndChar) then begin
 | |
|       inc(Run,3);
 | |
|       fRange:=rsUnknown;
 | |
|       EXIT;
 | |
|     end;
 | |
|     inc(Run);
 | |
|   until (FLine[Run] in [#0, #10, #13]);
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.UnknownProc;
 | |
| begin
 | |
|   inc(Run);
 | |
|   while (fLine[Run] in [#128..#191]) OR // continued utf8 subcode
 | |
|    ((fLine[Run]<>#0) and (fProcTable[fLine[Run]] = @UnknownProc)) do inc(Run);
 | |
|   fTokenID := tkUnknown;
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.Next;
 | |
| begin
 | |
|   fTokenPos := Run;
 | |
| 
 | |
|   case fRange of
 | |
|     rsMultilineString:
 | |
|       StringEndProc(#39);
 | |
|     rsMultilineString2:
 | |
|       StringEndProc('"');
 | |
|     rsMultilineString3:
 | |
|       StringEndProc(fStringStarter);
 | |
|     else
 | |
|       fProcTable[fLine[Run]];
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
 | |
| begin
 | |
|   case Index of
 | |
|     SYN_ATTR_COMMENT: Result := fCommentAttri;
 | |
|     SYN_ATTR_KEYWORD: Result := fKeyAttri;
 | |
|     SYN_ATTR_WHITESPACE: Result := fSpaceAttri;
 | |
|     SYN_ATTR_SYMBOL: Result := fSymbolAttri;
 | |
|   else
 | |
|     Result := nil;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetEol: Boolean;
 | |
| begin
 | |
|   Result := fTokenId = tkNull;
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetRange: Pointer;
 | |
| begin
 | |
|   Result := Pointer(PtrInt(fRange));
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetToken: string;
 | |
| var
 | |
|   Len: LongInt;
 | |
| begin
 | |
|   Result := '';
 | |
|   Len := Run - fTokenPos;
 | |
|   SetString(Result, (FLine + fTokenPos), Len);
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetTokenID: TtkTokenKind;
 | |
| begin
 | |
|   Result := fTokenId;
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetTokenAttribute: TSynHighlighterAttributes;
 | |
| begin
 | |
|   case fTokenID of
 | |
|     tkComment: Result := fCommentAttri;
 | |
|     tkIdentifier: Result := fIdentifierAttri;
 | |
|     tkKey: Result := fKeyAttri;
 | |
|     tkNonKeyword: Result := fNonKeyAttri;
 | |
|     tkSystemDefined: Result := fSystemAttri;
 | |
|     tkNumber: Result := fNumberAttri;
 | |
|     tkHex: Result := fHexAttri;
 | |
|     tkOct: Result := fOctalAttri;
 | |
|     tkFloat: Result := fFloatAttri;
 | |
|     tkSpace: Result := fSpaceAttri;
 | |
|     tkString: Result := fStringAttri;
 | |
|     tkTripleQuotedString: Result := fDocStringAttri;
 | |
|     tkSymbol: Result := fSymbolAttri;
 | |
|     tkUnknown: Result := fErrorAttri;
 | |
|   else
 | |
|     Result := nil;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetTokenKind: integer;
 | |
| begin
 | |
|   Result := Ord(fTokenId);
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetTokenPos: Integer;
 | |
| begin
 | |
|   Result := fTokenPos;
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.ResetRange;
 | |
| begin
 | |
|   fRange := rsUnknown;
 | |
| end;
 | |
| 
 | |
| procedure TSynPythonSyn.SetRange(Value: Pointer);
 | |
| begin
 | |
|   fRange := TRangeState(PtrUInt(Value));
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetIdentChars: TSynIdentChars;
 | |
| begin
 | |
|   Result := TSynValidStringChars;
 | |
| end;
 | |
| 
 | |
| class function TSynPythonSyn.GetLanguageName: string;
 | |
| begin
 | |
|   Result := SYNS_LangPython;
 | |
| end;
 | |
| 
 | |
| function TSynPythonSyn.GetSampleSource: string;
 | |
| begin
 | |
|   Result :=
 | |
|     '#!/usr/local/bin/python'#13#10 +
 | |
|     'import string, sys'#13#10 +
 | |
|     '""" If no arguments were given, print a helpful message """'#13#10 +
 | |
|     'if len(sys.argv)==1:'#13#10 +
 | |
|     '    print ''Usage: celsius temp1 temp2 ...'''#13#10 +
 | |
|     '    sys.exit(0)';
 | |
| end;
 | |
| 
 | |
| initialization
 | |
|   RegisterPlaceableHighlighter(TSynPythonSyn);
 | |
| 
 | |
| finalization
 | |
|   GlobalKeywords.Free;
 | |
| end.
 | |
| 
 | 
