scan.l 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. %{
  2. {
  3. $Id$
  4. Copyright (c) 1998-2000 by Florian Klaempfl
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************}
  17. unit scan;
  18. interface
  19. uses
  20. strings,
  21. lexlib,yacclib;
  22. type
  23. Char=system.char;
  24. ttyp = (
  25. t_id,
  26. { p contains the string }
  27. t_arraydef,
  28. { }
  29. t_pointerdef,
  30. { p1 contains the definition
  31. if in type overrider
  32. or nothing for args
  33. }
  34. t_addrdef,
  35. t_void,
  36. { no field }
  37. t_dec,
  38. { }
  39. t_declist,
  40. { p1 is t_dec
  41. next if exists }
  42. t_memberdec,
  43. { p1 is type specifier
  44. p2 is declarator_list }
  45. t_structdef,
  46. { }
  47. t_memberdeclist,
  48. { p1 is memberdec
  49. next is next if it exist }
  50. t_procdef,
  51. { }
  52. t_uniondef,
  53. { }
  54. t_enumdef,
  55. { }
  56. t_enumlist,
  57. { }
  58. t_preop,
  59. { p contains the operator string
  60. p1 contains the right expr }
  61. t_bop,
  62. { p contains the operator string
  63. p1 contains the left expr
  64. p2 contains the right expr }
  65. t_arg,
  66. {
  67. p1 contain the typedef
  68. p2 the declarator (t_dec)
  69. }
  70. t_arglist,
  71. { }
  72. t_funexprlist,
  73. { }
  74. t_exprlist,
  75. { p1 contains the expr
  76. next contains the next if it exists }
  77. t_ifexpr,
  78. { p1 contains the condition expr
  79. p2 contains the if branch
  80. p3 contains the else branch }
  81. t_funcname,
  82. { p1 contains the function dname
  83. p2 contains the funexprlist
  84. p3 possibly contains the return type }
  85. t_typespec,
  86. { p1 is the type itself
  87. p2 the typecast expr }
  88. t_size_specifier,
  89. { p1 expr for size }
  90. t_default_value
  91. { p1 expr for value }
  92. );
  93. {tdtyp = (dt_id,dt_one,dt_two,dt_three,dt_no,dt_uop,dt_bop);
  94. obsolete removed }
  95. presobject = ^tresobject;
  96. tresobject = object
  97. typ : ttyp;
  98. p : pchar;
  99. next : presobject;
  100. p1,p2,p3 : presobject;
  101. { dtyp : tdtyp; }
  102. constructor init_no(t : ttyp);
  103. constructor init_one(t : ttyp;_p1 : presobject);
  104. constructor init_two(t : ttyp;_p1,_p2 : presobject);
  105. constructor init_three(t : ttyp;_p1,_p2,_p3 : presobject);
  106. constructor init_id(const s : string);
  107. constructor init_bop(const s : string;_p1,_p2 : presobject);
  108. constructor init_preop(const s : string;_p1 : presobject);
  109. function str : string;
  110. function strlength : byte;
  111. function get_copy : presobject;
  112. { can this ve considered as a constant ? }
  113. function is_const : boolean;
  114. destructor done;
  115. end;
  116. tblocktype = (bt_type,bt_const,bt_var,bt_func,bt_no);
  117. var
  118. infile : string;
  119. textinfile,outfile : text;
  120. c : char;
  121. aktspace : string;
  122. block_type : tblocktype;
  123. const
  124. in_define : boolean = false;
  125. { 1 after define; 2 after the ID to print the first
  126. separating space }
  127. in_space_define : byte = 0;
  128. arglevel : longint = 0;
  129. prev_line : string = '';
  130. last_source_line : string = 'Line number 0';
  131. function yylex : integer;
  132. function act_token : string;
  133. procedure internalerror(i : integer);
  134. procedure next_line;
  135. function strpnew(const s : string) : pchar;
  136. implementation
  137. uses options,converu;
  138. procedure internalerror(i : integer);
  139. begin
  140. writeln('Internal error ',i,' in line ',line_no);
  141. halt(1);
  142. end;
  143. { keep the last source line }
  144. procedure next_line;
  145. begin
  146. inc(line_no);
  147. prev_line:=last_source_line;
  148. readln(textinfile,last_source_line);
  149. end;
  150. procedure commenteof;
  151. begin
  152. writeln('unexpected EOF inside comment at line ',line_no);
  153. end;
  154. var p : pchar;
  155. function strpnew(const s : string) : pchar;
  156. begin
  157. getmem(p,length(s)+1);
  158. strpcopy(p,s);
  159. strpnew:=p;
  160. end;
  161. const
  162. newline = #10;
  163. constructor tresobject.init_preop(const s : string;_p1 : presobject);
  164. begin
  165. typ:=t_preop;
  166. p:=strpnew(s);
  167. p1:=_p1;
  168. p2:=nil;
  169. p3:=nil;
  170. next:=nil;
  171. end;
  172. constructor tresobject.init_bop(const s : string;_p1,_p2 : presobject);
  173. begin
  174. typ:=t_bop;
  175. p:=strpnew(s);
  176. p1:=_p1;
  177. p2:=_p2;
  178. p3:=nil;
  179. next:=nil;
  180. end;
  181. constructor tresobject.init_id(const s : string);
  182. begin
  183. typ:=t_id;
  184. p:=strpnew(s);
  185. p1:=nil;
  186. p2:=nil;
  187. p3:=nil;
  188. next:=nil;
  189. end;
  190. constructor tresobject.init_two(t : ttyp;_p1,_p2 : presobject);
  191. begin
  192. typ:=t;
  193. p1:=_p1;
  194. p2:=_p2;
  195. p3:=nil;
  196. p:=nil;
  197. next:=nil;
  198. end;
  199. constructor tresobject.init_three(t : ttyp;_p1,_p2,_p3 : presobject);
  200. begin
  201. typ:=t;
  202. p1:=_p1;
  203. p2:=_p2;
  204. p3:=_p3;
  205. p:=nil;
  206. next:=nil;
  207. end;
  208. constructor tresobject.init_one(t : ttyp;_p1 : presobject);
  209. begin
  210. typ:=t;
  211. p1:=_p1;
  212. p2:=nil;
  213. p3:=nil;
  214. next:=nil;
  215. p:=nil;
  216. end;
  217. constructor tresobject.init_no(t : ttyp);
  218. begin
  219. typ:=t;
  220. p:=nil;
  221. p1:=nil;
  222. p2:=nil;
  223. p3:=nil;
  224. next:=nil;
  225. end;
  226. function tresobject.str : string;
  227. begin
  228. str:=strpas(p);
  229. end;
  230. function tresobject.strlength : byte;
  231. begin
  232. if assigned(p) then
  233. strlength:=strlen(p)
  234. else
  235. strlength:=0;
  236. end;
  237. { can this ve considered as a constant ? }
  238. function tresobject.is_const : boolean;
  239. begin
  240. case typ of
  241. t_id,t_void :
  242. is_const:=true;
  243. t_preop :
  244. is_const:= ((str='-') or (str=' not ')) and p1^.is_const;
  245. t_bop :
  246. is_const:= p2^.is_const and p1^.is_const;
  247. else
  248. is_const:=false;
  249. end;
  250. end;
  251. function tresobject.get_copy : presobject;
  252. var
  253. newres : presobject;
  254. begin
  255. newres:=new(presobject,init_no(typ));
  256. if assigned(p) then
  257. newres^.p:=strnew(p);
  258. if assigned(p1) then
  259. newres^.p1:=p1^.get_copy;
  260. if assigned(p2) then
  261. newres^.p2:=p2^.get_copy;
  262. if assigned(p3) then
  263. newres^.p3:=p3^.get_copy;
  264. if assigned(next) then
  265. newres^.next:=next^.get_copy;
  266. get_copy:=newres;
  267. end;
  268. destructor tresobject.done;
  269. begin
  270. (* writeln('disposing ',byte(typ)); *)
  271. if assigned(p)then strdispose(p);
  272. if assigned(p1) then
  273. dispose(p1,done);
  274. if assigned(p2) then
  275. dispose(p2,done);
  276. if assigned(p3) then
  277. dispose(p3,done);
  278. if assigned(next) then
  279. dispose(next,done);
  280. end;
  281. %}
  282. D [0-9]
  283. %%
  284. "/*" begin
  285. if not stripcomment then
  286. write(outfile,aktspace,'{');
  287. repeat
  288. c:=get_char;
  289. case c of
  290. '*' : begin
  291. c:=get_char;
  292. if c='/' then
  293. begin
  294. if not stripcomment then
  295. writeln(outfile,' }');
  296. flush(outfile);
  297. exit;
  298. end
  299. else
  300. begin
  301. if not stripcomment then
  302. write(outfile,' ');
  303. unget_char(c)
  304. end;
  305. end;
  306. newline : begin
  307. next_line;
  308. if not stripcomment then
  309. begin
  310. writeln(outfile);
  311. write(outfile,aktspace);
  312. end;
  313. end;
  314. #0 : commenteof;
  315. else if not stripcomment then
  316. write(outfile,c);
  317. end;
  318. until false;
  319. flush(outfile);
  320. end;
  321. "//" begin
  322. If not stripcomment then
  323. write(outfile,aktspace,'{');
  324. repeat
  325. c:=get_char;
  326. case c of
  327. newline : begin
  328. unget_char(c);
  329. if not stripcomment then
  330. writeln(outfile,' }');
  331. flush(outfile);
  332. exit;
  333. end;
  334. #0 : commenteof;
  335. else if not stripcomment then
  336. write(outfile,c);
  337. flush(outfile);
  338. end;
  339. until false;
  340. flush(outfile);
  341. end;
  342. \"[^\"]*\" return(CSTRING);
  343. \'[^\']*\' return(CSTRING);
  344. "L"\"[^\"]*\" if win32headers then
  345. return(CSTRING)
  346. else
  347. return(256);
  348. "L"\'[^\']*\' if win32headers then
  349. return(CSTRING)
  350. else
  351. return(256);
  352. {D}*[U]?[L]? begin
  353. if yytext[length(yytext)]='L' then
  354. dec(byte(yytext[0]));
  355. if yytext[length(yytext)]='U' then
  356. dec(byte(yytext[0]));
  357. return(NUMBER);
  358. end;
  359. "0x"[0-9A-Fa-f]*[U]?[L]? begin
  360. (* handle pre- and postfixes *)
  361. if copy(yytext,1,2)='0x' then
  362. begin
  363. delete(yytext,1,2);
  364. yytext:='$'+yytext;
  365. end;
  366. if yytext[length(yytext)]='L' then
  367. dec(byte(yytext[0]));
  368. if yytext[length(yytext)]='U' then
  369. dec(byte(yytext[0]));
  370. return(NUMBER);
  371. end;
  372. {D}+(\.{D}+)?([Ee][+-]?{D}+)?
  373. begin
  374. return(NUMBER);
  375. end;
  376. "->" if in_define then
  377. return(DEREF)
  378. else
  379. return(256);
  380. "-" return(MINUS);
  381. "==" return(EQUAL);
  382. "!=" return(UNEQUAL);
  383. ">=" return(GTE);
  384. "<=" return(LTE);
  385. ">>" return(_SHR);
  386. "##" return(STICK);
  387. "<<" return(_SHL);
  388. ">" return(GT);
  389. "<" return(LT);
  390. "|" return(_OR);
  391. "&" return(_AND);
  392. "!" return(_NOT);
  393. "/" return(_SLASH);
  394. "+" return(_PLUS);
  395. "?" return(QUESTIONMARK);
  396. ":" return(COLON);
  397. "," return(COMMA);
  398. "[" return(LECKKLAMMER);
  399. "]" return(RECKKLAMMER);
  400. "(" begin
  401. inc(arglevel);
  402. return(LKLAMMER);
  403. end;
  404. ")" begin
  405. dec(arglevel);
  406. return(RKLAMMER);
  407. end;
  408. "*" return(STAR);
  409. "..." return(ELLIPSIS);
  410. "." if in_define then
  411. return(POINT)
  412. else
  413. return(256);
  414. "=" return(_ASSIGN);
  415. "extern" return(EXTERN);
  416. "STDCALL" if Win32headers then
  417. return(STDCALL)
  418. else
  419. return(ID);
  420. "CDECL" if not Win32headers then
  421. return(ID)
  422. else
  423. return(CDECL);
  424. "PASCAL" if not Win32headers then
  425. return(ID)
  426. else
  427. return(PASCAL);
  428. "PACKED" if not Win32headers then
  429. return(ID)
  430. else
  431. return(_PACKED);
  432. "WINAPI" if not Win32headers then
  433. return(ID)
  434. else
  435. return(WINAPI);
  436. "SYS_TRAP" if not palmpilot then
  437. return(ID)
  438. else
  439. return(SYS_TRAP);
  440. "WINGDIAPI" if not Win32headers then
  441. return(ID)
  442. else
  443. return(WINGDIAPI);
  444. "CALLBACK" if not Win32headers then
  445. return(ID)
  446. else
  447. return(CALLBACK);
  448. "EXPENTRY" if not Win32headers then
  449. return(ID)
  450. else
  451. return(CALLBACK);
  452. "void" return(VOID);
  453. "VOID" return(VOID);
  454. "#ifdef __cplusplus"[ \t]*\n"extern \"C\" {"\n"#endif"
  455. writeln(outfile,'{ C++ extern C conditionnal removed }');
  456. "#ifdef __cplusplus"[ \t]*\n"}"\n"#endif"
  457. writeln(outfile,'{ C++ end of extern C conditionnal removed }');
  458. "#else" begin
  459. writeln(outfile,'{$else}');
  460. block_type:=bt_no;
  461. flush(outfile);
  462. end;
  463. "#endif" begin
  464. writeln(outfile,'{$endif}');
  465. block_type:=bt_no;
  466. flush(outfile);
  467. end;
  468. "#elif" begin
  469. write(outfile,'(*** was #elif ****)');
  470. write(outfile,'{$else');
  471. c:=get_char;
  472. while c<>newline do
  473. begin write(outfile,c);c:=get_char;end;
  474. writeln(outfile,'}');
  475. block_type:=bt_no;
  476. flush(outfile);
  477. next_line;
  478. end;
  479. "#undef" begin
  480. write(outfile,'{$undef');
  481. c:=get_char;
  482. while c<>newline do
  483. begin write(outfile,c);c:=get_char;end;
  484. writeln(outfile,'}');
  485. flush(outfile);
  486. next_line;
  487. end;
  488. "#error" begin
  489. write(outfile,'{$error');
  490. c:=get_char;
  491. while c<>newline do
  492. begin
  493. write(outfile,c);
  494. c:=get_char;
  495. end;
  496. writeln(outfile,'}');
  497. flush(outfile);
  498. next_line;
  499. end;
  500. "#include" begin
  501. write(outfile,'{$include');
  502. c:=get_char;
  503. while c<>newline do
  504. begin write(outfile,c);c:=get_char;end;
  505. writeln(outfile,'}');
  506. flush(outfile);
  507. block_type:=bt_no;
  508. next_line;
  509. end;
  510. "#if" begin
  511. write(outfile,'{$if');
  512. c:=get_char;
  513. while c<>newline do
  514. begin write(outfile,c);c:=get_char;end;
  515. writeln(outfile,'}');
  516. flush(outfile);
  517. block_type:=bt_no;
  518. next_line;
  519. end;
  520. "#pragma" begin
  521. write(outfile,'(** unsupported pragma');
  522. write(outfile,'#pragma');
  523. c:=get_char;
  524. while c<>newline do
  525. begin write(outfile,c);c:=get_char;end;
  526. writeln(outfile,'*)');
  527. flush(outfile);
  528. block_type:=bt_no;
  529. next_line;
  530. end;
  531. "#define" begin
  532. in_define:=true;
  533. in_space_define:=1;
  534. return(DEFINE);
  535. end;
  536. "char" return(_CHAR);
  537. "union" return(UNION);
  538. "enum" return(ENUM);
  539. "struct" return(STRUCT);
  540. "{" return(LGKLAMMER);
  541. "}" return(RGKLAMMER);
  542. "typedef" return(TYPEDEF);
  543. "int" return(INT);
  544. "short" return(SHORT);
  545. "long" return(LONG);
  546. "unsigned" return(UNSIGNED);
  547. "float" return(REAL);
  548. "const" return(_CONST);
  549. "CONST" return(_CONST);
  550. "FAR" return(_FAR);
  551. "far" return(_FAR);
  552. "NEAR" return(_NEAR);
  553. "near" return(_NEAR);
  554. "HUGE" return(_HUGE);
  555. "huge" return(_HUGE);
  556. [A-Za-z_][A-Za-z0-9_]* begin
  557. if in_space_define=1 then
  558. in_space_define:=2;
  559. return(ID);
  560. end;
  561. ";" return(SEMICOLON);
  562. [ \f\t] if arglevel=0 then
  563. if in_space_define=2 then
  564. begin
  565. in_space_define:=0;
  566. return(SPACE_DEFINE);
  567. end;
  568. \\\n begin
  569. next_line;
  570. if arglevel=0 then
  571. if in_space_define=2 then
  572. begin
  573. in_space_define:=0;
  574. return(SPACE_DEFINE);
  575. end;
  576. end;
  577. \n begin
  578. next_line;
  579. if in_define then
  580. begin
  581. in_define:=false;
  582. in_space_define:=0;
  583. return(NEW_LINE);
  584. end;
  585. end;
  586. . begin
  587. writeln('Illegal character in line ',line_no);
  588. writeln(last_source_line);
  589. return(256 { error });
  590. end;
  591. %%
  592. function act_token : string;
  593. begin
  594. act_token:=yytext;
  595. end;
  596. Function ForceExtension(Const HStr,ext:String):String;
  597. {
  598. Return a filename which certainly has the extension ext
  599. (no dot in ext !!)
  600. }
  601. var
  602. j : longint;
  603. begin
  604. j:=length(Hstr);
  605. while (j>0) and (Hstr[j]<>'.') do
  606. dec(j);
  607. if j=0 then
  608. j:=255;
  609. ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext;
  610. end;
  611. begin
  612. ProcessOptions;
  613. line_no := 1;
  614. assign(yyinput, inputfilename);
  615. reset(yyinput);
  616. assign(textinfile, inputfilename);
  617. reset(textinfile);
  618. readln(textinfile,last_source_line);
  619. assign(outfile, outputfilename);
  620. rewrite(outfile);
  621. if not(includefile) then
  622. begin
  623. writeln(outfile,'unit ',unitname,';');
  624. writeln(outfile);
  625. writeln(outfile,'{ Automatically converted by H2PAS.EXE from '+inputfilename);
  626. writeln(outfile,' Utility made by Florian Klaempfl 25th-28th september 96');
  627. writeln(outfile,' Improvements made by Mark A. Malakanov 22nd-25th may 97 ');
  628. writeln(outfile,' Further improvements by Michael Van Canneyt, April 1998 ');
  629. writeln(outfile,' define handling and error recovery by Pierre Muller, June 1998 }');
  630. writeln(outfile);
  631. writeln(outfile);
  632. writeln(outfile,' interface');
  633. writeln(outfile);
  634. writeln(outfile,' { C default packing is dword }');
  635. writeln(outfile);
  636. writeln(outfile,'{$PACKRECORDS 4}');
  637. end;
  638. if UsePPointers then
  639. begin
  640. { Define some pointers to basic pascal types }
  641. writeln(outfile);
  642. Writeln(outfile,' { Pointers to basic pascal types, inserted by h2pas conversion program.}');
  643. Writeln(outfile,' Type');
  644. Writeln(outfile,' PLongint = ^Longint;');
  645. Writeln(outfile,' PByte = ^Byte;');
  646. Writeln(outfile,' PWord = ^Word;');
  647. Writeln(outfile,' PInteger = ^Integer;');
  648. Writeln(outfile,' PCardinal = ^Cardinal;');
  649. Writeln(outfile,' PReal = ^Real;');
  650. Writeln(outfile,' PDouble = ^Double;');
  651. Writeln(outfile);
  652. end;
  653. end.