mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 05:39:34 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			173 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
unit PreProcessorExpressionTokenise;
 | 
						|
 | 
						|
{(*}
 | 
						|
(*------------------------------------------------------------------------------
 | 
						|
 Delphi Code formatter source code 
 | 
						|
 | 
						|
The Original Code is PreProcessorExpressionTokenise, released August 2003.
 | 
						|
The Initial Developer of the Original Code is Anthony Steele. 
 | 
						|
Portions created by Anthony Steele are Copyright (C) 2003 Anthony Steele.
 | 
						|
All Rights Reserved. 
 | 
						|
Contributor(s): Anthony Steele. 
 | 
						|
 | 
						|
The contents of this file are subject to the Mozilla Public License Version 1.1
 | 
						|
(the "License"). you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at http://www.mozilla.org/NPL/
 | 
						|
 | 
						|
Software distributed under the License is distributed on an "AS IS" basis,
 | 
						|
WITHOUT WARRANTY OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing rights and limitations 
 | 
						|
under the License.
 | 
						|
 | 
						|
Alternatively, the contents of this file may be used under the terms of
 | 
						|
the GNU General Public License Version 2 or later (the "GPL") 
 | 
						|
See http://www.gnu.org/licenses/gpl.html
 | 
						|
------------------------------------------------------------------------------*)
 | 
						|
{*)}
 | 
						|
 | 
						|
{$I JcfGlobal.inc}
 | 
						|
 | 
						|
interface
 | 
						|
 | 
						|
{
 | 
						|
  AFS 26 Aug 2003
 | 
						|
 | 
						|
 lexer for preprocessor $IF expressions
 | 
						|
 Turns text into a list of tokens
 | 
						|
 The tokens are defined in PreProcessorTokens
 | 
						|
 Whitespace is discarded
 | 
						|
}
 | 
						|
uses PreProcessorExpressionTokens;
 | 
						|
 | 
						|
type
 | 
						|
  TPreProcessorExpressionTokeniser = class
 | 
						|
  private
 | 
						|
    fsExpr: String;
 | 
						|
    fiCurrentIndex: integer;
 | 
						|
    fbHasError: boolean;
 | 
						|
 | 
						|
    fcTokens: TPreProcessorExpressionTokenList;
 | 
						|
 | 
						|
    function Rest: string;
 | 
						|
    function StartsWith(const ps: string): boolean;
 | 
						|
 | 
						|
    function TryConsumeFixedSymbol: boolean;
 | 
						|
    function TryConsumeIdentifier: boolean;
 | 
						|
    procedure ConsumeWhiteSpace;
 | 
						|
 | 
						|
  public
 | 
						|
    constructor Create;
 | 
						|
    destructor Destroy; override;
 | 
						|
 | 
						|
    procedure Tokenise;
 | 
						|
 | 
						|
    property Expression: String Read fsExpr Write fsExpr;
 | 
						|
    property Tokens: TPreProcessorExpressionTokenList Read fcTokens;
 | 
						|
    property HasError: boolean Read fbHasError;
 | 
						|
  end;
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
uses
 | 
						|
  { delphi }
 | 
						|
  {$IFNDEF FPC}Windows,{$ENDIF} SysUtils,
 | 
						|
  { local }
 | 
						|
  JcfStringUtils;
 | 
						|
 | 
						|
 | 
						|
constructor TPreProcessorExpressionTokeniser.Create;
 | 
						|
begin
 | 
						|
  inherited;
 | 
						|
  fcTokens := TPreProcessorExpressionTokenList.Create;
 | 
						|
end;
 | 
						|
 | 
						|
destructor TPreProcessorExpressionTokeniser.Destroy;
 | 
						|
begin
 | 
						|
  FreeAndNil(fcTokens);
 | 
						|
  inherited;
 | 
						|
end;
 | 
						|
 | 
						|
function TPreProcessorExpressionTokeniser.Rest: string;
 | 
						|
begin
 | 
						|
  Result := string(StrRestOf(fsExpr, fiCurrentIndex));
 | 
						|
end;
 | 
						|
 | 
						|
function TPreProcessorExpressionTokeniser.StartsWith(const ps: string): boolean;
 | 
						|
begin
 | 
						|
  Result := AnsiSameText(StrLeft(Rest, Length(ps)), ps);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TPreProcessorExpressionTokeniser.Tokenise;
 | 
						|
begin
 | 
						|
  fcTokens.Clear;
 | 
						|
  fiCurrentIndex := 1;
 | 
						|
  fbHasError     := False;
 | 
						|
 | 
						|
  while fiCurrentIndex <= Length(fsExpr) do
 | 
						|
  begin
 | 
						|
    if not TryConsumeFixedSymbol then
 | 
						|
      if not TryConsumeIdentifier then
 | 
						|
      begin
 | 
						|
        // unknown/unsupported Syntax. :(
 | 
						|
        fbHasError := True;
 | 
						|
        break;
 | 
						|
      end;
 | 
						|
 | 
						|
    ConsumeWhiteSpace;
 | 
						|
  end;
 | 
						|
 | 
						|
end;
 | 
						|
 | 
						|
function TPreProcessorExpressionTokeniser.TryConsumeFixedSymbol: boolean;
 | 
						|
var
 | 
						|
  leLoop:  TPreProcessorSymbol;
 | 
						|
  lbFound: boolean;
 | 
						|
begin
 | 
						|
  Result := False;
 | 
						|
 | 
						|
  for leLoop := low(SYMBOL_DATA) to high(SYMBOL_DATA) do
 | 
						|
  begin
 | 
						|
    lbFound := StartsWith(SYMBOL_DATA[leLoop]);
 | 
						|
 | 
						|
    if lbFound then
 | 
						|
    begin
 | 
						|
      fcTokens.Add(leLoop, SYMBOL_DATA[leLoop]);
 | 
						|
 | 
						|
      fiCurrentIndex := fiCurrentIndex + Length(SYMBOL_DATA[leLoop]);
 | 
						|
      Result := True;
 | 
						|
      break;
 | 
						|
    end;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TPreProcessorExpressionTokeniser.TryConsumeIdentifier: boolean;
 | 
						|
var
 | 
						|
  liStart: integer;
 | 
						|
  lsIdentifierText: string;
 | 
						|
begin
 | 
						|
  Result := False;
 | 
						|
 | 
						|
  if CharIsAlpha(fsExpr[fiCurrentIndex]) then
 | 
						|
  begin
 | 
						|
    liStart := fiCurrentIndex;
 | 
						|
    while CharIsAlphaNum(fsExpr[fiCurrentIndex]) do
 | 
						|
      Inc(fiCurrentIndex);
 | 
						|
 | 
						|
    Result := True;
 | 
						|
 | 
						|
    lsIdentifierText := string(copy(fsExpr, liStart, fiCurrentIndex - liStart));
 | 
						|
    fcTokens.Add(eIdentifier, lsIdentifierText);
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TPreProcessorExpressionTokeniser.ConsumeWhiteSpace;
 | 
						|
begin
 | 
						|
  // this lexer can ignore the white space
 | 
						|
  while (fiCurrentIndex < Length(fsExpr)) and CharIsWhiteSpace(fsExpr[fiCurrentIndex]) do
 | 
						|
    Inc(fiCurrentIndex);
 | 
						|
end;
 | 
						|
 | 
						|
end.
 |