Ignore:
Timestamp:
Oct 18, 2010, 12:39:37 PM (14 years ago)
Author:
george
Message:
  • Fixed: Parsing of strings.
  • Modified: Now supported C target "Dynamic C" dialect.
File:
1 edited

Legend:

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

    r65 r67  
    1111type
    1212  TOnErrorMessage = procedure(Text: string; Position: TPoint; FileName: string) of object;
     13
     14  TParserState = (psNone, psIdentifier, psConstantNumber, psConstantString,
     15    psOperator, psEndOfFile, psLineComment, psBlockComment1, psBlockComment2,
     16    psUnknown, psWhiteSpace, psConstantStringEnd);
    1317
    1418  TTokenType = (ttNone, ttIdentifier, ttConstantNumber, ttConstantString,
     
    2529    FNextToken: string;
    2630    FNextTokenType: TTokenType;
     31    FParserState: TParserState;
    2732    PreviousChar: char;
    2833    CurrentChar: char;
     
    3641    function ReadCode: string;
    3742    function NextToken: string;
     43    function NextTokenType: TTokenType;
    3844    procedure Expect(Code: string);
    3945    function IsWhiteSpace(Character: char): boolean;
     
    216222  FNextToken := '';
    217223  FNextTokenType := ttNone;
     224  FParserState := psNone;
    218225  with SourceCodeText do
    219226    while True do
    220227    begin
    221       if CodeStreamPosition < Length(Text) then
    222       begin
     228      if CodeStreamPosition < Length(Text) then begin
    223229        CurrentChar := Text[CodeStreamPosition];
    224       end
    225       else
    226       begin
     230      end else begin
    227231        FNextToken := '';
     232        FParserState := psEndOfFile;
    228233        FNextTokenType := ttEndOfFile;
    229234        Break;
    230235      end;
    231236
    232       if FNextTokenType = ttNone then
    233       begin
     237      if FParserState = psNone then begin
    234238        if IsWhiteSpace(CurrentChar) then
    235           FNextTokenType := ttWhiteSpace
     239          FParserState := psWhiteSpace
    236240        else
    237         if CurrentChar = '{' then
    238         begin
    239           FNextTokenType := ttBlockComment1;
    240         end
    241         else
    242         if CurrentChar = '''' then
    243         begin
    244           FNextTokenType := ttConstantString;
    245         end
    246         else
    247         if CurrentChar in SpecChar then
    248         begin
    249           FNextTokenType := ttOperator;
     241        if CurrentChar = '{' then begin
     242          FParserState := psBlockComment1;
     243        end else
     244        if CurrentChar = '''' then begin
     245          FParserState := psConstantString;
     246        end else
     247        if CurrentChar in SpecChar then begin
     248          FParserState := psOperator;
    250249          FNextToken := FNextToken + CurrentChar;
    251         end
    252         else
    253         if IsAlphanumeric(CurrentChar) then
    254         begin
    255           FNextTokenType := ttIdentifier;
     250        end else
     251        if IsAlphanumeric(CurrentChar) then begin
     252          FParserState := psIdentifier;
    256253          FNextToken := FNextToken + CurrentChar;
    257         end
    258         else
    259           FNextTokenType := ttUnknown;
    260       end
    261       else
    262       if FNextTokenType = ttLineComment then
    263       begin
     254        end else FParserState := psUnknown;
     255      end else
     256      if FParserState = psLineComment then begin
    264257        if (CurrentChar = #13) or (CurrentChar = #10) then
    265           FNextTokenType := ttNone;
    266       end
    267       else
    268       if FNextTokenType = ttBlockComment1 then
    269       begin
     258          FParserState := psNone;
     259      end else
     260      if FParserState = psBlockComment1 then begin
    270261        if (CurrentChar = '}') then
    271           FNextTokenType := ttNone;
    272       end
    273       else
    274       if FNextTokenType = ttBlockComment2 then
    275       begin
     262          FParserState := psNone;
     263      end else
     264      if FParserState = psBlockComment2 then begin
    276265        if (PreviousChar = '*') and (CurrentChar = ')') then
    277           FNextTokenType := ttNone;
    278       end
    279       else
    280       if FNextTokenType = ttConstantString then
    281       begin
    282         if (CurrentChar = '''') and (PreviousChar = '''') then
    283           Break
    284         else
    285           FNextToken := FNextToken + CurrentChar;
    286       end
    287       else
    288       if FNextTokenType = ttOperator then
     266          FParserState := psNone;
     267      end else
     268      if FParserState = psConstantString then
     269      begin
     270        if (CurrentChar = '''') then begin
     271          FParserState := psConstantStringEnd;
     272        end else FNextToken := FNextToken + CurrentChar;
     273      end else
     274      if FParserState = psConstantStringEnd then
     275      begin
     276        if (CurrentChar = '''') then begin
     277          FParserState := psConstantString;
     278        end else FParserState := psNone;
     279        FNextTokenType := ttConstantString;
     280        Break;
     281      end else
     282      if FParserState = psOperator then
    289283      begin
    290284        if (CurrentChar = '*') and (PreviousChar = '(') then
    291285        begin
    292286          FNextToken := '';
    293           FNextTokenType := ttBlockComment2;
    294         end
    295         else
     287          FParserState := psBlockComment2;
     288        end else
    296289        if (CurrentChar = '/') and (PreviousChar = '/') then
    297290        begin
    298291          FNextToken := '';
    299           FNextTokenType := ttLineComment;
     292          FParserState := psLineComment;
     293        end else
     294        if not (CurrentChar in SpecChar) then begin
     295          FNextTokenType := ttOperator;
     296          Break;
    300297        end
    301         else
    302         if not (CurrentChar in SpecChar) then
    303           Break
    304         else
    305         begin
     298        else begin
    306299          J := 0;
    307300          while (J < Length(DoubleSpecChar)) and
     
    310303          if J < Length(DoubleSpecChar) then
    311304            FNextToken := FNextToken + CurrentChar
    312           else
     305          else begin
     306            FNextTokenType := ttOperator;
    313307            Break;
    314         end;
     308          end;
     309        end;
     310      end else
     311      if FParserState = psIdentifier then
     312      begin
     313        if not IsAlphanumeric(CurrentChar) then begin
     314          FNextTokenType := ttIdentifier;
     315          Break;
     316        end else FNextToken := FNextToken + CurrentChar;
    315317      end
    316318      else
    317       if FNextTokenType = ttIdentifier then
    318       begin
    319         if not IsAlphanumeric(CurrentChar) then
    320           Break
    321         else
    322           FNextToken := FNextToken + CurrentChar;
    323       end
    324       else if FNextTokenType = ttWhiteSpace then
    325         FNextTokenType := ttNone;
    326 
    327       if FNextTokenType <> ttNone then
    328       begin
     319      if FParserState = psWhiteSpace then begin
     320        FParserState := psNone;
     321      end;
     322
     323      if FParserState <> psNone then begin
    329324        // Update cursor position
    330325        Inc(CodePosition.X);
    331         if (CurrentChar = #13) then
    332         begin
     326        if (CurrentChar = #13) then begin
    333327          CodePosition.X := 1;
    334328          Inc(CodePosition.Y);
     
    351345begin
    352346  Result := FNextToken;
     347end;
     348
     349function TBaseParser.NextTokenType: TTokenType;
     350begin
     351  Result := FNextTokenType;
    353352end;
    354353
     
    397396var
    398397  Identifier: string;
     398  IdentifierType: TTokenType;
    399399  NewVariable: TVariable;
    400400  NewExpression: TExpression;
     
    409409  Expressions.Add(TExpression.Create);
    410410  with SourceCode do begin
    411     while ((FNextToken <> ';') and (FNextToken <> ',') and
    412         (not IsKeyWord(FNextToken))) and not
    413       (((FNextToken = ')') or (FNextToken = ']'))) do begin
     411    while ((NextToken <> ';') and (NextToken <> ',') and (not IsKeyWord(NextToken))) and not
     412      (((NextToken = ')') or (NextToken = ']'))) and not (NextTokenType = ttEndOfFile) do begin
     413      IdentifierType := NextTokenType;
    414414      Identifier := ReadCode;
    415415      if Identifier = '(' then begin
     
    506506          TExpression(SubItems[1]).NodeType := ntConstant;
    507507
    508           if Identifier[1] = '''' then begin
     508          if IdentifierType = ttConstantString then begin
    509509            TExpression(SubItems[1]).Value := Identifier;
    510510            //SetLength(TExpression(SubItems[1]).Value, Length(Identifier));
     
    512512            //  TExpression(SubItems[1]).Value[I - 1] := Byte(Identifier[I]);
    513513          end else begin
    514             TExpression(SubItems[1]).Value := Identifier;
     514            TExpression(SubItems[1]).Value := StrToInt(Identifier);
    515515          end;
    516516        end;
Note: See TracChangeset for help on using the changeset viewer.