mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 05:39:34 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			1235 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			1235 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;
 | 
						|
    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 GetKeywordIdentifiers: TStringList; virtual;
 | 
						|
    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;
 | 
						|
    SYN_ATTR_NUMBER: Result := fNumberAttri;
 | 
						|
  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.
 | 
						|
 |