home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 October / Chip_2001-10_cd1.bin / zkuste / delphi / kolekce / d456 / DCSLIB25.ZIP / DCSyntaxData.pas < prev    next >
Pascal/Delphi Source File  |  2001-01-29  |  22KB  |  799 lines

  1. {
  2.  BUSINESS CONSULTING
  3.  s a i n t - p e t e r s b u r g
  4.  
  5.          Components Library for Borland Delphi 4.x, 5.x
  6.          Copyright (c) 1998-2000 Alex'EM
  7.  
  8. }
  9. unit DCSyntaxData;
  10.  
  11. interface
  12.  
  13. uses
  14.   Windows, SysUtils, Classes, Graphics;
  15.  
  16. type
  17.   TLexemType = (lxWhitespace, lxIdentifier, lxString, lxNumber, lxComment, lxSymbol,
  18.     lxKeyWord0, lxKeyWord1, lxKeyWord2, lxKeyWord3, lxKeyWord4, lxKeyWord5);
  19.  
  20.   PLexemItem = ^TLexemItem;
  21.   TLexemItem = packed record
  22.     Item: TLexemType;
  23.     Length: WORD;
  24.   end;
  25.  
  26.   PLexemItems = ^TLexemItems;
  27.   TLexemItems = packed array[0..0] of TLexemItem;
  28.  
  29.   PLineDataItem  = ^TLineDataItem;
  30.   TLineDataItem = packed record
  31.     FString: string;
  32.     FObject: TObject;
  33.     Comment: DWORD;
  34.     PrevComment: DWORD;
  35.     SyntaxType: DWORD;
  36.     Capacity: WORD;
  37.     Count: WORD;
  38.     Lexems: PLexemItems;
  39.   end;
  40.  
  41.   PLineDataItems = ^TLineDataItems;
  42.   TLineDataItems = packed array[0..0] of TLineDataItem;
  43.  
  44.   TDCCustomSyntaxData = class;
  45.  
  46.   TSyntaxDataClass = class of TDCCustomSyntaxData;
  47.  
  48.   TLexemColor = record
  49.     BGColor: TColor;
  50.     FGColor: TColor;
  51.     FontStyle: TFontStyles;
  52.   end;
  53.  
  54.   TDCSyntaxMemoColors = class(TPersistent)
  55.   public
  56.     Items: array[TLexemType] of TLexemColor;
  57.     constructor Create;
  58.   end;
  59.  
  60.   TCharArray = array[Char] of boolean;
  61.  
  62.   TDCCustomSyntaxData = class(TObject)
  63.   private
  64.     FSyntaxType: integer;
  65.     FOpenComment: DWORD;
  66.     FALexemSyntax: array[lxKeyWord0..lxKeyWord5] of integer;
  67.     FSyntaxColors: TDCSyntaxMemoColors;
  68.     function GetCommentLen(Comment: integer): integer;
  69.     procedure DefineKeyWord(LexemItem: TLexemType);
  70.   protected
  71.     FKeyWords: string;
  72.     FSymbols: string;
  73.     FQuotes: string;
  74.     FNumbers: string;
  75.     FOpenComment1: DWORD;
  76.     FCloseComment1: DWORD;
  77.     FOpenComment2: DWORD;
  78.     FCloseComment2: DWORD;
  79.     FEOLComment1: DWORD;
  80.     FEOLComment2: DWORD;
  81.     FAIdents, FANumbers, FASymbols: TCharArray;
  82.     function GetCloseComment(OpenComment: DWORD): DWORD;
  83.     function IsKeyWord(Value: string; var Lexem: TLexemType): boolean;
  84.     function IsIdentChar(Value: Char; lHeading: boolean): boolean; virtual;
  85.     function GetBlockComment(Source: PChar; OpenComment: DWORD; var LexemItem: TLexemItem;
  86.            AInc: boolean = True): boolean;
  87.     function GetEOLComment(Source: PChar; var LexemItem: TLexemItem; Comment: DWORD): boolean;
  88.     function GetIdent(Source: PChar; var LexemItem: TLexemItem): boolean;
  89.     function GetLex(Source: PChar; var LexemItem: TLexemItem): boolean;
  90.     function GetNumber(Source: PChar; var LexemItem: TLexemItem): boolean; virtual;
  91.     function GetString(Source: PChar; var LexemItem: TLexemItem): boolean; virtual;
  92.     function GetHexNumber(Source: PChar; var LexemItem: TLexemItem): boolean;
  93.     function GetDecNumber(Source: PChar; var LexemItem: TLexemItem): boolean;
  94.     procedure InitSyntaxColor(SyntaxColor: TDCSyntaxMemoColors); virtual;
  95.     procedure InitHash; virtual;
  96.   public
  97.     constructor Create; virtual;
  98.     destructor Destroy; override;
  99.     function BuildComment(Value: PChar): DWORD;
  100.     procedure ParseLine(pLineItems: PLineDataItem);
  101.     function IsDelimiter(Value: Char): boolean;
  102.     property SyntaxColors: TDCSyntaxMemoColors read FSyntaxColors;
  103.   end;
  104.  
  105.   TDCDelphiSyntaxData = class(TDCCustomSyntaxData)
  106.   protected
  107.     procedure InitSyntaxColor(SyntaxColor: TDCSyntaxMemoColors); override;
  108.   public
  109.     constructor Create; override;
  110.     function GetNumber(Source: PChar; var LexemItem: TLexemItem): boolean; override;
  111.     function GetString(Source: PChar; var LexemItem: TLexemItem): boolean; override;
  112.   end;
  113.  
  114.   TDCSQLSyntaxData = class(TDCCustomSyntaxData)
  115.   protected
  116.     procedure InitSyntaxColor(SyntaxColor: TDCSyntaxMemoColors); override;
  117.   public
  118.     constructor Create; override;
  119.     function GetNumber(Source: PChar; var LexemItem: TLexemItem): boolean; override;
  120.     function GetString(Source: PChar; var LexemItem: TLexemItem): boolean; override;
  121.   end;
  122.  
  123. function LISetCapacity(var LexemItems: PLexemItems; Capacity: WORD): PLexemItems;
  124.  
  125. implementation
  126.  
  127. { TDCCustomSyntaxData }
  128.  
  129. function LISetCapacity(var LexemItems: PLexemItems; Capacity: WORD): PLexemItems;
  130. begin
  131.   ReallocMem(LexemItems, Capacity * SizeOf(TLexemItem));
  132.   Result := LexemItems;
  133. end;
  134.  
  135. function TDCCustomSyntaxData.BuildComment(Value: PChar): DWORD;
  136. begin
  137.   Result := PDWORD(Value)^;
  138. end;
  139.  
  140. constructor TDCCustomSyntaxData.Create;
  141.  var
  142.   i: TLexemType;
  143. begin
  144.   inherited Create;
  145.  
  146.   for i := Low(FALexemSyntax) to High(FALexemSyntax) do FALexemSyntax[i] := -1;
  147.  
  148.   FKeyWords := '';
  149.   FSyntaxType := 0;
  150.   FSyntaxColors := TDCSyntaxMemoColors.Create;
  151.   InitSyntaxColor(FSyntaxColors);
  152. end;
  153.  
  154. procedure TDCCustomSyntaxData.DefineKeyWord(LexemItem: TLexemType);
  155. begin
  156.   FALexemSyntax[LexemItem] := Length(FKeyWords);
  157. end;
  158.  
  159. destructor TDCCustomSyntaxData.Destroy;
  160. begin
  161.   FSyntaxColors.Free;
  162.   inherited;
  163. end;
  164.  
  165. function TDCCustomSyntaxData.GetBlockComment(Source: PChar;
  166.   OpenComment: DWORD; var LexemItem: TLexemItem; AInc: boolean = True): boolean;
  167.  var
  168.   CloseComment: DWORD;
  169.   pValue: PChar;
  170.   i, j: DWORD;
  171. begin
  172.   LexemItem.Item   := lxComment;
  173.  
  174.   LexemItem.Length := GetCommentLen(OpenComment);
  175.   CloseComment   := GetCloseComment(OpenComment);
  176.  
  177.   i := GetCommentLen(CloseComment);
  178.   j := 8 * (Sizeof(DWORD) - i);
  179.  
  180.   pValue := Source;
  181.   Result := True;
  182.  
  183.   if AInc then Inc(pValue, LexemItem.Length);
  184.  
  185.   while (pValue^ <> #0) and
  186.         ((PDWORD(pValue)^ shl j) shr j <> CloseComment) do Inc(pValue);
  187.  
  188.   LexemItem.Length := pValue - Source;
  189.  
  190.   if pValue^ = #0 then
  191.     FOpenComment := OpenComment
  192.   else begin
  193.     LexemItem.Length := LexemItem.Length + i;
  194.     FOpenComment := 0;
  195.   end;
  196. end;
  197.  
  198. function TDCCustomSyntaxData.GetCloseComment(OpenComment: DWORD): DWORD;
  199. begin
  200.   if OpenComment = FOpenComment1 then Result := FCloseComment1 else
  201.   if OpenComment = FOpenComment2 then Result := FCloseComment2 else Result := 0;
  202. end;
  203.  
  204. function TDCCustomSyntaxData.GetCommentLen(Comment: integer): integer;
  205. begin
  206.   Result := 0;
  207.   while Comment > 0 do
  208.   begin
  209.     Comment := Comment shr 8;
  210.     inc(Result);
  211.   end;
  212. end;
  213.  
  214. function TDCCustomSyntaxData.GetDecNumber(Source: PChar;
  215.   var LexemItem: TLexemItem): boolean;
  216.  
  217.  type
  218.   TNumericPart = (npIntegral, npDecimal, npExponent);
  219.  
  220.  var
  221.   pValue: PChar;
  222.   NumericPart:  TNumericPart;
  223.   Values: array[TNumericPart] of string[30];
  224.   ESigns: array[TNumericPart] of ShortInt;
  225. begin
  226.   LexemItem.Item := lxNumber;
  227.  
  228.   Result   := True;
  229.   pValue   := Source;
  230.  
  231.   ESigns[npIntegral] := 0;
  232.   ESigns[npDecimal ] := -1;
  233.   ESigns[npExponent] := 0;
  234.  
  235.   for NumericPart := npIntegral to npExponent do Values[NumericPart] := '';
  236.   NumericPart := npIntegral;
  237.  
  238.   while (Source^ <> #0) do
  239.   begin
  240.     case Source^ of
  241.       '+', '-':
  242.         if (ESigns[NumericPart] = 0) and (Values[NumericPart] = '') then
  243.           ESigns[NumericPart] := ESigns[NumericPart] + 1
  244.         else
  245.           Break;
  246.       'E', 'e':
  247.         if (NumericPart <> npExponent) and
  248.            ((NumericPart = npIntegral) and (Values[NumericPart] <> '') or
  249.             (NumericPart = npDecimal ) and (Values[NumericPart] <> '')) then
  250.           NumericPart := npExponent
  251.         else
  252.           Break;
  253.       '0'..'9':
  254.         Values[NumericPart] := Values[NumericPart] + Source^;
  255.       else
  256.         if (Source^ = {DecimalSeparator}'.') and
  257.            (NumericPart = npIntegral)
  258.         then
  259.           NumericPart := npDecimal
  260.         else
  261.           Break;
  262.     end;
  263.     Inc(Source);
  264.   end;
  265.  
  266.   LexemItem.Length := Source - pValue;
  267. end;
  268.  
  269.  
  270. function TDCCustomSyntaxData.GetEOLComment(Source: PChar;
  271.   var LexemItem: TLexemItem; Comment: DWORD): boolean;
  272. begin
  273.   Result   := True;
  274.   LexemItem.Item   := lxComment;
  275.   LexemItem.Length := StrLen(Source);
  276. end;
  277.  
  278. function TDCCustomSyntaxData.GetHexNumber(Source: PChar;
  279.   var LexemItem: TLexemItem): boolean;
  280.  var
  281.   pValue: PChar;
  282. begin
  283.   LexemItem.Item := lxNumber;
  284.  
  285.   Result   := True;
  286.   pValue   := Source;
  287.  
  288.   Inc(Source);
  289.   while (Source^ >= '0') and (Source^ <= '9') or
  290.         (Source^ >= 'A') and (Source^ <= 'F') or
  291.         (Source^ >= 'a') and (Source^ <= 'f') do  Inc(Source);
  292.  
  293.   LexemItem.Length := Source - pValue;
  294. end;
  295.  
  296. function TDCCustomSyntaxData.GetIdent(Source: PChar;
  297.   var LexemItem: TLexemItem): boolean;
  298.  var
  299.   pValue: PChar;
  300.   IdentValue: String;
  301. begin
  302.   Result  := True;
  303.   pValue  := Source;
  304.   Inc(pValue);
  305.  
  306.   while (pValue^ <> #0) and IsIdentChar(pValue^, False) do Inc(pValue);
  307.  
  308.   LexemItem.Length := pValue - Source;
  309.   SetString(IdentValue, Source, LexemItem.Length);
  310.  
  311.  
  312.   if not IsKeyWord(IdentValue, LexemItem.Item) then LexemItem.Item := lxIdentifier;
  313. end;
  314.  
  315. function TDCCustomSyntaxData.GetLex(Source: PChar;
  316.   var LexemItem: TLexemItem): boolean;
  317.  var
  318.   pValue: PChar;
  319.   C: Char;
  320.   I, W: DWORD;
  321.  
  322.  function BeginOpenComment(AComment, W: DWORD): boolean;
  323.   var
  324.    i, j: DWORD;
  325.  begin
  326.    i := GetCommentLen(AComment);
  327.    j := 8 * (Sizeof(DWORD) - i);
  328.    Result := (W shl j) shr j = AComment;
  329.  end;
  330.  
  331. begin
  332.   FOpenComment := 0;
  333.  
  334.   if Source^ = #0
  335.   then begin
  336.     Result := False;
  337.     Exit;
  338.   end;
  339.  
  340.   Result := True;
  341.   pValue := Source;
  342.  
  343.   while Byte(pValue^) = VK_SPACE do Inc(pValue);
  344.  
  345.   if pValue - Source > 0 then
  346.   begin
  347.      LexemItem.Item   := lxWhiteSpace;
  348.      LexemItem.Length := pValue - Source;
  349.      Exit;
  350.   end;
  351.  
  352.   while pValue^ <> #0 do
  353.   begin
  354.     C := pValue^;
  355.     I := Byte(C);
  356.     W := PDWORD(pValue)^;
  357.  
  358.     if (I = FOpenComment1) or BeginOpenComment(FOpenComment1, W)
  359.     then begin
  360.       Result := GetBlockComment(pValue, FOpenComment1, LexemItem);
  361.       Exit;
  362.     end;
  363.     if (I = FOpenComment2) or BeginOpenComment(FOpenComment2, W)
  364.     then begin
  365.       Result := GetBlockComment(pValue, FOpenComment2, LexemItem);
  366.       Exit;
  367.     end;
  368.  
  369.     if (I = FEOLComment1) or BeginOpenComment(FEOLComment1, W)
  370.     then begin
  371.       Result := GetEOLComment(pValue, LexemItem, FEOLComment1);
  372.       Exit;
  373.     end;
  374.     if (I = FEOLComment2) or BeginOpenComment(FEOLComment2, W)
  375.     then begin
  376.       Result := GetEOLComment(pValue, LexemItem, FEOLComment2);
  377.       Exit;
  378.     end;
  379.  
  380.     if StrScan(PChar(FQuotes), C) <> nil then
  381.     begin
  382.       Result := GetString(pValue, LexemItem);
  383.       Exit;
  384.     end;
  385.  
  386.     if FANumbers[C] then
  387.     begin
  388.       Result := GetNumber(pValue, LexemItem);
  389.       Exit;
  390.     end;
  391.  
  392.     if FASymbols[C] then
  393.     begin
  394.       Inc(pValue);
  395.       while (pValue^ <> #0) and FASymbols[pValue^] do
  396.       begin
  397.         I := Byte(pValue^);
  398.         W := PWORD(pValue)^;
  399.         if (I = FOpenComment1) or (I = FOpenComment2) or (I = FEOLComment1) or (I = FEOLComment2) or
  400.            (W = FOpenComment1) or (W = FOpenComment2) or (W = FEOLComment1) or (W = fEOLComment2) or
  401.            (StrScan(PChar(FQuotes), pValue^) <> nil) then
  402.           Break;
  403.         Inc(pValue);
  404.       end;
  405.       LexemItem.Item   := lxSymbol;
  406.       LexemItem.Length := pValue - Source;
  407.       Exit;
  408.     end;
  409.  
  410.     if IsIdentChar(C, True) then
  411.     begin
  412.       Result := GetIdent(pValue, LexemItem);
  413.       Exit;
  414.     end;
  415.  
  416.     Inc(pValue);
  417.   end;
  418.  
  419.   if pValue - Source > 0 then
  420.   begin
  421.      LexemItem.Item   := lxWhiteSpace;
  422.      LexemItem.Length := pValue - Source;
  423.   end;
  424.  
  425. end;
  426.                                                    
  427. function TDCCustomSyntaxData.GetNumber(Source: PChar;
  428.   var LexemItem: TLexemItem): boolean;
  429.  var
  430.   pValue: PChar;
  431. begin
  432.   LexemItem.Item := lxNumber;
  433.  
  434.   Result   := True;
  435.   pValue   := Source;
  436.  
  437.   Inc(Source);
  438.   while (Source^ >= '0') and (Source^ <= '9') do  Inc(Source);
  439.  
  440.   LexemItem.Length := Source - pValue;
  441. end;
  442.  
  443. function TDCCustomSyntaxData.GetString(Source: PChar;
  444.   var LexemItem: TLexemItem): boolean;
  445.  var
  446.   Quote : Char;
  447.   pValue: PChar;
  448. begin
  449.    LexemItem.Item := lxString;
  450.  
  451.    Result   := True;
  452.    Quote    := Source^;
  453.    pValue   := Source;
  454.  
  455.    Inc(Source);
  456.  
  457.    while (Source^ <> #0) and (Source^ <> Quote) do Inc(Source);
  458.  
  459.    LexemItem.Length := Source - pValue;
  460.  
  461.    if Source^ <> #0 then Inc(LexemItem.Length);
  462. end;
  463.  
  464. procedure TDCCustomSyntaxData.InitHash;
  465.  var
  466.   c: Char;
  467. begin
  468.   for c:= #0 to #255 do
  469.     FAIdents[c] := (c in ['a'..'z', 'A'..'Z', '_']) or
  470.      ((c >= 'α') and (c <= ' ')) or ((c >= '└') and (c <= '▀')) or (c in ['0'..'9']);
  471.  
  472.   for c:= #0 to #255 do
  473.     FANumbers[c] := (c in ['0'..'9']) or (StrScan(PChar(FNumbers), c) <> nil);
  474.  
  475.   for c:= #0 to #255 do
  476.     FASymbols[c] := (StrScan(PChar(FSymbols), c) <> nil);
  477. end;
  478.  
  479. procedure TDCCustomSyntaxData.InitSyntaxColor;
  480. begin
  481.   {}
  482. end;
  483.  
  484. function TDCCustomSyntaxData.IsDelimiter(Value: Char): boolean;
  485. begin
  486.   Result := (Value = #32) or (StrScan(PChar(FSymbols), Value) <> nil);
  487. end;
  488.  
  489. function TDCCustomSyntaxData.IsIdentChar(Value: char;
  490.   lHeading: boolean): boolean;
  491. begin
  492.   Result := FAIdents[Value]
  493. end;
  494.  
  495. function TDCCustomSyntaxData.IsKeyWord(Value: string; var Lexem: TLexemType): boolean;
  496.  var
  497.   UpperValue: string;
  498.   pValue: PChar;
  499.   i: TLexemType;
  500.   ValuePos: integer;
  501. begin
  502.   UpperValue := ' ' + AnsiUpperCase(Value)+' ';
  503.   pValue := StrPos(PChar(FKeyWords), PChar(UpperValue));
  504.   Result := pValue <> nil;
  505.   if Result then
  506.   begin
  507.     ValuePos := pValue - PChar(FKeyWords);
  508.     for i := Low(FALexemSyntax) to High(FALexemSyntax) do
  509.       if (FALexemSyntax[i] > -1) and (FALexemSyntax[i] > ValuePos) then
  510.       begin
  511.         Lexem := i;
  512.         Break;
  513.       end;
  514.   end;
  515. end;
  516.  
  517. procedure TDCCustomSyntaxData.ParseLine(pLineItems: PLineDataItem);
  518.  var
  519.   LexemItem: TLexemItem;
  520.   Source: PChar;
  521.  
  522.   procedure AddItem;
  523.   begin
  524.     with pLineItems^ do
  525.     begin
  526.       if (Count > 0) and (Lexems^[Count-1].Item = LexemItem.Item)  then
  527.         Inc(Lexems^[Count-1].Length, LexemItem.Length)
  528.       else begin
  529.         if Count = Capacity then
  530.         begin
  531.           if Capacity > 16 then
  532.             Inc(Capacity, 16)
  533.           else
  534.             if Capacity > 8 then
  535.               Inc(Capacity, 8)
  536.             else
  537.               Inc(Capacity, 4);
  538.           Lexems := LISetCapacity(Lexems, Capacity);
  539.         end;
  540.         Lexems^[Count].Item   := LexemItem.Item;
  541.         Lexems^[Count].Length := LexemItem.Length;
  542.         Inc(Count);
  543.       end;
  544.     end;
  545.  
  546.     Inc(Source, LexemItem.Length);
  547.     if (LexemItem.Item = lxComment) and (FOpenComment <> 0) then
  548.       pLineItems^.Comment := FOpenComment;
  549.   end;
  550.  
  551. begin
  552.   with pLineItems^ do
  553.   begin
  554.     Count   := 0;
  555.     Comment := 0;
  556.     Source  := PChar(FString);
  557.   end;
  558.  
  559.   if pLineItems^.PrevComment <> 0
  560.   then begin
  561.      if GetBlockComment(Source, pLineItems^.PrevComment, LexemItem, False) then
  562.      begin
  563.        AddItem;
  564.        if FOpenComment <> 0 then
  565.        begin
  566.          pLineItems^.PrevComment := FOpenComment;
  567.          Exit;
  568.        end;
  569.      end;
  570.   end;
  571.  
  572.   while GetLex(Source, LexemItem) do AddItem;
  573.  
  574. end;
  575.  
  576. { TDCSyntaxMemoColors }
  577.  
  578. constructor TDCSyntaxMemoColors.Create;
  579.  const
  580.   DefaultLexemColor: TLexemColor = (BGColor: clWindow; FGColor: clBlack; FontStyle: []);
  581.  var
  582.   i: TLexemType;
  583. begin
  584.   inherited;
  585.   for i := Low(Items) to High(Items) do Items[i] := DefaultLexemColor;
  586. end;
  587.  
  588. { TDCDelphiSyntaxData }
  589.  
  590. constructor TDCDelphiSyntaxData.Create;
  591. begin
  592.   inherited;
  593.   FKeyWords := ' AND ARRAY AS ASM BEGIN CASE CLASS CONST CONSTRUCTOR' +
  594.                ' DESTRUCTOR DISPINTERFACE DIV DO DOWNTO ELSE END EXCEPT' +
  595.                ' EXPORTS FILE FINALIZATION FINNALY FOR FUNCTION GOTO IF' +
  596.                ' IMPLEMENTATION IN INHERITED INITIALIZATION INLINE INTERFACE' +
  597.                ' IS LABEL LIBRARY MOD NIL NOT OBJECT OF OR OUT PACKED'  +
  598.                ' PROCEDURE PROGRAM PROPERTY RAISE RECORD REPEAT RESOURCESTRING' +
  599.                ' SET SHL SHR STRING THEN THREADVAR TO TRY TYPE UNIT UNTIL USES' +
  600.                ' VAR WHILE WITH XOR MESSAGE' +
  601.                {property keywords}
  602.                ' PRIVATE PROTECTED PUBLIC PUBLISHED READ WRITE DEFAULT STORED' +
  603.                {special}
  604.                ' ON ';
  605.   DefineKeyWord(lxKeyWord0);
  606.  
  607.   FSymbols  := '`~!@#$%^&*()-+=|\{[}]:;<,>.?/"''';
  608.   FQuotes    := '#''';
  609.   FNumbers   := '$';
  610.  
  611.   FOpenComment1  := BuildComment('{');
  612.   FCloseComment1 := BuildComment('}') ;
  613.   FOpenComment2  := BuildComment('(*');
  614.   FCloseComment2 := BuildComment('*)');
  615.  
  616.   FEOLComment1  := BuildComment('//');
  617.   FEOLComment2  := 0;
  618.   InitHash;
  619. end;
  620.  
  621. function TDCDelphiSyntaxData.GetNumber(Source: PChar;
  622.   var LexemItem: TLexemItem): boolean;
  623. begin
  624.   if Source^ = '$' then
  625.     Result := GetHexNumber(Source, LexemItem)
  626.   else
  627.     Result := GetDecNumber(Source, LexemItem)
  628. end;
  629.  
  630. function TDCDelphiSyntaxData.GetString(Source: PChar;
  631.   var LexemItem: TLexemItem): boolean;
  632.  var
  633.   Quote : Char;
  634.   pValue: PChar;
  635.   W, EscapeValue: WORD;
  636. begin
  637.    LexemItem.Item := lxString;
  638.  
  639.    Result   := True;
  640.    Quote    := Source^;
  641.    pValue   := Source;
  642.  
  643.    if Source^ = '#' then
  644.    begin
  645.      Inc(Source);
  646.      while (Source^ <> #0) and (Source^ >= '0') and (Source^ <= '9') do Inc(Source);
  647.    end
  648.    else begin
  649.      Inc(Source);
  650.      EscapeValue := Ord('''') shl 8 or Ord('''');
  651.      while (Source^ <> #0) do begin
  652.        W := PWORD(Source)^;
  653.        if W = EscapeValue then
  654.          Inc(Source)
  655.        else
  656.          if Source^ = Quote then Break;
  657.        Inc(Source)
  658.      end;
  659.      if Source^ <> #0 then Inc(Source);
  660.    end;
  661.  
  662.    LexemItem.Length := Source - pValue;
  663. end;
  664.  
  665. procedure TDCDelphiSyntaxData.InitSyntaxColor(SyntaxColor: TDCSyntaxMemoColors);
  666. begin
  667.   inherited;
  668.   with SyntaxColor do
  669.   begin
  670.     Items[lxNumber ].FGColor := clRed;
  671.     Items[lxString ].FGColor := clBlue;
  672.     Items[lxComment].FGColor := clNavy;
  673.  
  674.     Items[lxNumber ].FontStyle := [fsBold];
  675.     Items[lxString ].FontStyle := [fsBold];
  676.     Items[lxComment].FontStyle := [fsItalic];
  677.  
  678.     Items[lxKeyWord0].FontStyle := [fsBold];
  679.   end;
  680. end;
  681.  
  682. { TDCSQLSyntaxData }
  683.  
  684. constructor TDCSQLSyntaxData.Create;
  685. begin
  686.   inherited;
  687.   FKeyWords := ' ADD ALL ALTER ANY AS ASC AUTHORIZATION AVG BACKUP BEGIN' +
  688.                ' BETWEEN BREAK BROWSE BULK BY CASCADE CHECKPOINT' +
  689.                ' CLOSE CLUSTERED COLESCE COLUMN COMMIT COMMITED COMPUTE' +
  690.                ' CONFIRM CONSTRAINT CONTAINS CONTAINSTABLE CONTINUE' +
  691.                ' CONTROLROW CREATE CROSS CURRENT CURRENT_DATE' +
  692.                ' CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR DATABASE' +
  693.                ' DBCC DEALLOCATE DECLARE DEFAULT DELETE DENY DESC DISK' +
  694.                ' DISTINCT DISTRIBUTED DOUBLE DROP DUMMY DUMP ELSE END ERRLVL' +
  695.                ' ERROREXIT EXCEPT EXEC EXECUTE ' +
  696.  
  697.                ' EXIT FETCH FILE FILLFACTOR FLOPPY FOR FOREIGN FREETEXT' +
  698.                ' FREETEXTTABLE FROM FULL GOTO GRANT GROUP HAVING HOLDLOCK' +
  699.                ' IDENTITY IDENTITY_INSERT IDENTITYCOL IF INDEX INNER' +
  700.                ' INSERT INTERSECT INTO IS ISOLATION JOIN KEY KILL LEFT' +
  701.                ' LEVEL LIKE LINENO LOAD MAX MIN MIRROREXIT NATIONAL NOCHECK' +
  702.                ' NONCLUSTERED OF OFF OFFSETS ON ONCE ONLY' +
  703.                ' OPEN OPENDATASOURCE OPENQUERY OPENROWSET OPTION ORDER' +
  704.                ' OUTER OVER PERCENT PERM PERMANENT PIP PLAN PRECISION' +
  705.  
  706.                ' PRIMARY PRINT PRIVILEGES PROC PROCEDURE PROCESSEXIT PUBLIC' +
  707.                ' RAISERROR READ READTEXT RECONFIGURE REFERENCES REPEATABLE' +
  708.                ' REPLICATION RESTORE RESTRICT RETURN REVOKE RIGHT ROLLBACK' +
  709.                ' ROWCOUNT ROWGUIDCOL RULE SAVE SCHEMA SELECT SERIALIZABLE' +
  710.                ' SESSION_USER SET SETUSER SHUTDOWN STATISTICS SUM' +
  711.                ' SYSTEM_USER TABLE TAPE TEMP TEMPORARY TEXTSIZE THEN TO TOP' +
  712.                ' TRAN TRANSACTION TRIGGER TRUNCATE TSEQUAL UNCOMMITTED UNION' +
  713.                ' UNIQUE UPDATE UPDATETEXT USE USER VALUES VARYING VIEW WAITFOR' +
  714.                ' WHEN WHERE WHILE WITH WORK WRITETEXT PREPARE ';
  715.   DefineKeyWord(lxKeyWord0);
  716.  
  717.   FKeyWords := FKeyWords +
  718.                ' IN OR AND NOT NULL EXISITS SOME ';
  719.   DefineKeyWord(lxKeyWord1);
  720.  
  721.   FKeyWords := FKeyWords +
  722.                ' SYSLOGINS SYSOBJECTS SYSCOLUMNS SYSINDEXES SYSUSERS SYSMEMBERS' +
  723.                ' SYSTEM ';
  724.   DefineKeyWord(lxKeyWord2);
  725.  
  726.   FKeyWords := FKeyWords +
  727.                ' CASE CONVERT COUNT NULLIF PI ';
  728.   DefineKeyWord(lxKeyWord3);
  729.  
  730.   FSymbols  := '`~!@#$%^&*()-+=|\{[}]:;<,>.?/"''';
  731.   FQuotes    := '#''"';
  732.   FNumbers   := '$';
  733.  
  734.   FOpenComment1  := BuildComment('/*');
  735.   FCloseComment1 := BuildComment('*/');
  736.   FOpenComment2  := 0;
  737.   FCloseComment2 := 0;
  738.  
  739.   FEOLComment1  := BuildComment('--');
  740.   FEOLComment2  := 0;
  741.   InitHash;
  742. end;
  743.  
  744. function TDCSQLSyntaxData.GetNumber(Source: PChar;
  745.   var LexemItem: TLexemItem): boolean;
  746. begin
  747.   if Source^ = '$' then
  748.     Result := GetHexNumber(Source, LexemItem)
  749.   else
  750.     Result := GetDecNumber(Source, LexemItem)
  751. end;
  752.  
  753. function TDCSQLSyntaxData.GetString(Source: PChar;
  754.   var LexemItem: TLexemItem): boolean;
  755.  var
  756.   Quote : Char;
  757.   pValue: PChar;
  758.   W, EscapeValue: WORD;
  759. begin
  760.    LexemItem.Item := lxString;
  761.  
  762.    Result   := True;
  763.    Quote    := Source^;
  764.    pValue   := Source;
  765.  
  766.    Inc(Source);
  767.    EscapeValue := Ord('''') shl 8 or Ord('''');
  768.    while (Source^ <> #0) do begin
  769.      W := PWORD(Source)^;
  770.      if W = EscapeValue then
  771.        Inc(Source)
  772.      else
  773.        if Source^ = Quote then Break;
  774.      Inc(Source)
  775.    end;
  776.    if Source^ <> #0 then Inc(Source);
  777.  
  778.    LexemItem.Length := Source - pValue;
  779. end;
  780.  
  781. procedure TDCSQLSyntaxData.InitSyntaxColor(
  782.   SyntaxColor: TDCSyntaxMemoColors);
  783. begin
  784.   inherited;
  785.   with SyntaxColor do
  786.   begin
  787.     Items[lxNumber ].FGColor := clNavy;
  788.     Items[lxString ].FGColor := clRed;
  789.     Items[lxComment].FGColor := clDkGray;
  790.  
  791.     Items[lxKeyWord0].FGColor := clBlue;
  792.     Items[lxKeyWord1].FGColor := clGray;
  793.     Items[lxKeyWord2].FGColor := clGreen;
  794.     Items[lxKeyWord3].FGColor := clFuchsia;
  795.   end;
  796. end;
  797.  
  798. end.
  799.