Ignore:
Timestamp:
Oct 21, 2010, 1:20:57 PM (14 years ago)
Author:
george
Message:
  • Enhanced: Tokenizerm, parsing of record type, generation C code for record type.
  • Added: Logging of debug information.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/Transpascal/Compiler/Analyze/UParser.pas

    r74 r76  
    1010
    1111type
    12   TOnErrorMessage = procedure(Text: string; Position: TPoint; FileName: string) of object;
     12  TErrorMessageEvent = procedure(Text: string; Position: TPoint; FileName: string) of object;
     13  TDebugLogEvent = procedure(Text: string) of object;
    1314
    1415  TParserState = (psNone, psIdentifier, psConstantNumber, psConstantString,
    1516    psOperator, psEndOfFile, psLineComment, psBlockComment1, psBlockComment2,
    16     psUnknown, psWhiteSpace, psConstantStringEnd);
     17    psUnknown, psWhiteSpace, psConstantStringEnd, psBlockComment1First,
     18    psCompilerDirective, psNoneShift, psConstantHexNumber);
    1719
    1820  TTokenType = (ttNone, ttIdentifier, ttConstantNumber, ttConstantString,
    1921    ttOperator, ttEndOfFile, ttLineComment, ttBlockComment1, ttBlockComment2,
    20     ttUnknown, ttWhiteSpace);
     22    ttUnknown, ttWhiteSpace, ttCompilerDirective);
    2123
    2224  TToken = class
     
    3133  private
    3234    FFileName: string;
    33     FOnErrorMessage: TOnErrorMessage;
     35    FOnDebugLog: TDebugLogEvent;
     36    FOnErrorMessage: TErrorMessageEvent;
    3437    FNextToken: string;
    3538    FNextTokenType: TTokenType;
     
    4952    destructor Destroy; override;
    5053    function IsAlphanumeric(Character: char): boolean;
     54    function IsNumeric(Character: char): boolean;
     55    function IsHex(Character: char): boolean;
    5156    function IsWhiteSpace(Character: char): boolean;
    5257    function IsAlphabetic(Character: char): boolean;
     
    6065    procedure ErrorMessage(const Text: string; const Arguments: array of const;
    6166      TokenOffset: Integer);
    62     property OnErrorMessage: TOnErrorMessage read FOnErrorMessage write FOnErrorMessage;
     67    property OnErrorMessage: TErrorMessageEvent read FOnErrorMessage write FOnErrorMessage;
     68    property OnDebugLog: TDebugLogEvent read FOnDebugLog write FOnDebugLog;
    6369    procedure Process;
     70    procedure Log(Text: string);
    6471    property FileName: string read FFileName write FFileName;
    6572  end;
     
    8491procedure TBaseParser.Expect(Code: string);
    8592begin
     93  Log('Expect: ' + Code);
    8694  if NextToken <> Code then begin
    8795    ErrorMessage(SExpectedButFound, [Code, NextToken], 0);
     
    112120function TBaseParser.IsAlphanumeric(Character: char): boolean;
    113121begin
    114   Result := IsAlphabetic(Character) or (Character in ['0'..'9']);
     122  Result := IsAlphabetic(Character) or IsNumeric(Character);
     123end;
     124
     125function TBaseParser.IsNumeric(Character: char): boolean;
     126begin
     127  Result := Character in ['0'..'9'];
     128end;
     129
     130function TBaseParser.IsHex(Character: char): boolean;
     131begin
     132  Result := IsNumeric(Character) or (Character in ['A'..'F']);
    115133end;
    116134
     
    179197end;
    180198
     199procedure TBaseParser.Log(Text: string);
     200begin
     201  if Assigned(FOnDebugLog) then
     202    FOnDebugLog(Text);
     203end;
     204
    181205procedure TBaseParser.GetNextToken;
    182206var
     
    204228      end;
    205229
    206       if FParserState = psNone then begin
     230      if (FParserState = psNone) or (FParserState = psNoneShift) then begin
    207231        TokenCodePosition := CodePosition;
    208232        if IsWhiteSpace(CurrentChar) then
     
    210234        else
    211235        if CurrentChar = '{' then begin
    212           FParserState := psBlockComment1;
     236          FParserState := psBlockComment1First;
    213237        end else
    214238        if CurrentChar = '''' then begin
    215239          FParserState := psConstantString;
     240        end else
     241        if CurrentChar = '$' then begin
     242          FParserState := psConstantHexNumber;
    216243        end else
    217244        if CurrentChar in SpecChar then begin
     
    219246          FNextToken := FNextToken + CurrentChar;
    220247        end else
    221         if IsAlphanumeric(CurrentChar) then begin
     248        if IsAlphabetic(CurrentChar) then begin
    222249          FParserState := psIdentifier;
    223250          FNextToken := FNextToken + CurrentChar;
     251        end else
     252        if IsNumeric(CurrentChar) then begin
     253          FPArserSTate := psConstantNumber;
     254          FNextToken := FNextToken + CurrentChar;
    224255        end else FParserState := psUnknown;
    225256      end else
    226257      if FParserState = psLineComment then begin
    227258        if (CurrentChar = #13) or (CurrentChar = #10) then
     259          FParserState := psNoneShift;
     260      end else
     261      if FParserState = psBlockComment1First then begin
     262        if CurrentChar = '$' then FParserState := psCompilerDirective
     263        else FParserSTate := psBlockComment1;
     264      end else
     265      if FParserState = psBlockComment1 then begin
     266        if (CurrentChar = '}') then begin
     267          FParserState := psNoneShift;
     268        end;
     269      end else
     270      if FParserState = psCompilerDirective then begin
     271        if (CurrentChar = '}') then begin
    228272          FParserState := psNone;
    229       end else
    230       if FParserState = psBlockComment1 then begin
    231         if (CurrentChar = '}') then
    232           FParserState := psNone;
     273          FNextTokenType := ttCompilerDirective;
     274          Break;
     275        end;
    233276      end else
    234277      if FParserState = psBlockComment2 then begin
    235278        if (PreviousChar = '*') and (CurrentChar = ')') then
    236           FParserState := psNone;
     279          FParserState := psNoneShift;
    237280      end else
    238281      if FParserState = psConstantString then
     
    249292        FNextTokenType := ttConstantString;
    250293        Break;
     294      end else
     295      if FParserState = psConstantHexNumber then
     296      begin
     297        if not IsHex(CurrentChar) then begin
     298          FParserState := psNone;
     299          FNextTokenType := ttConstantNumber;
     300          Break;
     301        end else FNextToken := FNextToken + CurrentChar;
     302      end else
     303      if FParserState = psConstantNumber then
     304      begin
     305        if not IsNumeric(CurrentChar) then begin
     306          FParserState := psNone;
     307          FNextTokenType := ttConstantNumber;
     308          Break;
     309        end else FNextToken := FNextToken + CurrentChar;
    251310      end else
    252311      if FParserState = psOperator then
     
    281340      if FParserState = psIdentifier then
    282341      begin
    283         if not IsAlphanumeric(CurrentChar) then begin
     342        if (not IsAlphanumeric(CurrentChar)) and (CurrentChar <> '_') then begin
    284343          FNextTokenType := ttIdentifier;
    285344          Break;
     
    311370    Inc(TokenIndex);
    312371  end else Result := '';
     372  Log('ReadCode: ' + Result);
    313373end;
    314374
     
    318378    Result := TToken(Tokens[TokenIndex]).Token;
    319379  end else Result := '';
     380  Log('NextToken: ' + Result);
    320381end;
    321382
Note: See TracChangeset for help on using the changeset viewer.