Changeset 72 for branches/Transpascal/Compiler
- Timestamp:
- Oct 20, 2010, 11:02:10 AM (15 years ago)
- Location:
- branches/Transpascal/Compiler
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/Transpascal/Compiler/Analyze/UParser.pas
r71 r72 6 6 7 7 uses 8 SysUtils, Variants, Classes, 8 SysUtils, Variants, Classes, Contnrs, 9 9 Dialogs, USourceCode, FileUtil; 10 10 … … 19 19 ttOperator, ttEndOfFile, ttLineComment, ttBlockComment1, ttBlockComment2, 20 20 ttUnknown, ttWhiteSpace); 21 22 TToken = class 23 Token: string; 24 CodePosition: TPoint; 25 TokenType: TTokenType; 26 end; 21 27 22 28 { TBaseParser } … … 29 35 FNextTokenType: TTokenType; 30 36 FParserState: TParserState; 31 PreviousChar: char; 32 CurrentChar: char; 37 PreviousChar: Char; 38 CurrentChar: Char; 39 TokenCodePosition: TPoint; 40 procedure GetNextToken; 33 41 public 34 42 ProgramCode: TProgram; 35 CodeStreamPosition: integer;43 CodeStreamPosition: Integer; 36 44 CodePosition: TPoint; 37 LastTokenEnd: TPoint;38 LastTokenStart: TPoint;39 45 SourceCodeText: TStringList; 46 Tokens: TObjectList; // TObjectList<TToken> 47 TokenIndex: Integer; 48 constructor Create; 49 destructor Destroy; override; 40 50 function IsAlphanumeric(Character: char): boolean; 41 procedure GetNextToken;42 function ReadCode: string;43 function NextToken: string;44 function NextTokenType: TTokenType;45 procedure Expect(Code: string);46 51 function IsWhiteSpace(Character: char): boolean; 47 52 function IsAlphabetic(Character: char): boolean; … … 49 54 function IsKeyword(Text: string): boolean; 50 55 function IsOperator(Text: string): boolean; 51 procedure Log(Text: string); 52 procedure ErrorMessage(const Text: string; const Arguments: array of const); 56 function ReadCode: string; 57 function NextToken: string; 58 function NextTokenType: TTokenType; 59 procedure Expect(Code: string); 60 procedure ErrorMessage(const Text: string; const Arguments: array of const; 61 TokenOffset: Integer); 53 62 property OnErrorMessage: TOnErrorMessage read FOnErrorMessage write FOnErrorMessage; 54 procedure Init;63 procedure Process; 55 64 property FileName: string read FFileName write FFileName; 56 65 end; 57 66 58 67 resourcestring 59 SUnknownIdentifier = 'Unknown identificator "%s".';60 SIllegalExpression = 'Illegal expression "%s".';61 68 SExpectedButFound = 'Expected "%s" but "%s" found.'; 62 SRedefineIdentifier = 'Identificator "%s" redefinition.';63 STypeNotDefined = 'Type "%s" not defined.';64 SEndOfDataReached = 'Parser reached to end of input data.';65 SUndefinedVariable = 'Undefined variable "%s".';66 SUndefinedType = 'Undefined type "%s".';67 SUndefinedConstant = 'Undefined constant "%s".';68 SUnitNotFound = 'Unit "%s" not found.';69 69 70 70 implementation … … 72 72 { TBaseParser } 73 73 74 procedure TBaseParser.ErrorMessage(const Text: string; const Arguments: array of const); 74 procedure TBaseParser.ErrorMessage(const Text: string; const Arguments: array of const; 75 TokenOffset: Integer); 75 76 begin 76 77 if Assigned(FOnErrorMessage) then 77 FOnErrorMessage(Format(Text, Arguments), LastTokenStart, FileName); 78 if (TokenIndex + TokenOffset) < Tokens.Count then begin 79 FOnErrorMessage(Format(Text, Arguments), 80 TToken(Tokens[TokenIndex + TokenOffset]).CodePosition, FileName); 81 end; 78 82 end; 79 83 80 84 procedure TBaseParser.Expect(Code: string); 81 85 begin 82 Log('Expected: ' + Code + ' Readed: ' + FNextToken); 83 if FNextToken <> Code then begin 84 //ReadCode; 85 ErrorMessage(SExpectedButFound, [Code, FNextToken]); 86 if NextToken <> Code then begin 87 ErrorMessage(SExpectedButFound, [Code, FNextToken], -2); 86 88 87 89 // Recovery: try to find nearest same code 88 while ( FNextToken <> Code) and (FNextTokenType <> ttEndOfFile) do89 GetNextToken;90 end; 91 GetNextToken;90 while (NextToken <> Code) and (NextTokenType <> ttEndOfFile) do 91 ReadCode; 92 end; 93 ReadCode; 92 94 end; 93 95 … … 95 97 begin 96 98 Result := (Character in ['a'..'z']) or (Character in ['A'..'Z']); 99 end; 100 101 constructor TBaseParser.Create; 102 begin 103 Tokens := TObjectList.Create; 104 end; 105 106 destructor TBaseParser.Destroy; 107 begin 108 Tokens.Free; 109 inherited Destroy; 97 110 end; 98 111 … … 144 157 end; 145 158 146 procedure TBaseParser.Log(Text: string); 147 const 148 LogFileName = 'ParseLog.txt'; 149 var 150 LogFile: TFileStream; 151 begin 152 try 153 if FileExistsUTF8(LogFileName) { *Converted from FileExists* } then 154 LogFile := TFileStream.Create(LogFileName, fmOpenWrite) 155 else 156 LogFile := TFileStream.Create(LogFileName, fmCreate); 157 if Length(Text) > 0 then 158 begin 159 LogFile.Write(Text[1], Length(Text)); 160 LogFile.Write(#13#10, 2); 161 end; 162 finally 163 LogFile.Free; 164 end; 165 end; 166 167 procedure TBaseParser.Init; 168 begin 169 CodePosition := Point(1, 1); 159 procedure TBaseParser.Process; 160 var 161 NewToken: TToken; 162 begin 163 CodePosition := Point(0, 1); 170 164 CurrentChar := #0; 171 165 PreviousChar := #0; … … 173 167 FNextTokenType := ttNone; 174 168 CodeStreamPosition := 1; 175 GetNextToken; 169 Tokens.Clear; 170 TokenIndex := 0; 171 while CodeStreamPosition < Length(SourceCodeText.Text) do begin 172 NewToken := TToken.Create; 173 GetNextToken; 174 NewToken.CodePosition := TokenCodePosition; 175 NewToken.TokenType := FNextTokenType; 176 NewToken.Token := FNextToken; 177 Tokens.Add(NewToken); 178 end; 176 179 end; 177 180 … … 184 187 SpecChar: set of char = [';', '.', ',', ':', '(', ')', '[', ']', 185 188 '+', '-', '/', '*', '^', '=', '<', '>', '@']; 186 DoubleSpecChar: array[0..6] of string = (':=', '..', '<=', '>=', '<>', '+=', '-='); 187 begin 188 LastTokenStart := LastTokenEnd; 189 LastTokenEnd := CodePosition; 189 DoubleSpecChar: array[0..6] of string = (':=', '..', '<=', '>=', '<>', 190 '+=', '-='); 191 begin 190 192 FNextToken := ''; 191 193 FNextTokenType := ttNone; 192 194 FParserState := psNone; 193 195 with SourceCodeText do 194 while True do 195 begin 196 while True do begin 196 197 if CodeStreamPosition < Length(Text) then begin 197 198 CurrentChar := Text[CodeStreamPosition]; … … 204 205 205 206 if FParserState = psNone then begin 207 TokenCodePosition := CodePosition; 206 208 if IsWhiteSpace(CurrentChar) then 207 209 FParserState := psWhiteSpace … … 293 295 Inc(CodePosition.X); 294 296 if (CurrentChar = #13) then begin 295 CodePosition.X := 1;297 CodePosition.X := 0; 296 298 Inc(CodePosition.Y); 297 299 end; … … 305 307 function TBaseParser.ReadCode: string; 306 308 begin 307 Result := FNextToken; 308 GetNextToken; 309 Log('Read: ' + Result); 309 if TokenIndex < Tokens.Count then begin 310 Result := TToken(Tokens[TokenIndex]).Token; 311 Inc(TokenIndex); 312 end else Result := ''; 310 313 end; 311 314 312 315 function TBaseParser.NextToken: string; 313 316 begin 314 Result := FNextToken; 317 if TokenIndex < Tokens.Count then begin 318 Result := TToken(Tokens[TokenIndex]).Token; 319 end else Result := ''; 315 320 end; 316 321 317 322 function TBaseParser.NextTokenType: TTokenType; 318 323 begin 319 Result := FNextTokenType; 324 if TokenIndex < Tokens.Count then begin 325 Result := TToken(Tokens[TokenIndex]).TokenType; 326 end else Result := ttEndOfFile; 320 327 end; 321 328 -
branches/Transpascal/Compiler/Analyze/UPascalParser.pas
r71 r72 47 47 48 48 49 resourcestring 50 SUnknownIdentifier = 'Unknown identificator "%s".'; 51 SIllegalExpression = 'Illegal expression "%s".'; 52 SRedefineIdentifier = 'Identificator "%s" redefinition.'; 53 STypeNotDefined = 'Type "%s" not defined.'; 54 SEndOfDataReached = 'Parser reached to end of input data.'; 55 SUndefinedVariable = 'Undefined variable "%s".'; 56 SUndefinedType = 'Undefined type "%s".'; 57 SUndefinedConstant = 'Undefined constant "%s".'; 58 SUnitNotFound = 'Unit "%s" not found.'; 59 60 49 61 implementation 50 62 … … 63 75 if Assigned(OnGetSource) then begin 64 76 if FOnGetSource(Name, Parser.SourceCodeText) then begin 65 Parser. Init;77 Parser.Process; 66 78 Parser.FileName := Name; 67 79 Parser.OnErrorMessage := OnErrorMessage; … … 192 204 end; 193 205 end else begin 194 ErrorMessage(SUnknownIdentifier, [Identifier] );206 ErrorMessage(SUnknownIdentifier, [Identifier], -1); 195 207 end; 196 208 end; … … 326 338 begin 327 339 Result := nil; 328 ErrorMessage(SUnknownIdentifier, [ReadCode] );340 ErrorMessage(SUnknownIdentifier, [ReadCode], -1); 329 341 end; 330 342 end … … 334 346 begin 335 347 Result := nil; 336 ErrorMessage(SIllegalExpression, [ReadCode] );348 ErrorMessage(SIllegalExpression, [ReadCode], -1); 337 349 end; 338 350 end; … … 454 466 ParseFunctionList(Functions, True) 455 467 else begin 456 ErrorMessage(SUnknownIdentifier, [NextToken] );468 ErrorMessage(SUnknownIdentifier, [NextToken], -1); 457 469 ReadCode; 458 470 end; … … 529 541 end; 530 542 end else 531 ErrorMessage(SRedefineIdentifier, [VariableName] );543 ErrorMessage(SRedefineIdentifier, [VariableName], 0); 532 544 Expect(':'); 533 545 TypeName := ReadCode; 534 546 NewValueType := Parent.Types.Search(TypeName); 535 547 if not Assigned(NewValueType) then 536 ErrorMessage(STypeNotDefined, [TypeName] )548 ErrorMessage(STypeNotDefined, [TypeName], -1) 537 549 else 538 550 for I := 0 to Identifiers.Count - 1 do … … 554 566 NewValueType := Parent.Types.Search(TypeName); 555 567 if not Assigned(NewValueType) then 556 ErrorMessage(STypeNotDefined, [TypeName] )568 ErrorMessage(STypeNotDefined, [TypeName], -1) 557 569 else 558 570 begin … … 611 623 ControlVariable := SourceCode.CommonBlock.Variables.Search(VariableName); 612 624 if not Assigned(ControlVariable) then 613 ErrorMessage(SUndefinedVariable, [VariableName] );625 ErrorMessage(SUndefinedVariable, [VariableName], 0); 614 626 Expect(':='); 615 627 Start.CommonBlock := CommonBlock; … … 653 665 end 654 666 else 655 ErrorMessage(SRedefineIdentifier, [VariableName] );667 ErrorMessage(SRedefineIdentifier, [VariableName], 0); 656 668 Expect(':'); 657 669 TypeName := ReadCode; 658 670 NewValueType := Parent.Types.Search(TypeName); 659 671 if NewValueType = nil then 660 ErrorMessage(STypeNotDefined, [TypeName] )672 ErrorMessage(STypeNotDefined, [TypeName], -1) 661 673 else 662 674 for I := 0 to Identifiers.Count - 1 do … … 714 726 end 715 727 else 716 ErrorMessage(SRedefineIdentifier, [ConstantName] );728 ErrorMessage(SRedefineIdentifier, [ConstantName], 0); 717 729 Expect(':'); 718 730 TypeName := ReadCode; … … 723 735 724 736 if NewValueType = nil then 725 ErrorMessage(STypeNotDefined, [TypeName] )737 ErrorMessage(STypeNotDefined, [TypeName], -1) 726 738 else 727 739 for I := 0 to Identifiers.Count - 1 do … … 800 812 TTypeArray(Result).IndexType := ParseType(TypeList, False); 801 813 if not Assigned(TTypeArray(Result).IndexType) then 802 ErrorMessage(SUndefinedType, [TypeName] );814 ErrorMessage(SUndefinedType, [TypeName], 0); 803 815 Expect(']'); 804 816 end; … … 807 819 TTypeArray(Result).ItemType := ParseType(TypeList, False); 808 820 if not Assigned(TTypeArray(Result).ItemType) then 809 ErrorMessage(SUndefinedType, [TypeName] );821 ErrorMessage(SUndefinedType, [TypeName], 0); 810 822 end else 811 823 if NextToken = '^' then begin … … 834 846 TType(Result).UsedType := TypeList.Search(TypeName); 835 847 if not Assigned(TType(Result).UsedType) then 836 ErrorMessage(SUndefinedType, [TypeName] );848 ErrorMessage(SUndefinedType, [TypeName], 0); 837 849 end else begin 838 850 TType(Result) := TypeList.Search(TypeName); 839 851 if not Assigned(TType(Result)) then 840 ErrorMessage(SUndefinedType, [TypeName] );852 ErrorMessage(SUndefinedType, [TypeName], 0); 841 853 end; 842 854 end; … … 922 934 constructor TPascalParser.Create; 923 935 begin 936 inherited; 924 937 end; 925 938 … … 949 962 Exported := AExported; 950 963 end else begin 951 ErrorMessage(SUnitNotFound, [Name] );964 ErrorMessage(SUnitNotFound, [Name], -2); 952 965 SourceCode.Delete(SourceCode.Count - 1); 953 966 end; … … 966 979 if not Assigned(Module) then begin 967 980 if not ParseFile(Name) then begin 968 ErrorMessage(SUnitNotFound, [Name] );981 ErrorMessage(SUnitNotFound, [Name], -2); 969 982 SourceCode.Delete(SourceCode.Count - 1); 970 983 end; -
branches/Transpascal/Compiler/TranspascalCompiler.lpk
r70 r72 15 15 </Other> 16 16 </CompilerOptions> 17 <Files Count=" 9">17 <Files Count="10"> 18 18 <Item1> 19 19 <Filename Value="UCompiler.pas"/> … … 52 52 <UnitName Value="UPascalParser"/> 53 53 </Item9> 54 <Item10> 55 <Filename Value="Analyze\UGrammer.pas"/> 56 <UnitName Value="UGrammer"/> 57 </Item10> 54 58 </Files> 55 59 <Type Value="RunAndDesignTime"/> -
branches/Transpascal/Compiler/TranspascalCompiler.pas
r70 r72 9 9 uses 10 10 UCompiler, USourceCode, UProducerTreeView, UProducer, UProducerAsm8051, 11 UProducerC, UProducerPascal, UParser, UPascalParser, LazarusPackageIntf; 11 UProducerC, UProducerPascal, UParser, UPascalParser, UGrammer, 12 LazarusPackageIntf; 12 13 13 14 implementation -
branches/Transpascal/Compiler/UCompiler.pas
r71 r72 65 65 Parser.FileName := ModuleName; 66 66 Parser.SourceCodeText := Source; 67 Parser. Init;67 Parser.Process; 68 68 //ShowMessage(IntToHex(Integer(Addr(Parser.OnGetSource)), 8)); 69 69 NewModule := Parser.ParseModule(ProgramCode);
Note:
See TracChangeset
for help on using the changeset viewer.