tcscanner.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566
  1. unit tcscanner;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, typinfo, fpcunit, testregistry, pscanner;
  6. type
  7. { TTestTokenFinder }
  8. TTestTokenFinder = class(TTestCase)
  9. Published
  10. Procedure TestFind;
  11. end;
  12. { TTestStreamLineReader }
  13. TTestStreamLineReader = class(TTestCase)
  14. Private
  15. FReader: TStreamLineReader;
  16. Protected
  17. procedure NewSource(Const Source : string);
  18. Procedure TestLine(Const ALine : String; ExpectEOF : Boolean = True);
  19. procedure TearDown; override;
  20. Published
  21. Procedure TestCreate;
  22. Procedure TestEOF;
  23. Procedure TestEmptyLine;
  24. Procedure TestEmptyLineCR;
  25. Procedure TestEmptyLineLF;
  26. Procedure TestEmptyLineCRLF;
  27. Procedure TestEmptyLineLFCR;
  28. Procedure TestOneLine;
  29. Procedure TestTwoLines;
  30. end;
  31. { TTestingPascalScanner }
  32. TTestingPascalScanner = Class(TPascalScanner)
  33. private
  34. FDoSpecial: Boolean;
  35. protected
  36. function HandleMacro(AIndex: integer): TToken;override;
  37. Public
  38. Property DoSpecial : Boolean Read FDoSpecial Write FDoSpecial;
  39. end;
  40. { TTestScanner }
  41. TTestScanner= class(TTestCase)
  42. Private
  43. FLI: String;
  44. FScanner : TPascalScanner;
  45. FResolver : TStreamResolver;
  46. protected
  47. procedure SetUp; override;
  48. procedure TearDown; override;
  49. Function TokenToString(tk : TToken) : string;
  50. Procedure AssertEquals(Msg : String; Expected,Actual : TToken); overload;
  51. Procedure AssertEquals(Msg : String; Expected,Actual : TModeSwitch); overload;
  52. Procedure AssertEquals(Msg : String; Expected,Actual : TModeSwitches); overload;
  53. procedure NewSource(Const Source : string; DoClear : Boolean = True);
  54. Procedure DoTestToken(t : TToken; Const ASource : String; Const CheckEOF : Boolean = True);
  55. Procedure TestToken(t : TToken; Const ASource : String; Const CheckEOF : Boolean = True);
  56. Procedure TestTokens(t : array of TToken; Const ASource : String; Const CheckEOF : Boolean = True;Const DoClear : Boolean = True);
  57. Property LastIDentifier : String Read FLI Write FLi;
  58. Property Scanner : TPascalScanner Read FScanner;
  59. published
  60. Procedure TestEmpty;
  61. procedure TestEOF;
  62. procedure TestWhitespace;
  63. procedure TestComment1;
  64. procedure TestComment2;
  65. procedure TestComment3;
  66. procedure TestComment4;
  67. procedure TestComment5;
  68. procedure TestNestedComment1;
  69. procedure TestNestedComment2;
  70. procedure TestNestedComment3;
  71. procedure TestNestedComment4;
  72. procedure TestNestedComment5;
  73. procedure TestIdentifier;
  74. procedure TestSelf;
  75. procedure TestSelfNoToken;
  76. procedure TestString;
  77. procedure TestNumber;
  78. procedure TestChar;
  79. procedure TestCharString;
  80. procedure TestBraceOpen;
  81. procedure TestBraceClose;
  82. procedure TestMul;
  83. procedure TestPlus;
  84. procedure TestComma;
  85. procedure TestMinus;
  86. procedure TestDot;
  87. procedure TestDivision;
  88. procedure TestColon;
  89. procedure TestSemicolon;
  90. procedure TestLessThan;
  91. procedure TestEqual;
  92. procedure TestGreaterThan;
  93. procedure TestAt;
  94. procedure TestSquaredBraceOpen;
  95. procedure TestSquaredBraceClose;
  96. procedure TestCaret;
  97. procedure TestBackslash;
  98. procedure TestDotDot;
  99. procedure TestAssign;
  100. procedure TestAssignPlus;
  101. procedure TestAssignMinus;
  102. procedure TestAssignMul;
  103. procedure TestAssignDivision;
  104. procedure TestNotEqual;
  105. procedure TestLessEqualThan;
  106. procedure TestGreaterEqualThan;
  107. procedure TestPower;
  108. procedure TestSymmetricalDifference;
  109. procedure TestAbsolute;
  110. procedure TestAnd;
  111. procedure TestArray;
  112. procedure TestAs;
  113. procedure TestAsm;
  114. procedure TestBegin;
  115. procedure TestBitpacked;
  116. procedure TestCase;
  117. procedure TestClass;
  118. procedure TestConst;
  119. procedure TestConstructor;
  120. procedure TestDestructor;
  121. procedure TestDispinterface;
  122. procedure TestDiv;
  123. procedure TestDo;
  124. procedure TestDownto;
  125. procedure TestElse;
  126. procedure TestEnd;
  127. procedure TestExcept;
  128. procedure TestExports;
  129. procedure TestFalse;
  130. procedure TestFile;
  131. procedure TestFinalization;
  132. procedure TestFinally;
  133. procedure TestFor;
  134. procedure TestFunction;
  135. procedure TestGeneric;
  136. procedure TestGoto;
  137. Procedure TestHelper;
  138. procedure TestIf;
  139. procedure TestImplementation;
  140. procedure TestIn;
  141. procedure TestInherited;
  142. procedure TestInitialization;
  143. procedure TestInline;
  144. procedure TestInterface;
  145. procedure TestIs;
  146. procedure TestLabel;
  147. procedure TestLibrary;
  148. procedure TestMod;
  149. procedure TestNil;
  150. procedure TestNot;
  151. procedure TestObject;
  152. procedure TestOf;
  153. procedure TestOn;
  154. procedure TestOperator;
  155. procedure TestOr;
  156. procedure TestPacked;
  157. procedure TestProcedure;
  158. procedure TestProgram;
  159. procedure TestProperty;
  160. procedure TestRaise;
  161. procedure TestRecord;
  162. procedure TestRepeat;
  163. procedure TestResourceString;
  164. procedure TestSet;
  165. procedure TestShl;
  166. procedure TestShr;
  167. procedure TestShlC;
  168. procedure TestShrC;
  169. procedure TestSpecialize;
  170. procedure TestThen;
  171. procedure TestThreadvar;
  172. procedure TestTo;
  173. procedure TestTrue;
  174. procedure TestTry;
  175. procedure TestType;
  176. procedure TestUnit;
  177. procedure TestUntil;
  178. procedure TestUses;
  179. procedure TestVar;
  180. procedure TestWhile;
  181. procedure TestWith;
  182. procedure TestXor;
  183. procedure TestLineEnding;
  184. procedure TestTab;
  185. Procedure TestEscapedKeyWord;
  186. Procedure TestTokenSeries;
  187. Procedure TestTokenSeriesNoWhiteSpace;
  188. Procedure TestTokenSeriesComments;
  189. Procedure TestTokenSeriesNoComments;
  190. Procedure TestDefine0;
  191. procedure TestDefine01;
  192. Procedure TestDefine1;
  193. Procedure TestDefine2;
  194. Procedure TestDefine21;
  195. procedure TestDefine22;
  196. Procedure TestDefine3;
  197. Procedure TestDefine4;
  198. Procedure TestDefine5;
  199. Procedure TestDefine6;
  200. Procedure TestDefine7;
  201. Procedure TestDefine8;
  202. Procedure TestDefine9;
  203. Procedure TestDefine10;
  204. Procedure TestDefine11;
  205. Procedure TestDefine12;
  206. Procedure TestDefine13;
  207. Procedure TestDefine14;
  208. Procedure TestInclude;
  209. Procedure TestInclude2;
  210. Procedure TestUnDefine1;
  211. Procedure TestMacro1;
  212. procedure TestMacro2;
  213. procedure TestMacro3;
  214. procedure TestMacroHandling;
  215. Procedure TestModeSwitch;
  216. end;
  217. implementation
  218. { TTestingPascalScanner }
  219. function TTestingPascalScanner.HandleMacro(AIndex: integer): TToken;
  220. begin
  221. if DoSpecial then
  222. begin
  223. Result:=tkIdentifier;
  224. SetCurTokenstring('somethingweird');
  225. end
  226. else
  227. Result:=inherited HandleMacro(AIndex);
  228. end;
  229. { TTestTokenFinder }
  230. procedure TTestTokenFinder.TestFind;
  231. Var
  232. tk,tkr : TToken;
  233. S : string;
  234. B : Boolean;
  235. begin
  236. For tk:=tkAbsolute to tkXor do
  237. begin
  238. S:=tokenInfos[tk];
  239. B:=IsNamedToken(S,tkr);
  240. AssertEquals('Token '+S+' is a token',true,B);
  241. AssertEquals('Token '+S+' returns correct token',Ord(tk),Ord(tkr));
  242. end;
  243. end;
  244. { TTestStreamLineReader }
  245. procedure TTestStreamLineReader.NewSource(Const Source: string);
  246. begin
  247. FReader:=TStringStreamLineReader.Create('afile',Source);
  248. end;
  249. procedure TTestStreamLineReader.TestLine(const ALine: String; ExpectEOF: Boolean);
  250. begin
  251. AssertNotNull('Have reader',FReader);
  252. AssertEquals('Reading source line',ALine,FReader.ReadLine);
  253. if ExpectEOF then
  254. AssertEquals('End of file reached',True,FReader.IsEOF);
  255. end;
  256. procedure TTestStreamLineReader.TearDown;
  257. begin
  258. inherited TearDown;
  259. If Assigned(FReader) then
  260. FreeAndNil(Freader);
  261. end;
  262. procedure TTestStreamLineReader.TestCreate;
  263. begin
  264. FReader:=TStreamLineReader.Create('afile');
  265. AssertEquals('Correct filename','afile',FReader.FileName);
  266. AssertEquals('Initially empty',True,FReader.isEOF);
  267. end;
  268. procedure TTestStreamLineReader.TestEOF;
  269. begin
  270. NewSource('');
  271. AssertEquals('Empty stream',True,FReader.IsEOF);
  272. end;
  273. procedure TTestStreamLineReader.TestEmptyLine;
  274. begin
  275. NewSource('');
  276. TestLine('');
  277. end;
  278. procedure TTestStreamLineReader.TestEmptyLineCR;
  279. begin
  280. NewSource(#13);
  281. TestLine('');
  282. end;
  283. procedure TTestStreamLineReader.TestEmptyLineLF;
  284. begin
  285. NewSource(#10);
  286. TestLine('');
  287. end;
  288. procedure TTestStreamLineReader.TestEmptyLineCRLF;
  289. begin
  290. NewSource(#13#10);
  291. TestLine('');
  292. end;
  293. procedure TTestStreamLineReader.TestEmptyLineLFCR;
  294. begin
  295. NewSource(#10#13);
  296. TestLine('',False);
  297. TestLine('');
  298. end;
  299. procedure TTestStreamLineReader.TestOneLine;
  300. Const
  301. S = 'a line with text';
  302. begin
  303. NewSource(S);
  304. TestLine(S);
  305. end;
  306. procedure TTestStreamLineReader.TestTwoLines;
  307. Const
  308. S = 'a line with text';
  309. begin
  310. NewSource(S+sLineBreak+S);
  311. TestLine(S,False);
  312. TestLine(S);
  313. end;
  314. { ---------------------------------------------------------------------
  315. TTestScanner
  316. ---------------------------------------------------------------------}
  317. procedure TTestScanner.SetUp;
  318. begin
  319. FResolver:=TStreamResolver.Create;
  320. FResolver.OwnsStreams:=True;
  321. FScanner:=TTestingPascalScanner.Create(FResolver);
  322. // Do nothing
  323. end;
  324. procedure TTestScanner.TearDown;
  325. begin
  326. FreeAndNil(FScanner);
  327. FreeAndNil(FResolver);
  328. end;
  329. function TTestScanner.TokenToString(tk: TToken): string;
  330. begin
  331. Result:=GetEnumName(TypeInfo(TToken),Ord(tk));
  332. end;
  333. procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TToken);
  334. begin
  335. AssertEquals(Msg,TokenToString(Expected),TokenToString(Actual));
  336. end;
  337. procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TModeSwitch);
  338. begin
  339. AssertEquals(Msg,GetEnumName(TypeInfo(TModeSwitch),Ord(Expected)),
  340. GetEnumName(TypeInfo(TModeSwitch),Ord(Actual)))
  341. end;
  342. procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TModeSwitches);
  343. Function ToString(S : TModeSwitches) : String;
  344. Var
  345. M : TModeSwitch;
  346. begin
  347. Result:='';
  348. For M in TModeswitch do
  349. if M in S then
  350. begin
  351. If (Result<>'') then
  352. Result:=Result+', ';
  353. Result:=Result+GetEnumName(TypeInfo(TModeSwitch), Ord(M));
  354. end;
  355. end;
  356. begin
  357. AssertEquals(Msg,ToString(Expected),ToString(Actual));
  358. end;
  359. procedure TTestScanner.NewSource(const Source: string; DoClear : Boolean = True);
  360. begin
  361. if DoClear then
  362. FResolver.Clear;
  363. FResolver.AddStream('afile.pp',TStringStream.Create(Source));
  364. Writeln('// '+TestName);
  365. Writeln(Source);
  366. // FreeAndNil(FScanner);
  367. // FScanner:=TTestingPascalScanner.Create(FResolver);
  368. FScanner.OpenFile('afile.pp');
  369. end;
  370. procedure TTestScanner.DoTestToken(t: TToken; const ASource: String;
  371. const CheckEOF: Boolean);
  372. Var
  373. tk : ttoken;
  374. begin
  375. NewSource(ASource);
  376. tk:=FScanner.FetchToken;
  377. AssertEquals('Read token equals expected token.',t,tk);
  378. if CheckEOF then
  379. begin
  380. tk:=FScanner.FetchToken;
  381. if (tk=tkLineEnding) and not (t in [tkEOF,tkLineEnding]) then
  382. tk:=FScanner.FetchToken;
  383. AssertEquals('EOF reached.',tkEOF,FScanner.FetchToken);
  384. end
  385. end;
  386. procedure TTestScanner.TestToken(t: TToken; const ASource: String;
  387. const CheckEOF: Boolean);
  388. Var
  389. S : String;
  390. begin
  391. DoTestToken(t,ASource);
  392. if (ASource<>'') then
  393. begin
  394. S:=ASource;
  395. S[1]:=Upcase(S[1]);
  396. DoTestToken(t,S);
  397. end;
  398. DoTestToken(t,UpperCase(ASource));
  399. DoTestToken(t,LowerCase(ASource));
  400. end;
  401. procedure TTestScanner.TestTokens(t: array of TToken; const ASource: String;
  402. const CheckEOF: Boolean; const DoClear: Boolean);
  403. Var
  404. tk : ttoken;
  405. i : integer;
  406. begin
  407. NewSource(ASource,DoClear);
  408. For I:=Low(t) to High(t) do
  409. begin
  410. tk:=FScanner.FetchToken;
  411. AssertEquals(Format('Read token %d equals expected token.',[i]),t[i],tk);
  412. if tk=tkIdentifier then
  413. LastIdentifier:=FScanner.CurtokenString;
  414. end;
  415. if CheckEOF then
  416. begin
  417. tk:=FScanner.FetchToken;
  418. if (tk=tkLineEnding) then
  419. tk:=FScanner.FetchToken;
  420. AssertEquals('EOF reached.',tkEOF,FScanner.FetchToken);
  421. end;
  422. end;
  423. procedure TTestScanner.TestEmpty;
  424. begin
  425. AssertNotNull('Have Scanner',Scanner);
  426. AssertTrue('Options is empty',[]=Scanner.Options);
  427. AssertEquals('FPC modes is default',FPCModeSwitches,Scanner.CurrentModeSwitches);
  428. end;
  429. procedure TTestScanner.TestEOF;
  430. begin
  431. TestToken(tkEOF,'')
  432. end;
  433. procedure TTestScanner.TestWhitespace;
  434. begin
  435. TestToken(tkWhitespace,' ');
  436. TestToken(tkWhitespace,' ');
  437. end;
  438. procedure TTestScanner.TestComment1;
  439. begin
  440. TestToken(tkComment,'{ comment }');
  441. end;
  442. procedure TTestScanner.TestComment2;
  443. begin
  444. TestToken(tkComment,'(* comment *)');
  445. end;
  446. procedure TTestScanner.TestComment3;
  447. begin
  448. TestToken(tkComment,'//');
  449. end;
  450. procedure TTestScanner.TestComment4;
  451. begin
  452. DoTestToken(tkComment,'(* abc *)',False);
  453. AssertEquals('Correct comment',' abc ',Scanner.CurTokenString);
  454. end;
  455. procedure TTestScanner.TestComment5;
  456. begin
  457. DoTestToken(tkComment,'(* abc'+LineEnding+'def *)',False);
  458. AssertEquals('Correct comment',' abc'+LineEnding+'def ',Scanner.CurTokenString);
  459. end;
  460. procedure TTestScanner.TestNestedComment1;
  461. begin
  462. TestToken(tkComment,'// { comment } ');
  463. end;
  464. procedure TTestScanner.TestNestedComment2;
  465. begin
  466. TestToken(tkComment,'(* { comment } *)');
  467. end;
  468. procedure TTestScanner.TestNestedComment3;
  469. begin
  470. TestToken(tkComment,'{ { comment } }');
  471. end;
  472. procedure TTestScanner.TestNestedComment4;
  473. begin
  474. TestToken(tkComment,'{ (* comment *) }');
  475. end;
  476. procedure TTestScanner.TestNestedComment5;
  477. begin
  478. TestToken(tkComment,'(* (* comment *) *)');
  479. end;
  480. procedure TTestScanner.TestIdentifier;
  481. begin
  482. TestToken(tkIdentifier,'identifier');
  483. end;
  484. procedure TTestScanner.TestString;
  485. begin
  486. TestToken(pscanner.tkString,'''A string''');
  487. end;
  488. procedure TTestScanner.TestCharString;
  489. begin
  490. TestToken(pscanner.tkChar,'''A''');
  491. end;
  492. procedure TTestScanner.TestNumber;
  493. begin
  494. TestToken(tkNumber,'123');
  495. end;
  496. procedure TTestScanner.TestChar;
  497. begin
  498. TestToken(pscanner.tkChar,'#65 ', false);
  499. end;
  500. procedure TTestScanner.TestBraceOpen;
  501. begin
  502. TestToken(tkBraceOpen,'(');
  503. end;
  504. procedure TTestScanner.TestBraceClose;
  505. begin
  506. TestToken(tkBraceClose,')');
  507. end;
  508. procedure TTestScanner.TestMul;
  509. begin
  510. TestToken(tkMul,'*');
  511. end;
  512. procedure TTestScanner.TestPlus;
  513. begin
  514. TestToken(tkPlus,'+');
  515. end;
  516. procedure TTestScanner.TestComma;
  517. begin
  518. TestToken(tkComma,',');
  519. end;
  520. procedure TTestScanner.TestMinus;
  521. begin
  522. TestToken(tkMinus,'-');
  523. end;
  524. procedure TTestScanner.TestDot;
  525. begin
  526. TestToken(tkDot,'.');
  527. end;
  528. procedure TTestScanner.TestDivision;
  529. begin
  530. TestToken(tkDivision,'/');
  531. end;
  532. procedure TTestScanner.TestColon;
  533. begin
  534. TestToken(tkColon,':');
  535. end;
  536. procedure TTestScanner.TestSemicolon;
  537. begin
  538. TestToken(tkSemicolon,';');
  539. end;
  540. procedure TTestScanner.TestLessThan;
  541. begin
  542. TestToken(tkLessThan,'<');
  543. end;
  544. procedure TTestScanner.TestEqual;
  545. begin
  546. TestToken(tkEqual,'=');
  547. end;
  548. procedure TTestScanner.TestGreaterThan;
  549. begin
  550. TestToken(tkGreaterThan,'>');
  551. end;
  552. procedure TTestScanner.TestAt;
  553. begin
  554. TestToken(tkAt,'@');
  555. end;
  556. procedure TTestScanner.TestSquaredBraceOpen;
  557. begin
  558. TestToken(tkSquaredBraceOpen,'[');
  559. end;
  560. procedure TTestScanner.TestSquaredBraceClose;
  561. begin
  562. TestToken(tkSquaredBraceClose,']');
  563. end;
  564. procedure TTestScanner.TestCaret;
  565. begin
  566. TestToken(tkCaret,'^');
  567. end;
  568. procedure TTestScanner.TestBackslash;
  569. begin
  570. TestToken(tkBackslash,'\');
  571. end;
  572. procedure TTestScanner.TestDotDot;
  573. begin
  574. TestToken(tkDotDot,'..');
  575. end;
  576. procedure TTestScanner.TestAssign;
  577. begin
  578. TestToken(tkAssign,':=');
  579. end;
  580. procedure TTestScanner.TestAssignPlus;
  581. begin
  582. TestTokens([tkPlus,tkEqual],'+=');
  583. FScanner.Options:=[po_cassignments];
  584. TestToken(tkAssignPlus,'+=');
  585. end;
  586. procedure TTestScanner.TestAssignMinus;
  587. begin
  588. TestTokens([tkMinus,tkEqual],'-=');
  589. FScanner.Options:=[po_cassignments];
  590. TestToken(tkAssignMinus,'-=');
  591. end;
  592. procedure TTestScanner.TestAssignMul;
  593. begin
  594. TestTokens([tkMul,tkEqual],'*=');
  595. FScanner.Options:=[po_cassignments];
  596. TestToken(tkAssignMul,'*=');
  597. end;
  598. procedure TTestScanner.TestAssignDivision;
  599. begin
  600. TestTokens([tkDivision,tkEqual],'/=');
  601. FScanner.Options:=[po_cassignments];
  602. TestToken(tkAssignDivision,'/=');
  603. end;
  604. procedure TTestScanner.TestNotEqual;
  605. begin
  606. TestToken(tkNotEqual,'<>');
  607. end;
  608. procedure TTestScanner.TestLessEqualThan;
  609. begin
  610. TestToken(tkLessEqualThan,'<=');
  611. end;
  612. procedure TTestScanner.TestGreaterEqualThan;
  613. begin
  614. TestToken(tkGreaterEqualThan,'>=');
  615. end;
  616. procedure TTestScanner.TestPower;
  617. begin
  618. TestToken(tkPower,'**');
  619. end;
  620. procedure TTestScanner.TestSymmetricalDifference;
  621. begin
  622. TestToken(tkSymmetricalDifference,'><');
  623. end;
  624. procedure TTestScanner.TestAbsolute;
  625. begin
  626. TestToken(tkabsolute,'absolute');
  627. end;
  628. procedure TTestScanner.TestAnd;
  629. begin
  630. TestToken(tkand,'and');
  631. end;
  632. procedure TTestScanner.TestArray;
  633. begin
  634. TestToken(tkarray,'array');
  635. end;
  636. procedure TTestScanner.TestAs;
  637. begin
  638. TestToken(tkas,'as');
  639. end;
  640. procedure TTestScanner.TestAsm;
  641. begin
  642. TestToken(tkasm,'asm');
  643. end;
  644. procedure TTestScanner.TestBegin;
  645. begin
  646. TestToken(tkbegin,'begin');
  647. end;
  648. procedure TTestScanner.TestBitpacked;
  649. begin
  650. TestToken(tkbitpacked,'bitpacked');
  651. end;
  652. procedure TTestScanner.TestCase;
  653. begin
  654. TestToken(tkcase,'case');
  655. end;
  656. procedure TTestScanner.TestClass;
  657. begin
  658. TestToken(tkclass,'class');
  659. end;
  660. procedure TTestScanner.TestConst;
  661. begin
  662. TestToken(tkconst,'const');
  663. end;
  664. procedure TTestScanner.TestConstructor;
  665. begin
  666. TestToken(tkconstructor,'constructor');
  667. end;
  668. procedure TTestScanner.TestDestructor;
  669. begin
  670. TestToken(tkdestructor,'destructor');
  671. end;
  672. procedure TTestScanner.TestDispinterface;
  673. begin
  674. TestToken(tkdispinterface,'dispinterface');
  675. end;
  676. procedure TTestScanner.TestDiv;
  677. begin
  678. TestToken(tkdiv,'div');
  679. end;
  680. procedure TTestScanner.TestDo;
  681. begin
  682. TestToken(tkdo,'do');
  683. end;
  684. procedure TTestScanner.TestDownto;
  685. begin
  686. TestToken(tkdownto,'downto');
  687. end;
  688. procedure TTestScanner.TestElse;
  689. begin
  690. TestToken(tkelse,'else');
  691. end;
  692. procedure TTestScanner.TestEnd;
  693. begin
  694. TestToken(tkend,'end');
  695. end;
  696. procedure TTestScanner.TestExcept;
  697. begin
  698. TestToken(tkexcept,'except');
  699. end;
  700. procedure TTestScanner.TestExports;
  701. begin
  702. TestToken(tkexports,'exports');
  703. end;
  704. procedure TTestScanner.TestFalse;
  705. begin
  706. TestToken(tkfalse,'false');
  707. end;
  708. procedure TTestScanner.TestFile;
  709. begin
  710. TestToken(tkfile,'file');
  711. end;
  712. procedure TTestScanner.TestFinalization;
  713. begin
  714. TestToken(tkfinalization,'finalization');
  715. end;
  716. procedure TTestScanner.TestFinally;
  717. begin
  718. TestToken(tkfinally,'finally');
  719. end;
  720. procedure TTestScanner.TestFor;
  721. begin
  722. TestToken(tkfor,'for');
  723. end;
  724. procedure TTestScanner.TestFunction;
  725. begin
  726. TestToken(tkfunction,'function');
  727. end;
  728. procedure TTestScanner.TestGeneric;
  729. begin
  730. TestToken(tkgeneric,'generic');
  731. end;
  732. procedure TTestScanner.TestGoto;
  733. begin
  734. TestToken(tkgoto,'goto');
  735. end;
  736. procedure TTestScanner.TestHelper;
  737. begin
  738. TestToken(tkIdentifier,'helper');
  739. end;
  740. procedure TTestScanner.TestIf;
  741. begin
  742. TestToken(tkif,'if');
  743. end;
  744. procedure TTestScanner.TestImplementation;
  745. begin
  746. TestToken(tkimplementation,'implementation');
  747. end;
  748. procedure TTestScanner.TestIn;
  749. begin
  750. TestToken(tkin,'in');
  751. end;
  752. procedure TTestScanner.TestInherited;
  753. begin
  754. TestToken(tkinherited,'inherited');
  755. end;
  756. procedure TTestScanner.TestInitialization;
  757. begin
  758. TestToken(tkinitialization,'initialization');
  759. end;
  760. procedure TTestScanner.TestInline;
  761. begin
  762. TestToken(tkinline,'inline');
  763. end;
  764. procedure TTestScanner.TestInterface;
  765. begin
  766. TestToken(tkinterface,'interface');
  767. end;
  768. procedure TTestScanner.TestIs;
  769. begin
  770. TestToken(tkis,'is');
  771. end;
  772. procedure TTestScanner.TestLabel;
  773. begin
  774. TestToken(tklabel,'label');
  775. end;
  776. procedure TTestScanner.TestLibrary;
  777. begin
  778. TestToken(tklibrary,'library');
  779. end;
  780. procedure TTestScanner.TestMod;
  781. begin
  782. TestToken(tkmod,'mod');
  783. end;
  784. procedure TTestScanner.TestNil;
  785. begin
  786. TestToken(tknil,'nil');
  787. end;
  788. procedure TTestScanner.TestNot;
  789. begin
  790. TestToken(tknot,'not');
  791. end;
  792. procedure TTestScanner.TestObject;
  793. begin
  794. TestToken(tkobject,'object');
  795. end;
  796. procedure TTestScanner.TestOf;
  797. begin
  798. TestToken(tkof,'of');
  799. end;
  800. procedure TTestScanner.TestOn;
  801. begin
  802. TestToken(tkon,'on');
  803. end;
  804. procedure TTestScanner.TestOperator;
  805. begin
  806. TestToken(tkoperator,'operator');
  807. end;
  808. procedure TTestScanner.TestOr;
  809. begin
  810. TestToken(tkor,'or');
  811. end;
  812. procedure TTestScanner.TestPacked;
  813. begin
  814. TestToken(tkpacked,'packed');
  815. end;
  816. procedure TTestScanner.TestProcedure;
  817. begin
  818. TestToken(tkprocedure,'procedure');
  819. end;
  820. procedure TTestScanner.TestProgram;
  821. begin
  822. TestToken(tkprogram,'program');
  823. end;
  824. procedure TTestScanner.TestProperty;
  825. begin
  826. TestToken(tkproperty,'property');
  827. end;
  828. procedure TTestScanner.TestRaise;
  829. begin
  830. TestToken(tkraise,'raise');
  831. end;
  832. procedure TTestScanner.TestRecord;
  833. begin
  834. TestToken(tkrecord,'record');
  835. end;
  836. procedure TTestScanner.TestRepeat;
  837. begin
  838. TestToken(tkrepeat,'repeat');
  839. end;
  840. procedure TTestScanner.TestResourceString;
  841. begin
  842. TestToken(tkResourceString,'resourcestring');
  843. end;
  844. procedure TTestScanner.TestSelf;
  845. begin
  846. FScanner.Options:=FScanner.Options + [po_selftoken];
  847. TestToken(tkself,'self');
  848. end;
  849. procedure TTestScanner.TestSelfNoToken;
  850. begin
  851. TestToken(tkIdentifier,'self');
  852. end;
  853. procedure TTestScanner.TestSet;
  854. begin
  855. TestToken(tkset,'set');
  856. end;
  857. procedure TTestScanner.TestShl;
  858. begin
  859. TestToken(tkshl,'shl');
  860. end;
  861. procedure TTestScanner.TestShr;
  862. begin
  863. TestToken(tkshr,'shr');
  864. end;
  865. procedure TTestScanner.TestShlC;
  866. begin
  867. TestToken(tkshl,'<<');
  868. end;
  869. procedure TTestScanner.TestShrC;
  870. begin
  871. TestToken(tkshr,'>>');
  872. end;
  873. procedure TTestScanner.TestSpecialize;
  874. begin
  875. TestToken(tkspecialize,'specialize');
  876. end;
  877. procedure TTestScanner.TestThen;
  878. begin
  879. TestToken(tkthen,'then');
  880. end;
  881. procedure TTestScanner.TestThreadvar;
  882. begin
  883. TestToken(tkthreadvar,'threadvar');
  884. end;
  885. procedure TTestScanner.TestTo;
  886. begin
  887. TestToken(tkto,'to');
  888. end;
  889. procedure TTestScanner.TestTrue;
  890. begin
  891. TestToken(tktrue,'true');
  892. end;
  893. procedure TTestScanner.TestTry;
  894. begin
  895. TestToken(tktry,'try');
  896. end;
  897. procedure TTestScanner.TestType;
  898. begin
  899. TestToken(tktype,'type');
  900. end;
  901. procedure TTestScanner.TestUnit;
  902. begin
  903. TestToken(tkunit,'unit');
  904. end;
  905. procedure TTestScanner.TestUntil;
  906. begin
  907. TestToken(tkuntil,'until');
  908. end;
  909. procedure TTestScanner.TestUses;
  910. begin
  911. TestToken(tkuses,'uses');
  912. end;
  913. procedure TTestScanner.TestVar;
  914. begin
  915. TestToken(tkvar,'var');
  916. end;
  917. procedure TTestScanner.TestWhile;
  918. begin
  919. TestToken(tkwhile,'while');
  920. end;
  921. procedure TTestScanner.TestWith;
  922. begin
  923. TestToken(tkwith,'with');
  924. end;
  925. procedure TTestScanner.TestXor;
  926. begin
  927. TestToken(tkxor,'xor');
  928. end;
  929. procedure TTestScanner.TestLineEnding;
  930. begin
  931. TestToken(tkLineEnding,#10);
  932. end;
  933. procedure TTestScanner.TestTab;
  934. begin
  935. TestToken(tkTab,#9);
  936. end;
  937. procedure TTestScanner.TestEscapedKeyWord;
  938. begin
  939. TestToken(tkIdentifier,'&xor');
  940. end;
  941. procedure TTestScanner.TestTokenSeries;
  942. begin
  943. TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkthen,tkWhiteSpace,tkIdentifier],'in of then aninteger')
  944. end;
  945. procedure TTestScanner.TestTokenSeriesNoWhiteSpace;
  946. begin
  947. FScanner.SkipWhiteSpace:=True;
  948. TestTokens([tkin,tkOf,tkthen,tkIdentifier],'in of then aninteger')
  949. end;
  950. procedure TTestScanner.TestTokenSeriesComments;
  951. begin
  952. TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkComment,tkWhiteSpace,tkIdentifier],'in of {then} aninteger')
  953. end;
  954. procedure TTestScanner.TestTokenSeriesNoComments;
  955. begin
  956. FScanner.SkipComments:=True;
  957. TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkWhiteSpace,tkIdentifier],'in of {then} aninteger')
  958. end;
  959. procedure TTestScanner.TestDefine0;
  960. begin
  961. TestTokens([tkComment],'{$DEFINE NEVER}');
  962. If FSCanner.Defines.IndexOf('NEVER')=-1 then
  963. Fail('Define not defined');
  964. end;
  965. procedure TTestScanner.TestDefine01;
  966. begin
  967. TestTokens([tkComment],'(*$DEFINE NEVER*)');
  968. If FSCanner.Defines.IndexOf('NEVER')=-1 then
  969. Fail('Define not defined');
  970. end;
  971. procedure TTestScanner.TestDefine1;
  972. begin
  973. TestTokens([tkComment],'{$IFDEF NEVER} of {$ENDIF}');
  974. end;
  975. procedure TTestScanner.TestDefine2;
  976. begin
  977. FSCanner.Defines.Add('ALWAYS');
  978. TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ENDIF}');
  979. end;
  980. procedure TTestScanner.TestDefine21;
  981. begin
  982. FSCanner.Defines.Add('ALWAYS');
  983. TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'(*$IFDEF ALWAYS*) of (*$ENDIF*)');
  984. end;
  985. procedure TTestScanner.TestDefine22;
  986. begin
  987. FSCanner.Defines.Add('ALWAYS');
  988. // No whitespace. Test border of *)
  989. TestTokens([tkComment,tkOf,tkWhitespace,tkcomment],'(*$IFDEF ALWAYS*)of (*$ENDIF*)');
  990. end;
  991. procedure TTestScanner.TestDefine3;
  992. begin
  993. FSCanner.Defines.Add('ALWAYS');
  994. TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  995. end;
  996. procedure TTestScanner.TestDefine4;
  997. begin
  998. TestTokens([tkComment,tkWhitespace,tkin,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  999. end;
  1000. procedure TTestScanner.TestDefine5;
  1001. begin
  1002. FScanner.SkipComments:=True;
  1003. TestTokens([tkLineEnding],'{$IFDEF NEVER} of {$ENDIF}');
  1004. end;
  1005. procedure TTestScanner.TestDefine6;
  1006. begin
  1007. FSCanner.Defines.Add('ALWAYS');
  1008. FScanner.SkipComments:=True;
  1009. TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ENDIF}');
  1010. end;
  1011. procedure TTestScanner.TestDefine7;
  1012. begin
  1013. FSCanner.Defines.Add('ALWAYS');
  1014. FScanner.SkipComments:=True;
  1015. TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1016. end;
  1017. procedure TTestScanner.TestDefine8;
  1018. begin
  1019. FScanner.SkipComments:=True;
  1020. TestTokens([tkWhitespace,tkin,tkWhitespace],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1021. end;
  1022. procedure TTestScanner.TestDefine9;
  1023. begin
  1024. FScanner.SkipWhiteSpace:=True;
  1025. TestTokens([],'{$IFDEF NEVER} of {$ENDIF}');
  1026. end;
  1027. procedure TTestScanner.TestDefine10;
  1028. begin
  1029. FSCanner.Defines.Add('ALWAYS');
  1030. FScanner.SkipComments:=True;
  1031. TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ENDIF}');
  1032. end;
  1033. procedure TTestScanner.TestDefine11;
  1034. begin
  1035. FSCanner.Defines.Add('ALWAYS');
  1036. FScanner.SkipComments:=True;
  1037. FScanner.SkipWhiteSpace:=True;
  1038. TestTokens([tkOf],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1039. end;
  1040. procedure TTestScanner.TestDefine12;
  1041. begin
  1042. FScanner.SkipComments:=True;
  1043. FScanner.SkipWhiteSpace:=True;
  1044. TestTokens([tkin],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1045. end;
  1046. procedure TTestScanner.TestDefine13;
  1047. begin
  1048. FScanner.SkipComments:=True;
  1049. FScanner.SkipWhiteSpace:=True;
  1050. TestTokens([tkin],'{$IFDEF ALWAYS} }; ą è {$ELSE} in {$ENDIF}');
  1051. end;
  1052. procedure TTestScanner.TestDefine14;
  1053. Const
  1054. Source = '{$ifdef NEVER_DEFINED}' +sLineBreak+
  1055. 'type'+sLineBreak+
  1056. ' TNPEventModel = ('+sLineBreak+
  1057. ' NPEventModelCarbon = 0,'+sLineBreak+
  1058. ' NPEventModelCocoa = 1'+sLineBreak+
  1059. '}; // yes, this is an error... except this code should never be included.'+sLineBreak+
  1060. 'ą'+sLineBreak+
  1061. '|'+sLineBreak+
  1062. '{$endif}'+sLineBreak+
  1063. ''+sLineBreak+
  1064. 'begin'+sLineBreak+
  1065. 'end.'+sLineBreak;
  1066. begin
  1067. NewSource(Source,True);
  1068. While FScanner.fetchToken<>tkEOF do
  1069. end;
  1070. procedure TTestScanner.TestInclude;
  1071. begin
  1072. FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
  1073. FScanner.SkipWhiteSpace:=True;
  1074. FScanner.SkipComments:=True;
  1075. TestTokens([tkIf,tkTrue,tkThen],'{$I myinclude.inc}',True,False);
  1076. end;
  1077. procedure TTestScanner.TestInclude2;
  1078. begin
  1079. FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
  1080. FScanner.SkipWhiteSpace:=True;
  1081. FScanner.SkipComments:=True;
  1082. TestTokens([tkIf,tkTrue,tkThen,tkElse],'{$I myinclude.inc} else',True,False);
  1083. end;
  1084. procedure TTestScanner.TestUnDefine1;
  1085. begin
  1086. FSCanner.Defines.Add('ALWAYS');
  1087. TestTokens([tkComment],'{$UNDEF ALWAYS}');
  1088. AssertEquals('No more define',-1,FScanner.Defines.INdexOf('ALWAYS'));
  1089. end;
  1090. procedure TTestScanner.TestMacro1;
  1091. begin
  1092. FScanner.SkipWhiteSpace:=True;
  1093. FScanner.SkipComments:=True;
  1094. TestTokens([tkbegin,tkend,tkDot],'{$DEFINE MM:=begin end.}'#13#10'MM',True,False);
  1095. end;
  1096. procedure TTestScanner.TestMacro2;
  1097. begin
  1098. FScanner.SkipWhiteSpace:=True;
  1099. FScanner.SkipComments:=True;
  1100. TestTokens([tkbegin,tkend,tkDot],'{$DEFINE MM:=begin end}'#13#10'MM .',True,False);
  1101. end;
  1102. procedure TTestScanner.TestMacro3;
  1103. begin
  1104. FScanner.SkipComments:=True;
  1105. FScanner.SkipWhiteSpace:=True;
  1106. TestTokens([tkof],'{$DEFINE MM:=begin end}'#13#10'{$IFDEF MM} of {$ELSE} in {$ENDIF}');
  1107. end;
  1108. procedure TTestScanner.TestMacroHandling;
  1109. begin
  1110. TTestingPascalScanner(FScanner).DoSpecial:=True;
  1111. FScanner.SkipComments:=True;
  1112. FScanner.SkipWhiteSpace:=True;
  1113. TestTokens([tkIdentifier],'{$DEFINE MM:=begin end}'#13#10'MM');
  1114. AssertEQuals('Correct identifier', 'somethingweird',LastIdentifier);
  1115. end;
  1116. procedure TTestScanner.TestModeSwitch;
  1117. Const
  1118. PlusMinus = [' ','+','-'];
  1119. Var
  1120. M : TModeSwitch;
  1121. C : Char;
  1122. begin
  1123. For M in TModeSwitch do
  1124. for C in PlusMinus do
  1125. if SModeSwitchNames[M]<>'' then
  1126. begin
  1127. Scanner.CurrentModeSwitches:=[];
  1128. NewSource('{$MODESWITCH '+SModeSwitchNames[M]+' '+C+'}');
  1129. While not (Scanner.FetchToken=tkEOF) do;
  1130. if C in [' ','+'] then
  1131. AssertTrue(SModeSwitchNames[M]+C+' sets '+GetEnumName(TypeInfo(TModeSwitch),Ord(M)),M in Scanner.CurrentModeSwitches)
  1132. else
  1133. AssertFalse(SModeSwitchNames[M]+C+' removes '+GetEnumName(TypeInfo(TModeSwitch),Ord(M)),M in Scanner.CurrentModeSwitches);
  1134. end;
  1135. end;
  1136. initialization
  1137. RegisterTests([TTestTokenFinder,TTestStreamLineReader,TTestScanner]);
  1138. end.