LuaSyntax.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  1. {-------------------------------------------------------------------------------
  2. The contents of this file are subject to the Mozilla Public License
  3. Version 1.1 (the "License"); you may not use this file except in compliance
  4. with the License. You may obtain a copy of the License at
  5. http://www.mozilla.org/MPL/
  6. Software distributed under the License is distributed on an "AS IS" basis,
  7. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  8. the specific language governing rights and limitations under the License.
  9. Code template generated with SynGen.
  10. The original code is: Lua.pas, released 2004-10-27.
  11. Description: Lua Syntax Parser/Highlighter
  12. The initial author of this file is Jean-François Goulet.
  13. Copyright (c) 2004, all rights reserved.
  14. Contributors to the SynEdit and mwEdit projects are listed in the
  15. Contributors.txt file.
  16. Alternatively, the contents of this file may be used under the terms of the
  17. GNU General Public License Version 2 or later (the "GPL"), in which case
  18. the provisions of the GPL are applicable instead of those above.
  19. If you wish to allow use of your version of this file only under the terms
  20. of the GPL and not to allow others to use your version of this file
  21. under the MPL, indicate your decision by deleting the provisions above and
  22. replace them with the notice and other provisions required by the GPL.
  23. If you do not delete the provisions above, a recipient may use your version
  24. of this file under either the MPL or the GPL.
  25. $Id: LuaSyntax.pas,v 1.2 2006-10-27 03:32:56 jfgoulet Exp $
  26. You may retrieve the latest version of this file at the SynEdit home page,
  27. located at http://SynEdit.SourceForge.net
  28. -------------------------------------------------------------------------------}
  29. unit LuaSyntax;
  30. {$I SynEdit.inc}
  31. interface
  32. uses
  33. {$IFDEF SYN_CLX}
  34. QGraphics,
  35. QSynEditTypes,
  36. QSynEditHighlighter,
  37. {$ELSE}
  38. Graphics,
  39. SynEditTypes,
  40. SynEditHighlighter,
  41. {$ENDIF}
  42. SysUtils,
  43. Classes;
  44. type
  45. TtkTokenKind = (
  46. tkComment,
  47. tkIdentifier,
  48. tkKey,
  49. tkLuaMString,
  50. tkNull,
  51. tkNumber,
  52. tkOctal,
  53. tkHex,
  54. tkFloat,
  55. tkSpace,
  56. tkString,
  57. tkUnknown);
  58. TRangeState = (rsUnKnown, rsLuaComment, rsLuaMComment, rsLuaMString, rsString1, rsString2);
  59. TProcTableProc = procedure of object;
  60. PIdentFuncTableFunc = ^TIdentFuncTableFunc;
  61. TIdentFuncTableFunc = function: TtkTokenKind of object;
  62. const
  63. MaxKey = 110;
  64. type
  65. TSynLuaSyn = class(TSynCustomHighlighter)
  66. private
  67. fLineRef: string;
  68. fLine: PChar;
  69. fLineNumber: Integer;
  70. fProcTable: array[#0..#255] of TProcTableProc;
  71. fRange: TRangeState;
  72. Run: LongInt;
  73. fStringLen: Integer;
  74. fToIdent: PChar;
  75. fTokenPos: Integer;
  76. fTokenID: TtkTokenKind;
  77. fIdentFuncTable: array[0 .. MaxKey] of TIdentFuncTableFunc;
  78. fCommentAttri: TSynHighlighterAttributes;
  79. fIdentifierAttri: TSynHighlighterAttributes;
  80. fKeyAttri: TSynHighlighterAttributes;
  81. fLuaMStringAttri: TSynHighlighterAttributes;
  82. fNumberAttri: TSynHighlighterAttributes;
  83. fSpaceAttri: TSynHighlighterAttributes;
  84. fStringAttri: TSynHighlighterAttributes;
  85. function KeyHash(ToHash: PChar): Integer;
  86. function KeyComp(const aKey: string): Boolean;
  87. function Func17: TtkTokenKind;
  88. function Func21: TtkTokenKind;
  89. function Func22: TtkTokenKind;
  90. function Func25: TtkTokenKind;
  91. function Func26: TtkTokenKind;
  92. function Func35: TtkTokenKind;
  93. function Func38: TtkTokenKind;
  94. function Func42: TtkTokenKind;
  95. function Func45: TtkTokenKind;
  96. function Func48: TtkTokenKind;
  97. function Func51: TtkTokenKind;
  98. function Func52: TtkTokenKind;
  99. function Func57: TtkTokenKind;
  100. function Func61: TtkTokenKind;
  101. function Func62: TtkTokenKind;
  102. function Func67: TtkTokenKind;
  103. function Func68: TtkTokenKind;
  104. function Func70: TtkTokenKind;
  105. function Func71: TtkTokenKind;
  106. function Func81: TtkTokenKind;
  107. function Func82: TtkTokenKind;
  108. function Func102: TtkTokenKind;
  109. function Func110: TtkTokenKind;
  110. procedure IdentProc;
  111. procedure UnknownProc;
  112. function AltFunc: TtkTokenKind;
  113. procedure InitIdent;
  114. function IdentKind(MayBe: PChar): TtkTokenKind;
  115. procedure MakeMethodTables;
  116. procedure NullProc;
  117. procedure SpaceProc;
  118. procedure CRProc;
  119. procedure LFProc;
  120. procedure LuaCommentOpenProc;
  121. procedure LuaCommentProc;
  122. procedure LuaMCommentOpenProc;
  123. procedure LuaMCommentProc;
  124. procedure LuaMStringOpenProc;
  125. procedure LuaMStringProc;
  126. procedure String1OpenProc;
  127. procedure String1Proc;
  128. procedure String2OpenProc;
  129. procedure String2Proc;
  130. procedure NumberProc;
  131. protected
  132. function GetIdentChars: TSynIdentChars; override;
  133. function GetSampleSource: string; override;
  134. function IsFilterStored: Boolean; override;
  135. public
  136. constructor Create(AOwner: TComponent); override;
  137. {$IFNDEF SYN_CPPB_1} class {$ENDIF}
  138. function GetLanguageName: string; override;
  139. function GetRange: Pointer; override;
  140. procedure ResetRange; override;
  141. procedure SetRange(Value: Pointer); override;
  142. function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; override;
  143. function GetEol: Boolean; override;
  144. function GetKeyWords: string;
  145. function GetTokenID: TtkTokenKind;
  146. procedure SetLine(NewValue: String; LineNumber: Integer); override;
  147. function GetToken: String; override;
  148. function GetTokenAttribute: TSynHighlighterAttributes; override;
  149. function GetTokenKind: integer; override;
  150. function GetTokenPos: Integer; override;
  151. procedure Next; override;
  152. published
  153. property CommentAttri: TSynHighlighterAttributes read fCommentAttri write fCommentAttri;
  154. property IdentifierAttri: TSynHighlighterAttributes read fIdentifierAttri write fIdentifierAttri;
  155. property KeyAttri: TSynHighlighterAttributes read fKeyAttri write fKeyAttri;
  156. property LuaMStringAttri: TSynHighlighterAttributes read fLuaMStringAttri write fLuaMStringAttri;
  157. property NumberAttri: TSynHighlighterAttributes read fNumberAttri write fNumberAttri;
  158. property SpaceAttri: TSynHighlighterAttributes read fSpaceAttri write fSpaceAttri;
  159. property StringAttri: TSynHighlighterAttributes read fStringAttri write fStringAttri;
  160. end;
  161. implementation
  162. uses
  163. {$IFDEF SYN_CLX}
  164. QSynEditStrConst;
  165. {$ELSE}
  166. SynEditStrConst;
  167. {$ENDIF}
  168. {$IFDEF SYN_COMPILER_3_UP}
  169. resourcestring
  170. {$ELSE}
  171. const
  172. {$ENDIF}
  173. SYNS_FilterLua = 'Lua Files (*.lua, *.lpr)|*.lua;*.lpr';
  174. SYNS_LangLua = 'Lua';
  175. SYNS_AttrLuaMString = 'LuaMString';
  176. SYNS_AttrNumber = 'Numbers';
  177. var
  178. Identifiers: array[#0..#255] of ByteBool;
  179. mHashTable : array[#0..#255] of Integer;
  180. procedure MakeIdentTable;
  181. var
  182. I: Char;
  183. begin
  184. for I := #0 to #255 do
  185. begin
  186. case I of
  187. '_', '0'..'9', 'a'..'z', 'A'..'Z': Identifiers[I] := True;
  188. else
  189. Identifiers[I] := False;
  190. end;
  191. case I in ['_', 'A'..'Z', 'a'..'z'] of
  192. True:
  193. begin
  194. if (I > #64) and (I < #91) then
  195. mHashTable[I] := Ord(I) - 64
  196. else if (I > #96) then
  197. mHashTable[I] := Ord(I) - 95;
  198. end;
  199. else
  200. mHashTable[I] := 0;
  201. end;
  202. end;
  203. end;
  204. procedure TSynLuaSyn.InitIdent;
  205. var
  206. I: Integer;
  207. pF: PIdentFuncTableFunc;
  208. begin
  209. pF := PIdentFuncTableFunc(@fIdentFuncTable);
  210. for I := Low(fIdentFuncTable) to High(fIdentFuncTable) do
  211. begin
  212. pF^ := AltFunc;
  213. Inc(pF);
  214. end;
  215. fIdentFuncTable[17] := Func17;
  216. fIdentFuncTable[21] := Func21;
  217. fIdentFuncTable[22] := Func22;
  218. fIdentFuncTable[25] := Func25;
  219. fIdentFuncTable[26] := Func26;
  220. fIdentFuncTable[35] := Func35;
  221. fIdentFuncTable[38] := Func38;
  222. fIdentFuncTable[42] := Func42;
  223. fIdentFuncTable[45] := Func45;
  224. fIdentFuncTable[48] := Func48;
  225. fIdentFuncTable[51] := Func51;
  226. fIdentFuncTable[52] := Func52;
  227. fIdentFuncTable[57] := Func57;
  228. fIdentFuncTable[61] := Func61;
  229. fIdentFuncTable[62] := Func62;
  230. fIdentFuncTable[67] := Func67;
  231. fIdentFuncTable[68] := Func68;
  232. fIdentFuncTable[70] := Func70;
  233. fIdentFuncTable[71] := Func71;
  234. fIdentFuncTable[81] := Func81;
  235. fIdentFuncTable[82] := Func82;
  236. fIdentFuncTable[102] := Func102;
  237. fIdentFuncTable[110] := Func110;
  238. end;
  239. function TSynLuaSyn.KeyHash(ToHash: PChar): Integer;
  240. begin
  241. Result := 0;
  242. while ToHash^ in ['_', 'a'..'z', 'A'..'Z'] do
  243. begin
  244. inc(Result, mHashTable[ToHash^]);
  245. inc(ToHash);
  246. end;
  247. fStringLen := ToHash - fToIdent;
  248. end;
  249. function TSynLuaSyn.KeyComp(const aKey: String): Boolean;
  250. var
  251. I: Integer;
  252. Temp: PChar;
  253. begin
  254. Temp := fToIdent;
  255. if Length(aKey) = fStringLen then
  256. begin
  257. Result := True;
  258. for i := 1 to fStringLen do
  259. begin
  260. if Temp^ <> aKey[i] then
  261. begin
  262. Result := False;
  263. break;
  264. end;
  265. inc(Temp);
  266. end;
  267. end else Result := False;
  268. end;
  269. function TSynLuaSyn.Func17: TtkTokenKind;
  270. begin
  271. if KeyComp('if') then Result := tkKey else Result := tkIdentifier;
  272. end;
  273. function TSynLuaSyn.Func21: TtkTokenKind;
  274. begin
  275. if KeyComp('do') then Result := tkKey else Result := tkIdentifier;
  276. end;
  277. function TSynLuaSyn.Func22: TtkTokenKind;
  278. begin
  279. if KeyComp('and') then Result := tkKey else Result := tkIdentifier;
  280. end;
  281. function TSynLuaSyn.Func25: TtkTokenKind;
  282. begin
  283. if KeyComp('in') then Result := tkKey else Result := tkIdentifier;
  284. end;
  285. function TSynLuaSyn.Func26: TtkTokenKind;
  286. begin
  287. if KeyComp('end') then Result := tkKey else Result := tkIdentifier;
  288. end;
  289. function TSynLuaSyn.Func35: TtkTokenKind;
  290. begin
  291. if KeyComp('or') then Result := tkKey else Result := tkIdentifier;
  292. end;
  293. function TSynLuaSyn.Func38: TtkTokenKind;
  294. begin
  295. if KeyComp('nil') then Result := tkKey else Result := tkIdentifier;
  296. end;
  297. function TSynLuaSyn.Func42: TtkTokenKind;
  298. begin
  299. if KeyComp('for') then Result := tkKey else
  300. if KeyComp('break') then Result := tkKey else Result := tkIdentifier;
  301. end;
  302. function TSynLuaSyn.Func45: TtkTokenKind;
  303. begin
  304. if KeyComp('else') then Result := tkKey else Result := tkIdentifier;
  305. end;
  306. function TSynLuaSyn.Func48: TtkTokenKind;
  307. begin
  308. if KeyComp('local') then Result := tkKey else
  309. if KeyComp('false') then Result := tkKey else Result := tkIdentifier;
  310. end;
  311. function TSynLuaSyn.Func51: TtkTokenKind;
  312. begin
  313. if KeyComp('then') then Result := tkKey else Result := tkIdentifier;
  314. end;
  315. function TSynLuaSyn.Func52: TtkTokenKind;
  316. begin
  317. if KeyComp('not') then Result := tkKey else Result := tkIdentifier;
  318. end;
  319. function TSynLuaSyn.Func57: TtkTokenKind;
  320. begin
  321. if KeyComp('loaddll') then Result := tkIdentifier else Result := tkIdentifier;
  322. end;
  323. function TSynLuaSyn.Func61: TtkTokenKind;
  324. begin
  325. if KeyComp('asd') then Result := tkIdentifier else Result := tkIdentifier;
  326. end;
  327. function TSynLuaSyn.Func62: TtkTokenKind;
  328. begin
  329. if KeyComp('while') then Result := tkKey else
  330. if KeyComp('print') then Result := tkIdentifier else
  331. if KeyComp('elseif') then Result := tkKey else Result := tkIdentifier;
  332. end;
  333. function TSynLuaSyn.Func67: TtkTokenKind;
  334. begin
  335. if KeyComp('asd') then Result := tkIdentifier else Result := tkIdentifier;
  336. end;
  337. function TSynLuaSyn.Func68: TtkTokenKind;
  338. begin
  339. if KeyComp('true') then Result := tkKey else Result := tkIdentifier;
  340. end;
  341. function TSynLuaSyn.Func70: TtkTokenKind;
  342. begin
  343. if KeyComp('asd') then Result := tkIdentifier else
  344. if KeyComp('asd') then Result := tkIdentifier else
  345. if KeyComp('dofile') then Result := tkIdentifier else Result := tkIdentifier;
  346. end;
  347. function TSynLuaSyn.Func71: TtkTokenKind;
  348. begin
  349. if KeyComp('repeat') then Result := tkKey else Result := tkIdentifier;
  350. end;
  351. function TSynLuaSyn.Func81: TtkTokenKind;
  352. begin
  353. if KeyComp('until') then Result := tkKey else Result := tkIdentifier;
  354. end;
  355. function TSynLuaSyn.Func82: TtkTokenKind;
  356. begin
  357. if KeyComp('asd') then Result := tkIdentifier else
  358. if KeyComp('asd') then Result := tkIdentifier else
  359. if KeyComp('beep') then Result := tkIdentifier else Result := tkIdentifier;
  360. end;
  361. function TSynLuaSyn.Func102: TtkTokenKind;
  362. begin
  363. if KeyComp('return') then Result := tkKey else Result := tkIdentifier;
  364. end;
  365. function TSynLuaSyn.Func110: TtkTokenKind;
  366. begin
  367. if KeyComp('function') then Result := tkKey else Result := tkIdentifier;
  368. end;
  369. function TSynLuaSyn.AltFunc: TtkTokenKind;
  370. begin
  371. Result := tkIdentifier;
  372. end;
  373. function TSynLuaSyn.IdentKind(MayBe: PChar): TtkTokenKind;
  374. var
  375. HashKey: Integer;
  376. begin
  377. fToIdent := MayBe;
  378. HashKey := KeyHash(MayBe);
  379. if HashKey <= MaxKey then
  380. Result := fIdentFuncTable[HashKey]
  381. else
  382. Result := tkIdentifier;
  383. end;
  384. procedure TSynLuaSyn.MakeMethodTables;
  385. var
  386. I: Char;
  387. begin
  388. for I := #0 to #255 do
  389. case I of
  390. #0: fProcTable[I] := NullProc;
  391. #10: fProcTable[I] := LFProc;
  392. #13: fProcTable[I] := CRProc;
  393. '-': fProcTable[I] := LuaCommentOpenProc;
  394. '[': fProcTable[I] := LuaMStringOpenProc;
  395. '"': fProcTable[I] := String1OpenProc;
  396. '''': fProcTable[I] := String2OpenProc;
  397. #1..#9, #11, #12, #14..#32 : fProcTable[I] := SpaceProc;
  398. '0'..'9': fProcTable[I] := NumberProc;
  399. 'A'..'Z', 'a'..'z', '_': fProcTable[I] := IdentProc;
  400. else
  401. fProcTable[I] := UnknownProc;
  402. end;
  403. end;
  404. procedure TSynLuaSyn.SpaceProc;
  405. begin
  406. fTokenID := tkSpace;
  407. repeat
  408. inc(Run);
  409. until not (fLine[Run] in [#1..#32]);
  410. end;
  411. procedure TSynLuaSyn.NullProc;
  412. begin
  413. fTokenID := tkNull;
  414. end;
  415. procedure TSynLuaSyn.CRProc;
  416. begin
  417. fTokenID := tkSpace;
  418. inc(Run);
  419. if fLine[Run] = #10 then
  420. inc(Run);
  421. end;
  422. procedure TSynLuaSyn.LFProc;
  423. begin
  424. fTokenID := tkSpace;
  425. inc(Run);
  426. end;
  427. procedure TSynLuaSyn.LuaCommentOpenProc;
  428. begin
  429. Inc(Run);
  430. if (fLine[Run] = '-') and
  431. (fLine[Run + 1] = '[') and
  432. (fLine[Run + 2] = '[') then
  433. begin
  434. LuaMCommentOpenProc;
  435. end
  436. else if (fLine[Run] = '-') then
  437. begin
  438. fRange := rsLuaComment;
  439. LuaCommentProc;
  440. fTokenID := tkComment;
  441. end
  442. else
  443. fTokenID := tkIdentifier;
  444. end;
  445. procedure TSynLuaSyn.LuaCommentProc;
  446. begin
  447. fTokenID := tkComment;
  448. repeat
  449. if (fLine[Run] = '@') and
  450. (fLine[Run + 1] = '£') and
  451. (fLine[Run + 2] = '¤') and
  452. (fLine[Run + 3] = '£') and
  453. (fLine[Run + 4] = '@') and
  454. (fLine[Run + 5] = '¢') and
  455. (fLine[Run + 6] = '£') and
  456. (fLine[Run + 7] = '@') then
  457. begin
  458. Inc(Run, 8);
  459. fRange := rsUnKnown;
  460. Break;
  461. end;
  462. if not (fLine[Run] in [#0, #10, #13]) then
  463. Inc(Run);
  464. until fLine[Run] in [#0, #10, #13];
  465. end;
  466. procedure TSynLuaSyn.LuaMCommentOpenProc;
  467. begin
  468. fRange := rsLuaMComment;
  469. LuaMCommentProc;
  470. fTokenID := tkComment;
  471. end;
  472. procedure TSynLuaSyn.LuaMCommentProc;
  473. begin
  474. case fLine[Run] of
  475. #0: NullProc;
  476. #10: LFProc;
  477. #13: CRProc;
  478. else
  479. begin
  480. fTokenID := tkComment;
  481. repeat
  482. if (fLine[Run] = ']') and
  483. (fLine[Run + 1] = ']') then
  484. begin
  485. Inc(Run, 2);
  486. fRange := rsUnKnown;
  487. Break;
  488. end;
  489. if not (fLine[Run] in [#0, #10, #13]) then
  490. Inc(Run);
  491. until fLine[Run] in [#0, #10, #13];
  492. end;
  493. end;
  494. end;
  495. procedure TSynLuaSyn.LuaMStringOpenProc;
  496. begin
  497. Inc(Run);
  498. if (fLine[Run] = '[') then
  499. begin
  500. fRange := rsLuaMString;
  501. LuaMStringProc;
  502. fTokenID := tkLuaMString;
  503. end
  504. else
  505. fTokenID := tkIdentifier;
  506. end;
  507. procedure TSynLuaSyn.LuaMStringProc;
  508. begin
  509. case fLine[Run] of
  510. #0: NullProc;
  511. #10: LFProc;
  512. #13: CRProc;
  513. else
  514. begin
  515. fTokenID := tkLuaMString;
  516. repeat
  517. if (fLine[Run] = ']') and
  518. (fLine[Run + 1] = ']') then
  519. begin
  520. Inc(Run, 2);
  521. fRange := rsUnKnown;
  522. Break;
  523. end;
  524. if not (fLine[Run] in [#0, #10, #13]) then
  525. Inc(Run);
  526. until fLine[Run] in [#0, #10, #13];
  527. end;
  528. end;
  529. end;
  530. procedure TSynLuaSyn.NumberProc;
  531. var
  532. idx1: Integer; // token[1]
  533. i: Integer;
  534. begin
  535. idx1 := Run;
  536. Inc(Run);
  537. fTokenID := tkNumber;
  538. while FLine[Run] in
  539. ['0'..'9', 'A'..'F', 'a'..'f', '.', 'u', 'U', 'l', 'L', 'x', 'X', '-', '+'] do
  540. begin
  541. case FLine[Run] of
  542. '.':
  543. if FLine[Succ(Run)] = '.' then
  544. Break
  545. else
  546. if (fTokenID <> tkHex) then
  547. fTokenID := tkFloat
  548. else // invalid
  549. begin
  550. fTokenID := tkUnknown;
  551. Exit;
  552. end;
  553. '-', '+':
  554. begin
  555. if fTokenID <> tkFloat then // number <> float. an arithmetic operator
  556. Exit;
  557. if not (FLine[Pred(Run)] in ['e', 'E']) then
  558. Exit; // number = float, but no exponent. an arithmetic operator
  559. if not (FLine[Succ(Run)] in ['0'..'9', '+', '-']) then // invalid
  560. begin
  561. Inc(Run);
  562. fTokenID := tkUnknown;
  563. Exit;
  564. end
  565. end;
  566. '0'..'7':
  567. if (Run = Succ(idx1)) and (FLine[idx1] = '0') then // octal number
  568. fTokenID := tkNumber; // Jean-François Goulet - Changed for token Number because token Octal was plain text and cannot be modified...
  569. '8', '9':
  570. if (FLine[idx1] = '0') and
  571. ((fTokenID <> tkHex) and (fTokenID <> tkFloat)) then // invalid octal char
  572. fTokenID := tkUnknown;
  573. 'a'..'d', 'A'..'D':
  574. if fTokenID <> tkHex then // invalid char
  575. Break;
  576. 'e', 'E':
  577. if (fTokenID <> tkHex) then
  578. if FLine[Pred(Run)] in ['0'..'9'] then // exponent
  579. begin
  580. for i := idx1 to Pred(Run) do
  581. if FLine[i] in ['e', 'E'] then // too many exponents
  582. begin
  583. fTokenID := tkUnknown;
  584. Exit;
  585. end;
  586. if not (FLine[Succ(Run)] in ['0'..'9', '+', '-']) then
  587. Break
  588. else
  589. fTokenID := tkFloat
  590. end
  591. else // invalid char
  592. Break;
  593. 'f', 'F':
  594. if fTokenID <> tkHex then
  595. begin
  596. for i := idx1 to Pred(Run) do
  597. if FLine[i] in ['f', 'F'] then // declaration syntax error
  598. begin
  599. fTokenID := tkUnknown;
  600. Exit;
  601. end;
  602. if fTokenID = tkFloat then
  603. begin
  604. if fLine[Pred(Run)] in ['l', 'L'] then // can't mix
  605. Break;
  606. end
  607. else
  608. fTokenID := tkFloat;
  609. end;
  610. 'l', 'L':
  611. begin
  612. for i := idx1 to Pred(Run) do
  613. if FLine[i] in ['l', 'L'] then // declaration syntax error
  614. begin
  615. fTokenID := tkUnknown;
  616. Exit;
  617. end;
  618. if fTokenID = tkFloat then
  619. if fLine[Pred(Run)] in ['f', 'F'] then // can't mix
  620. Break;
  621. end;
  622. 'u', 'U':
  623. if fTokenID = tkFloat then // not allowed
  624. Break
  625. else
  626. for i := idx1 to Pred(Run) do
  627. if FLine[i] in ['u', 'U'] then // declaration syntax error
  628. begin
  629. fTokenID := tkUnknown;
  630. Exit;
  631. end;
  632. 'x', 'X':
  633. if (Run = Succ(idx1)) and // 0x... 'x' must be second char
  634. (FLine[idx1] = '0') and // 0x...
  635. (FLine[Succ(Run)] in ['0'..'9', 'a'..'f', 'A'..'F']) then // 0x... must be continued with a number
  636. fTokenID := tkHex
  637. else // invalid char
  638. begin
  639. if (not Identifiers[fLine[Succ(Run)]]) and
  640. (FLine[Succ(idx1)] in ['x', 'X']) then
  641. begin
  642. Inc(Run); // highlight 'x' too
  643. fTokenID := tkUnknown;
  644. end;
  645. Break;
  646. end;
  647. end; // case
  648. Inc(Run);
  649. end; // while
  650. if FLine[Run] in ['A'..'Z', 'a'..'z', '_'] then
  651. fTokenID := tkUnknown;
  652. end;
  653. procedure TSynLuaSyn.String1OpenProc;
  654. begin
  655. Inc(Run);
  656. fRange := rsString1;
  657. String1Proc;
  658. fTokenID := tkString;
  659. end;
  660. procedure TSynLuaSyn.String1Proc;
  661. begin
  662. fTokenID := tkString;
  663. repeat
  664. if (((fLine[Run] = '"') and (fLine[Run - 1] <> '\')) or ((fLine[Run - 1] = '\') and (fLine[Run - 2] = '\') and (fLine[Run] = '"'))) then
  665. begin
  666. Inc(Run, 1);
  667. fRange := rsUnKnown;
  668. Break;
  669. end;
  670. if not (fLine[Run] in [#0, #10, #13]) then
  671. Inc(Run);
  672. until fLine[Run] in [#0, #10, #13];
  673. end;
  674. procedure TSynLuaSyn.String2OpenProc;
  675. begin
  676. Inc(Run);
  677. fRange := rsString2;
  678. String2Proc;
  679. fTokenID := tkString;
  680. end;
  681. procedure TSynLuaSyn.String2Proc;
  682. begin
  683. fTokenID := tkString;
  684. repeat
  685. if (fLine[Run] = '''') then
  686. begin
  687. Inc(Run, 1);
  688. fRange := rsUnKnown;
  689. Break;
  690. end;
  691. if not (fLine[Run] in [#0, #10, #13]) then
  692. Inc(Run);
  693. until fLine[Run] in [#0, #10, #13];
  694. end;
  695. constructor TSynLuaSyn.Create(AOwner: TComponent);
  696. begin
  697. inherited Create(AOwner);
  698. fCommentAttri := TSynHighLighterAttributes.Create(SYNS_AttrComment);
  699. fCommentAttri.Style := [fsItalic];
  700. fCommentAttri.Foreground := clGray;
  701. AddAttribute(fCommentAttri);
  702. fIdentifierAttri := TSynHighLighterAttributes.Create(SYNS_AttrIdentifier);
  703. AddAttribute(fIdentifierAttri);
  704. fKeyAttri := TSynHighLighterAttributes.Create(SYNS_AttrReservedWord);
  705. fKeyAttri.Style := [fsBold];
  706. AddAttribute(fKeyAttri);
  707. fLuaMStringAttri := TSynHighLighterAttributes.Create(SYNS_AttrLuaMString);
  708. fLuaMStringAttri.Foreground := clNavy;
  709. AddAttribute(fLuaMStringAttri);
  710. fNumberAttri := TSynHighLighterAttributes.Create(SYNS_AttrNumber);
  711. fNumberAttri.Foreground := clBlue;
  712. AddAttribute(fNumberAttri);
  713. fSpaceAttri := TSynHighLighterAttributes.Create(SYNS_AttrSpace);
  714. AddAttribute(fSpaceAttri);
  715. fStringAttri := TSynHighLighterAttributes.Create(SYNS_AttrString);
  716. fStringAttri.Foreground := clNavy;
  717. AddAttribute(fStringAttri);
  718. SetAttributesOnChange(DefHighlightChange);
  719. InitIdent;
  720. MakeMethodTables;
  721. fDefaultFilter := SYNS_FilterLua;
  722. fRange := rsUnknown;
  723. end;
  724. procedure TSynLuaSyn.SetLine(NewValue: String; LineNumber: Integer);
  725. begin
  726. fLineRef := NewValue;
  727. fLine := PChar(fLineRef);
  728. Run := 0;
  729. fLineNumber := LineNumber;
  730. Next;
  731. end;
  732. procedure TSynLuaSyn.IdentProc;
  733. begin
  734. fTokenID := IdentKind((fLine + Run));
  735. inc(Run, fStringLen);
  736. while Identifiers[fLine[Run]] do
  737. Inc(Run);
  738. end;
  739. procedure TSynLuaSyn.UnknownProc;
  740. begin
  741. {$IFDEF SYN_MBCSSUPPORT}
  742. if FLine[Run] in LeadBytes then
  743. Inc(Run,2)
  744. else
  745. {$ENDIF}
  746. inc(Run);
  747. fTokenID := tkUnknown;
  748. end;
  749. procedure TSynLuaSyn.Next;
  750. begin
  751. fTokenPos := Run;
  752. case fRange of
  753. rsLuaMComment: LuaMCommentProc;
  754. rsLuaMString: LuaMStringProc;
  755. else
  756. begin
  757. fRange := rsUnknown;
  758. fProcTable[fLine[Run]];
  759. end;
  760. end;
  761. end;
  762. function TSynLuaSyn.GetDefaultAttribute(Index: integer): TSynHighLighterAttributes;
  763. begin
  764. case Index of
  765. SYN_ATTR_COMMENT : Result := fCommentAttri;
  766. SYN_ATTR_IDENTIFIER : Result := fIdentifierAttri;
  767. SYN_ATTR_KEYWORD : Result := fKeyAttri;
  768. SYN_ATTR_STRING : Result := fStringAttri;
  769. SYN_ATTR_WHITESPACE : Result := fSpaceAttri;
  770. else
  771. Result := nil;
  772. end;
  773. end;
  774. function TSynLuaSyn.GetEol: Boolean;
  775. begin
  776. Result := fTokenID = tkNull;
  777. end;
  778. function TSynLuaSyn.GetKeyWords: string;
  779. begin
  780. Result :=
  781. 'and,break,div,do,dofile,else,elseif,end,exit,false,for,function,if,in,loa' +
  782. 'ddll,local,nil,not,or,print,repeat,return,Sleep,then,true,type,until,w' +
  783. 'hile';
  784. end;
  785. function TSynLuaSyn.GetToken: String;
  786. var
  787. Len: LongInt;
  788. begin
  789. Len := Run - fTokenPos;
  790. SetString(Result, (FLine + fTokenPos), Len);
  791. end;
  792. function TSynLuaSyn.GetTokenID: TtkTokenKind;
  793. begin
  794. Result := fTokenId;
  795. end;
  796. function TSynLuaSyn.GetTokenAttribute: TSynHighLighterAttributes;
  797. begin
  798. case GetTokenID of
  799. tkComment: Result := fCommentAttri;
  800. tkIdentifier: Result := fIdentifierAttri;
  801. tkKey: Result := fKeyAttri;
  802. tkLuaMString: Result := fLuaMStringAttri;
  803. tkNumber, tkFloat: Result := fNumberAttri;
  804. tkSpace: Result := fSpaceAttri;
  805. tkString: Result := fStringAttri;
  806. tkUnknown: Result := fIdentifierAttri;
  807. else
  808. Result := nil;
  809. end;
  810. end;
  811. function TSynLuaSyn.GetTokenKind: integer;
  812. begin
  813. Result := Ord(fTokenId);
  814. end;
  815. function TSynLuaSyn.GetTokenPos: Integer;
  816. begin
  817. Result := fTokenPos;
  818. end;
  819. function TSynLuaSyn.GetIdentChars: TSynIdentChars;
  820. begin
  821. Result := ['_', 'a'..'z', 'A'..'Z'];
  822. end;
  823. function TSynLuaSyn.GetSampleSource: string;
  824. begin
  825. Result := 'Sample source for: '#13#10 +
  826. 'Lua Syntax Parser/Highlighter';
  827. end;
  828. function TSynLuaSyn.IsFilterStored: Boolean;
  829. begin
  830. Result := fDefaultFilter <> SYNS_FilterLua;
  831. end;
  832. {$IFNDEF SYN_CPPB_1} class {$ENDIF}
  833. function TSynLuaSyn.GetLanguageName: string;
  834. begin
  835. Result := SYNS_LangLua;
  836. end;
  837. procedure TSynLuaSyn.ResetRange;
  838. begin
  839. fRange := rsUnknown;
  840. end;
  841. procedure TSynLuaSyn.SetRange(Value: Pointer);
  842. begin
  843. fRange := TRangeState(Value);
  844. end;
  845. function TSynLuaSyn.GetRange: Pointer;
  846. begin
  847. Result := Pointer(fRange);
  848. end;
  849. initialization
  850. MakeIdentTable;
  851. {$IFNDEF SYN_CPPB_1}
  852. RegisterPlaceableHighlighter(TSynLuaSyn);
  853. {$ENDIF}
  854. end.