parser.inc 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. {
  2. $Id$
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1998 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************}
  12. {* TParser *}
  13. {****************************************************************************}
  14. {!!!TSE 21.09.1998 Changed by Thomas Seban (TSE) }
  15. const
  16. ParseBufSize = 4096;
  17. procedure BinToHex(Buffer, Text: PChar; BufSize: Integer);
  18. begin
  19. end;
  20. function HexToBin(Text, Buffer: PChar; BufSize: Integer) : Integer;
  21. begin
  22. end;
  23. procedure TParser.ReadBuffer;
  24. var
  25. Count : Integer;
  26. begin
  27. Inc(FOrigin, FSourcePtr - FBuffer);
  28. FSourceEnd[0] := FSaveChar;
  29. Count := FBufPtr - FSourcePtr;
  30. if Count <> 0 then
  31. begin
  32. Move(FSourcePtr[0], FBuffer[0], Count);
  33. end;
  34. FBufPtr := FBuffer + Count;
  35. Inc(FBufPtr, FStream.Read(FBufPtr[0], FBufEnd - FBufPtr));
  36. FSourcePtr := FBuffer;
  37. FSourceEnd := FBufPtr;
  38. if (FSourceEnd = FBufEnd) then
  39. begin
  40. FSourceEnd := LineStart(FBuffer, FSourceEnd - 1);
  41. if FSourceEnd = FBuffer then
  42. begin
  43. Error(SLineTooLong);
  44. end;
  45. end;
  46. FSaveChar := FSourceEnd[0];
  47. FSourceEnd[0] := #0;
  48. end;
  49. procedure TParser.SkipBlanks;
  50. var
  51. Count : Integer;
  52. begin
  53. Inc(FOrigin, FSourcePtr - FBuffer);
  54. FSourceEnd[0] := FSaveChar;
  55. Count := FBufPtr - FSourcePtr;
  56. if Count <> 0 then Move(FSourcePtr[0], FBuffer[0], Count);
  57. FBufPtr := FBuffer + Count;
  58. Inc(FBufPtr, FStream.Read(FBufPtr[0], FBufEnd - FBufPtr));
  59. FSourcePtr := FBuffer;
  60. FSourceEnd := FBufPtr;
  61. if FSourceEnd = FBufEnd then
  62. begin
  63. FSourceEnd := LineStart(FBuffer, FSourceEnd - 1);
  64. if FSourceEnd = FBuffer then Error(SLineTooLong);
  65. end;
  66. FSaveChar := FSourceEnd[0];
  67. FSourceEnd[0] := #0;
  68. end;
  69. constructor TParser.Create(Stream: TStream);
  70. begin
  71. inherited Create;
  72. FStream := Stream;
  73. GetMem(FBuffer, ParseBufSize);
  74. FBuffer[0] := #0;
  75. FBufPtr := FBuffer;
  76. FBufEnd := FBuffer + ParseBufSize;
  77. FSourcePtr := FBuffer;
  78. FSourceEnd := FBuffer;
  79. FTokenPtr := FBuffer;
  80. FSourceLine := 1;
  81. NextToken;
  82. end;
  83. destructor TParser.Destroy;
  84. begin
  85. if Assigned(FBuffer) then
  86. begin
  87. FStream.Seek(Longint(FTokenPtr) - Longint(FBufPtr), 1);
  88. FreeMem(FBuffer, ParseBufSize);
  89. end;
  90. inherited Destroy;
  91. end;
  92. procedure TParser.CheckToken(T : Char);
  93. begin
  94. if Token <> T then
  95. begin
  96. case T of
  97. toSymbol:
  98. Error(SIdentifierExpected);
  99. toString:
  100. Error(SStringExpected);
  101. toInteger, toFloat:
  102. Error(SNumberExpected);
  103. else
  104. ErrorFmt(SCharExpected, [T]);
  105. end;
  106. end;
  107. end;
  108. procedure TParser.CheckTokenSymbol(const S: string);
  109. begin
  110. if not TokenSymbolIs(S) then
  111. ErrorFmt(SSymbolExpected, [S]);
  112. end;
  113. Procedure TParser.Error(const Ident: string);
  114. begin
  115. ErrorStr(Ident);
  116. end;
  117. Procedure TParser.ErrorFmt(const Ident: string; const Args: array of const);
  118. begin
  119. ErrorStr(Format(Ident, Args));
  120. end;
  121. Procedure TParser.ErrorStr(const Message: string);
  122. begin
  123. raise EParserError.CreateFmt(SParseError, [Message, FSourceLine]);
  124. end;
  125. Procedure TParser.HexToBinary(Stream: TStream);
  126. var
  127. Count : Integer;
  128. Buffer : array[0..255] of Char;
  129. begin
  130. SkipBlanks;
  131. while FSourcePtr^ <> '}' do
  132. begin
  133. Count := HexToBin(FSourcePtr, Buffer, SizeOf(Buffer));
  134. if Count = 0 then Error(SInvalidBinary);
  135. Stream.Write(Buffer, Count);
  136. Inc(FSourcePtr, Count * 2);
  137. SkipBlanks;
  138. end;
  139. NextToken;
  140. end;
  141. Function TParser.NextToken: Char;
  142. var
  143. I : Integer;
  144. P, S : PChar;
  145. begin
  146. SkipBlanks;
  147. P := FSourcePtr;
  148. FTokenPtr := P;
  149. case P^ of
  150. 'A'..'Z', 'a'..'z', '_':
  151. begin
  152. Inc(P);
  153. while P^ in ['A'..'Z', 'a'..'z', '0'..'9', '_'] do Inc(P);
  154. Result := toSymbol;
  155. end;
  156. '#', '''':
  157. begin
  158. S := P;
  159. while True do
  160. case P^ of
  161. '#':
  162. begin
  163. Inc(P);
  164. I := 0;
  165. while P^ in ['0'..'9'] do
  166. begin
  167. I := I * 10 + (Ord(P^) - Ord('0'));
  168. Inc(P);
  169. end;
  170. S^ := Chr(I);
  171. Inc(S);
  172. end;
  173. '''':
  174. begin
  175. Inc(P);
  176. while True do
  177. begin
  178. case P^ of
  179. #0, #10, #13:
  180. Error(SInvalidString);
  181. '''':
  182. begin
  183. Inc(P);
  184. if P^ <> '''' then Break;
  185. end;
  186. end;
  187. S^ := P^;
  188. Inc(S);
  189. Inc(P);
  190. end;
  191. end;
  192. else
  193. Break;
  194. end;
  195. FStringPtr := S;
  196. Result := toString;
  197. end;
  198. '$':
  199. begin
  200. Inc(P);
  201. while P^ in ['0'..'9', 'A'..'F', 'a'..'f'] do Inc(P);
  202. Result := toInteger;
  203. end;
  204. '-', '0'..'9':
  205. begin
  206. Inc(P);
  207. while P^ in ['0'..'9'] do Inc(P);
  208. Result := toInteger;
  209. while P^ in ['0'..'9', '.', 'e', 'E', '+', '-'] do
  210. begin
  211. Inc(P);
  212. Result := toFloat;
  213. end;
  214. end;
  215. else
  216. Result := P^;
  217. if Result <> toEOF then Inc(P);
  218. end;
  219. FSourcePtr := P;
  220. FToken := Result;
  221. end;
  222. Function TParser.SourcePos: Longint;
  223. begin
  224. Result := FOrigin + (FTokenPtr - FBuffer);
  225. end;
  226. Function TParser.TokenComponentIdent: String;
  227. var
  228. P : PChar;
  229. begin
  230. CheckToken(toSymbol);
  231. P := FSourcePtr;
  232. while P^ = '.' do
  233. begin
  234. Inc(P);
  235. if not (P^ in ['A'..'Z', 'a'..'z', '_']) then
  236. Error(SIdentifierExpected);
  237. repeat
  238. Inc(P)
  239. until not (P^ in ['A'..'Z', 'a'..'z', '0'..'9', '_']);
  240. end;
  241. FSourcePtr := P;
  242. Result := TokenString;
  243. end;
  244. Function TParser.TokenFloat: Extended;
  245. var
  246. FloatError : Integer;
  247. Back : Real;
  248. begin
  249. Result := 0;
  250. // doesn't work, overload function not found
  251. // systemh.inc compiled without -S2 switch => SizeOf(Integer) = 2
  252. // classes.pp compiled with -S2 switch => SizeOf(Integer) = 4
  253. // Val(TokenString, Back, FloatError);
  254. Val(TokenString, Back); // this works fine
  255. Result := Back;
  256. end;
  257. Function TParser.TokenInt: Longint;
  258. begin
  259. Result := StrToInt(TokenString);
  260. end;
  261. Function TParser.TokenString: string;
  262. var
  263. L : Integer;
  264. StrBuf : array[0..1023] of Char;
  265. begin
  266. if FToken = toString then begin
  267. L := FStringPtr - FTokenPtr
  268. end else begin
  269. L := FSourcePtr - FTokenPtr;
  270. end;
  271. StrLCopy(StrBuf, FTokenPtr, L);
  272. Result := StrPas(StrBuf);
  273. end;
  274. Function TParser.TokenSymbolIs(const S: string): Boolean;
  275. begin
  276. Result := (Token = toSymbol) and (CompareText(S, TokenString) = 0);
  277. end;
  278. {
  279. $Log$
  280. Revision 1.5 1999-01-28 23:55:41 florian
  281. * made it compilable
  282. Revision 1.4 1998/10/30 14:52:51 michael
  283. + Added format in interface
  284. + Some errors in parser fixed, it uses exceptions now
  285. + Strings now has no more syntax errors.
  286. Revision 1.3 1998/10/02 22:41:28 michael
  287. + Added exceptions for error handling
  288. Revision 1.2 1998/09/23 07:48:11 michael
  289. + Implemented by TSE
  290. Revision 1.1 1998/05/04 14:30:12 michael
  291. * Split file according to Class; implemented dummys for all methods, so unit compiles.
  292. }