OScan.pas
上传用户:yj_qiu
上传日期:2022-08-08
资源大小:23636k
文件大小:7k
源码类别:

游戏引擎

开发平台:

Delphi

  1. (*
  2.  Oberon scanner unit
  3.  (C) 2004-2007 George "Mirage" Bakhtadze. <a href="http://www.casteng.com">www.casteng.com</a> <br>
  4.  The source code may be used under either MPL 1.1 or LGPL 2.1 license. See included license.txt file <br>
  5.  The unit contains scanner class
  6. *)
  7. unit OScan;
  8. interface
  9. uses OTypes;
  10. const
  11. //  sSpecial = ['+', '-', '*', '/', '~', '&', '.', ',', ':', ';', '|', '(', ')', '[', ']', '{', '}', '=', '>', '<', '#', '^'];
  12.   sOperation = ['+', '-', '*', '/', '~', '&', '|', '=', '>', '<', '#', '^'];
  13.   sOperator = [':', '='];
  14.   sRelation = ['=', '<', '>', '#'];
  15. type
  16.   TScaner = class
  17.     Source, Buf: string;
  18.     SourcePos, CurLine: Int;
  19.     EOS: Boolean;
  20.     constructor Create(ASource: string);
  21.     function ReadChar(var Character: Char): Boolean;
  22.     procedure ReturnChar(Character: Char);
  23.     procedure ReturnBuf(Buffer: string);
  24.     function isComment(c: Char): Boolean;
  25.     function isDelim(c: Char): Boolean;
  26.     function isAlpha(c: Char): Boolean;
  27.     function isNumber(c: Char): Boolean;
  28.     function isHexNumber(c: Char): Boolean;
  29.     function isOperation(c: Char): Boolean;
  30.     function isOperator(c: Char): Boolean;
  31.     function isRelation(c: Char): Boolean;
  32.     procedure SkipDelims;
  33.     procedure GetIdent(c: Char);
  34.     procedure GetNumber(c: Char);
  35.     procedure GetString(c: Char);
  36.     procedure GetComment(c: Char);
  37.     function GetOperation(c: Char): Int32;
  38.     function GetOperator(c: Char): Int32;
  39.     function GetRelation(c: Char): Int32;
  40.   private
  41.     CommentStack: array of Int32;
  42.     TotalCommentStack: Int;
  43.     procedure AddComment(Index: Integer);
  44.     procedure DelComment;
  45.   end;
  46. implementation
  47. constructor TScaner.Create(ASource: string);
  48. begin
  49.   Source := ASource; SourcePos := 1; CurLine := 1; Buf := ''; TotalCommentStack := 0; EOS := False;
  50. end;
  51. function TScaner.ReadChar(var Character: Char): Boolean;
  52. begin
  53.   Result := False;
  54.   if SourcePos > Length(Source) then begin Character := #10; Inc(SourcePos); Inc(CurLine); EOS := True; Exit; end;
  55.   Character := Source[SourcePos];
  56.   if Character = #10 then Inc(CurLine);
  57.   Inc(SourcePos);
  58.   Result := True;
  59.   EOS := False;
  60. end;
  61. procedure TScaner.ReturnChar(Character: Char);
  62. begin
  63.   if SourcePos <= 1 then Exit;
  64.   if Character = #10 then Dec(CurLine);
  65.   Dec(SourcePos);
  66.   EOS := False;
  67. end;
  68. procedure TScaner.ReturnBuf(Buffer: string);
  69. var i: Integer;
  70. begin
  71.   for i := Length(Buffer) downto 1 do ReturnChar(Buf[i]);
  72.   if Length(Buffer)>0 then EOS := False;
  73. end;
  74. function TScaner.isComment(c: Char): Boolean;
  75. begin
  76.   Result := (c = '/') or (c = '(') or (c='*');       // ToFix: Fix it
  77.   Result := False;
  78. end;
  79. function TScaner.isDelim(c: Char): Boolean;
  80. begin
  81.   Result := (c =  ' ') or (c =  #10) or (c =  #13);
  82. end;
  83. function TScaner.isAlpha(c: Char): Boolean;
  84. begin
  85.   Result := (c in ['a'..'z']) or (c in ['A'..'Z']) or (c = '_');
  86. end;
  87. function TScaner.isNumber(c: Char): Boolean;
  88. begin
  89.   Result := (c in ['0'..'9']);
  90. end;
  91. function TScaner.isHexNumber(c: Char): Boolean;
  92. begin
  93.   Result := (c in ['A'..'F', 'a'..'f', 'H', 'h']);
  94. end;
  95. function TScaner.isOperation(c: Char): Boolean;
  96. begin
  97.   Result := (c in sOperation);
  98. end;
  99. function TScaner.isOperator(c: Char): Boolean;
  100. begin
  101.   Result := (c in sOperator);
  102. end;
  103. function TScaner.isRelation(c: Char): Boolean;
  104. begin
  105.   Result := (c in sRelation);
  106. end;
  107. procedure TScaner.SkipDelims;
  108. var ch: Char;
  109. begin
  110. // ( )
  111.   repeat
  112.     if not ReadChar(ch) then Exit;
  113. //    if isComment(ch) then GetComment(ch);
  114.   until not isDelim(ch);
  115.   ReturnChar(ch);
  116. end;
  117. procedure TScaner.GetIdent(c: Char);
  118. var i: Integer;
  119. begin
  120.   Buf := '';
  121. //  repeat
  122.     if isAlpha(c) then begin
  123.       Buf := Buf + c;
  124.       while ReadChar(c) and (isAlpha(c) or isNumber(c) or (c = '_')) do Buf := Buf + c;
  125.     end;
  126. //    if isComment(c) then GetComment(c) else ReturnChar(c);
  127. //    ReadChar(c);
  128. //  until not (isAlpha(c) or isNumber(c));
  129.   ReturnChar(c);
  130. end;
  131. procedure TScaner.GetNumber(c: Char);
  132. var i: Integer; LastChar: Char;
  133. begin
  134.   LastChar := #0;
  135.   Buf := c;
  136. //  repeat
  137.     while ReadChar(c) and (isNumber(c) or isHexNumber(c) or (c='.') or
  138.           ( ((c = '-') or (c = '+')) and ((UpCase(LastChar) = 'E') or (UpCase(LastChar) = 'D')) ) ) do begin
  139.       Buf := Buf + c;
  140.       LastChar := c;
  141.     end;
  142. {    if isComment(c) then GetComment(c) else ReturnChar(c);
  143.     ReadChar(c);
  144.   until not isNumber(c);}
  145.   ReturnChar(c);
  146. end;
  147. procedure TScaner.GetString(c: Char);
  148. var Term: Char;
  149. begin
  150.   Term := c; Buf := '';
  151.   ReadChar(c);
  152.   while c <> Term do begin
  153.     if c = #10 then begin {Error(CurLine - 1, 2); }Exit; end;
  154.     Buf := Buf + c;
  155.     ReadChar(c);
  156.   end;
  157. //  Memo1.Text := Memo1.Text+' Str: '+Term+Buf+Term;
  158. end;
  159. procedure TScaner.AddComment(Index: Integer);
  160. begin
  161.   Inc(TotalCommentStack);
  162. {  SetLength(CommentStack, TotalCommentStack);
  163.   CommentStack[TotalCommentStack-1] := Index;}
  164. end;
  165. procedure TScaner.DelComment;
  166. begin
  167.   Dec(TotalCommentStack);
  168. //  SetLength(CommentStack, TotalCommentStack);
  169. end;
  170. procedure TScaner.GetComment(c: Char);
  171. var i: Integer; Buf: string; ReallyComment: Boolean;
  172. begin
  173.   Buf := c;
  174.   while ReadChar(c) and isComment(c) do Buf := Buf + c;
  175.   if not isDelim(c) then ReturnChar(c);                    // Don't return delimiters
  176.   ReallyComment := False;
  177.   for i := 0 to TotalComments-1 do begin
  178.     if (Length(CommentStr[i].Open) <= Length(Buf)) and (CommentStr[i].Open = Copy(Buf, Length(Buf)-Length(CommentStr[i].Open)+1, Length(CommentStr[i].Open))) then begin
  179.       ReallyComment := True; Break;
  180.     end;
  181.   end;
  182.   if not ReallyComment then begin ReturnBuf(Buf); Exit; end;
  183.   AddComment(0);
  184.   while ReadChar(c) and (TotalCommentStack > 0) do begin
  185.     Buf := Buf + c;
  186.     for i := 0 to TotalComments-1 do begin
  187.       if (Length(CommentStr[i].Close) <= Length(Buf)) and (CommentStr[i].Close = Copy(Buf, Length(Buf)-Length(CommentStr[i].Close)+1, Length(CommentStr[i].Close))) then DelComment;
  188. //      if (Length(CommentStr[i].Open) <= Length(Buf)) and (CommentStr[i].Open = Copy(Buf, Length(Buf)-Length(CommentStr[i].Open)+1, Length(CommentStr[i].Open))) then GetComment;
  189.     end;
  190.   end;
  191. //  Memo1.Text := Memo1.Text+' Comment: '+Buf;
  192.   ReturnChar(c);
  193.   Buf := '';
  194. end;
  195. function TScaner.GetOperation(c: Char): Int32;
  196. var i: Integer;
  197. begin
  198.   Buf := c;
  199.   repeat
  200.     while ReadChar(c) and isOperation(c) do Buf := Buf + c;
  201.     if isComment(c) then GetComment(c) else ReturnChar(c);
  202.     ReadChar(c);
  203.   until not isOperation(c);
  204.   ReturnChar(c);
  205. end;
  206. function TScaner.GetOperator(c: Char): Int32;
  207. var i: Integer;
  208. begin
  209.   Buf := c;
  210.   repeat
  211.     while ReadChar(c) and isOperator(c) do Buf := Buf + c;
  212.     if isComment(c) then GetComment(c) else ReturnChar(c);
  213.     ReadChar(c);
  214.   until not isOperator(c);
  215.   ReturnChar(c);
  216. end;
  217. function TScaner.GetRelation(c: Char): Int32;
  218. var i: Integer;
  219. begin
  220.   Buf := c;
  221.   repeat
  222.     while ReadChar(c) and isRelation(c) do Buf := Buf + c;
  223.     if isComment(c) then GetComment(c) else ReturnChar(c);
  224.     ReadChar(c);
  225.   until not isRelation(c);
  226.   ReturnChar(c);
  227. end;
  228. end.