parser.inc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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. const
  15. ParseBufSize = 4096;
  16. procedure BinToHex(Buffer, Text: PChar; BufSize: Integer);
  17. begin
  18. end;
  19. function HexToBin(Text, Buffer: PChar; BufSize: Integer) : Integer;
  20. begin
  21. HexToBin:=0;
  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. Val(TokenString, Back, FloatError);
  251. Result := Back;
  252. end;
  253. Function TParser.TokenInt: Longint;
  254. begin
  255. Result := StrToInt(TokenString);
  256. end;
  257. Function TParser.TokenString: string;
  258. var
  259. L : Integer;
  260. StrBuf : array[0..1023] of Char;
  261. begin
  262. if FToken = toString then begin
  263. L := FStringPtr - FTokenPtr
  264. end else begin
  265. L := FSourcePtr - FTokenPtr;
  266. end;
  267. StrLCopy(StrBuf, FTokenPtr, L);
  268. Result := StrPas(StrBuf);
  269. end;
  270. Function TParser.TokenSymbolIs(const S: string): Boolean;
  271. begin
  272. Result := (Token = toSymbol) and (CompareText(S, TokenString) = 0);
  273. end;
  274. {
  275. $Log$
  276. Revision 1.6 1999-04-08 10:18:53 peter
  277. * makefile updates
  278. }