Changeset 70 for branches/Transpascal/Compiler/Analyze/UParser.pas
- Timestamp:
- Oct 19, 2010, 11:22:55 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/Transpascal/Compiler/Analyze/UParser.pas
r69 r70 25 25 private 26 26 FFileName: string; 27 ProgramCode: TProgram;28 27 FOnErrorMessage: TOnErrorMessage; 29 28 FNextToken: string; … … 32 31 PreviousChar: char; 33 32 CurrentChar: char; 34 procedure ErrorMessage(const Text: string; const Arguments: array of const);35 33 public 34 ProgramCode: TProgram; 36 35 CodeStreamPosition: integer; 37 36 CodePosition: TPoint; 37 LastTokenPosition: TPoint; 38 38 SourceCodeText: TStringList; 39 39 function IsAlphanumeric(Character: char): boolean; … … 49 49 function IsOperator(Text: string): boolean; 50 50 procedure Log(Text: string); 51 procedure ErrorMessage(const Text: string; const Arguments: array of const); 51 52 property OnErrorMessage: TOnErrorMessage read FOnErrorMessage write FOnErrorMessage; 52 53 procedure Init; 53 54 property FileName: string read FFileName write FFileName; 54 55 end; 55 56 TGetSourceEvent = function (Name: string; Source: TStringList): Boolean of object;57 58 { TPascalParser }59 60 TPascalParser = class(TBaseParser)61 private62 FOnGetSource: TGetSourceEvent;63 public64 function ParseFile(Name: string): Boolean;65 procedure ParseWhileDo(SourceCode: TWhileDo);66 procedure ParseExpression(SourceCode: TExpression);67 procedure ParseUses(SourceCode: TUsedModuleList; AExported: Boolean);68 function ParseModule(ProgramCode: TProgram): TModule;69 procedure ParseUnit(SourceCode: TModuleUnit);70 procedure ParseUnitInterface(SourceCode: TModuleUnit);71 procedure ParseUnitImplementation(SourceCode: TModuleUnit);72 procedure ParseProgram(SourceCode: TModuleProgram);73 procedure ParseCommonBlock(SourceCode: TCommonBlock; EndSymbol: char = ';');74 procedure ParseCommonBlockInterface(SourceCode: TCommonBlock);75 function ParseCommand(SourceCode: TCommonBlock): TCommand;76 procedure ParseBeginEnd(SourceCode: TBeginEnd);77 procedure ParseFunctionList(SourceCode: TFunctionList; Exported: Boolean = False);78 procedure ParseIfThenElse(SourceCode: TIfThenElse);79 procedure ParseForToDo(SourceCode: TForToDo);80 procedure ParseVariableList(SourceCode: TVariableList; Exported: Boolean = False);81 procedure ParseVariable(SourceCode: TVariable; Exported: Boolean = False);82 procedure ParseConstantList(SourceCode: TConstantList; Exported: Boolean = False);83 procedure ParseTypeList(SourceCode: TTypeList; Exported: Boolean = False);84 function ParseType(TypeList: TTypeList; ExpectName: Boolean = True; AssignSymbol: string = '='): TType;85 function ParseTypeEnumeration(TypeList: TTypeList; Name: string): TType;86 function ParseTypeRecord(TypeList: TTypeList; Name: string): TType;87 property OnGetSource: TGetSourceEvent read FOnGetSource88 write FOnGetSource;89 constructor Create;90 destructor Destroy; override;91 end;92 93 94 implementation95 56 96 57 resourcestring … … 106 67 SUnitNotFound = 'Unit "%s" not found.'; 107 68 69 implementation 70 108 71 { TBaseParser } 109 72 … … 111 74 begin 112 75 if Assigned(FOnErrorMessage) then 113 FOnErrorMessage(Format(Text, Arguments), CodePosition, FileName);76 FOnErrorMessage(Format(Text, Arguments), LastTokenPosition, FileName); 114 77 end; 115 78 … … 222 185 DoubleSpecChar: array[0..6] of string = (':=', '..', '<=', '>=', '<>', '+=', '-='); 223 186 begin 187 LastTokenPosition := CodePosition; 224 188 FNextToken := ''; 225 189 FNextTokenType := ttNone; … … 354 318 end; 355 319 356 { TPascalParser }357 358 function TPascalParser.ParseFile(Name: string): Boolean;359 var360 Parser: TPascalParser;361 NewModule: TModule;362 begin363 try364 Parser := TPascalParser.Create;365 Parser.SourceCodeText := TStringList.Create;366 Parser.ProgramCode := ProgramCode;367 Parser.OnGetSource := OnGetSource;368 if Assigned(FOnGetSource) then begin369 if FOnGetSource(Name, Parser.SourceCodeText) then begin370 Parser.Init;371 Parser.FileName := Name;372 Parser.OnErrorMessage := OnErrorMessage;373 NewModule := Parser.ParseModule(ProgramCode);374 ProgramCode.Modules.Add(NewModule);375 Result := True;376 end else Result := False;377 end else Result := False;378 finally379 Parser.SourceCodeText.Free;380 Parser.Free;381 end;382 end;383 384 procedure TPascalParser.ParseWhileDo(SourceCode: TWhileDo);385 begin386 with SourceCode do387 begin388 Expect('while');389 Condition.CommonBlock := CommonBlock;390 ParseExpression(Condition);391 Expect('do');392 Command := ParseCommand(CommonBlock);393 end;394 end;395 396 { TExpression }397 398 procedure TPascalParser.ParseExpression(SourceCode: TExpression);399 var400 Identifier: string;401 IdentifierType: TTokenType;402 NewVariable: TVariable;403 NewExpression: TExpression;404 Method: TFunction;405 Constant: TConstant;406 // Brackets: Integer;407 Expressions: TExpressionList;408 I: integer;409 II: integer;410 begin411 Expressions := TExpressionList.Create;412 Expressions.Add(TExpression.Create);413 with SourceCode do begin414 while ((NextToken <> ';') and (NextToken <> ',') and (not IsKeyWord(NextToken))) and not415 (((NextToken = ')') or (NextToken = ']'))) and not (NextTokenType = ttEndOfFile) do begin416 IdentifierType := NextTokenType;417 Identifier := ReadCode;418 if Identifier = '(' then begin419 // Subexpression420 with TExpression(Expressions.Last) do begin421 SubItems[1] := TExpression.Create;422 ParseExpression(TExpression(SubItems[1]));423 end;424 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do425 begin426 CommonBlock := SourceCode.CommonBlock;427 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1];428 end;429 Expect(')');430 end else431 if IsOperator(Identifier) then begin432 // Operator433 TExpression(Expressions.Last).OperatorName := Identifier;434 TExpression(Expressions.Last).NodeType := ntOperator;435 end else436 if IsIdentificator(Identifier) then begin437 // Reference to identificator438 NewVariable := CommonBlock.Variables.Search(Identifier);439 if Assigned(NewVariable) then begin440 // Referenced variable441 with TExpression(Expressions.Last) do begin442 SubItems[1] := TExpression.Create;443 TExpression(SubItems[1]).NodeType := ntVariable;444 TExpression(SubItems[1]).Variable := NewVariable;445 end;446 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do447 begin448 CommonBlock := SourceCode.CommonBlock;449 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1];450 end;451 end else begin452 Method := CommonBlock.Functions.Search(Identifier);453 if Assigned(Method) then454 begin455 // Referenced method456 with TExpression(Expressions.Last) do begin457 SubItems[1] := TExpression.Create;458 if FNextToken = '(' then // Method with parameters459 with TExpression(SubItems[1]) do begin460 Expect('(');461 NewExpression := TExpression.Create;462 NewExpression.CommonBlock := CommonBlock;463 ParseExpression(NewExpression);464 SubItems.Add(NewExpression);465 while FNextToken = ',' do begin466 Expect(',');467 NewExpression := TExpression.Create;468 NewExpression.CommonBlock := CommonBlock;469 ParseExpression(NewExpression);470 SubItems.Add(NewExpression);471 end;472 Expect(')');473 end;474 TExpression(SubItems[1]).NodeType := ntFunction;475 TExpression(SubItems[1]).Method := Method;476 end;477 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do478 begin479 CommonBlock := SourceCode.CommonBlock;480 SubItems[0] :=481 TExpression(Expressions[Expressions.Count - 2]).SubItems[1];482 end;483 end else begin484 Constant := CommonBlock.Constants.Search(Identifier);485 if Assigned(Constant) then begin486 // Referenced constant487 with TExpression(Expressions.Last) do begin488 SubItems[1] := TExpression.Create;489 TExpression(SubItems[1]).NodeType := ntConstant;490 TExpression(SubItems[1]).Value := Constant.Value;491 end;492 with TExpression(Expressions.Items[Expressions.Add(493 TExpression.Create)]) do begin494 CommonBlock := SourceCode.CommonBlock;495 SubItems[0] :=496 TExpression(Expressions[Expressions.Count - 2]).SubItems[1];497 end;498 end else begin499 ErrorMessage(SUnknownIdentifier, [Identifier]);500 end;501 end;502 end;503 end else begin504 // Constant value505 with TExpression(Expressions.Last) do506 begin507 SubItems[1] := TExpression.Create;508 TExpression(SubItems[1]).CommonBlock := SourceCode.CommonBlock;509 TExpression(SubItems[1]).NodeType := ntConstant;510 511 if IdentifierType = ttConstantString then begin512 TExpression(SubItems[1]).Value := Identifier;513 //SetLength(TExpression(SubItems[1]).Value, Length(Identifier));514 //for I := 1 to Length(Identifier) do515 // TExpression(SubItems[1]).Value[I - 1] := Byte(Identifier[I]);516 end else begin517 TExpression(SubItems[1]).Value := StrToInt(Identifier);518 end;519 end;520 //ShowMessage(IntToStr(Expressions.Count));521 with TExpression(Expressions.Items[Expressions.Add(TExpression.Create)]) do522 begin523 CommonBlock := SourceCode.CommonBlock;524 SubItems[0] := TExpression(Expressions[Expressions.Count - 2]).SubItems[1];525 end;526 end;527 end;528 529 // Build expression tree530 for II := 0 to High(Operators) do begin531 I := 1;532 while (I < Expressions.Count - 1) do begin533 if not TExpression(Expressions[I]).Associated and534 (TExpression(Expressions[I]).OperatorName = Operators[II]) then535 begin536 TExpression(Expressions[I]).Associated := True;537 TExpression(Expressions[I - 1]).SubItems[1] := Expressions[I];538 TExpression(Expressions[I + 1]).SubItems[0] := Expressions[I];539 //Expressions.Delete(I);540 end else Inc(I);541 end;542 end;543 if Assigned(TExpression(Expressions.First).SubItems[1]) then544 Assign(TExpression(TExpression(Expressions.First).SubItems[1]));545 TExpression(Expressions.First).SubItems[1] := nil;546 //ShowMessage(IntToStr(Expressions.Count));547 if Expressions.Count > 1 then548 TExpression(Expressions[1]).SubItems[0] := nil;549 Expressions.Free;550 end;551 end;552 553 function TPascalParser.ParseCommand(SourceCode: TCommonBlock): TCommand;554 var555 Identifier: string;556 Variable: TVariable;557 Method: TFunction;558 First: TOperation;559 Second: TOperation;560 StartIndex: integer;561 LoopVariable: TVariable;562 IdentName: string;563 FunctionName: string;564 begin565 begin566 if FNextToken = 'begin' then567 begin568 Result := TBeginEnd.Create;569 TBeginEnd(Result).CommonBlock := SourceCode;570 //ShowMessage(IntToStr(Integer(SourceCode))571 // + ' ' + IntToStr(Integer(Result)));572 ParseBeginEnd(TBeginEnd(Result));573 end574 else575 if FNextToken = 'if' then576 begin577 Result := TIfThenElse.Create;578 TIfThenElse(Result).CommonBlock := SourceCode;579 ParseIfThenElse(TIfThenElse(Result));580 end581 else582 if FNextToken = 'while' then583 begin584 Result := TWhileDo.Create;585 TWhileDo(Result).CommonBlock := SourceCode;586 ParseWhileDo(TWhileDo(Result));587 end588 else589 if FNextToken = 'for' then590 begin591 Result := TForToDo.Create;592 TForToDo(Result).CommonBlock := SourceCode;593 ParseForToDo(TForToDo(Result));594 end595 else596 if IsIdentificator(FNextToken) then597 begin598 if Assigned(SourceCode.Variables.Search(FNextToken)) then599 begin600 // Variable assignment601 Result := TAssignment.Create;602 TAssignment(Result).CommonBlock := SourceCode;603 IdentName := ReadCode;604 TAssignment(Result).Target := SourceCode.Variables.Search(IdentName);605 Expect(':=');606 TAssignment(Result).Source := TExpression.Create;607 TAssignment(Result).Source.CommonBlock := SourceCode;608 ParseExpression(TAssignment(Result).Source);609 end610 else611 if Assigned(SourceCode.Functions.Search(FNextToken)) then612 begin613 // Function call614 FunctionName := ReadCode;615 Result := TFunctionCall.Create;616 TFunctionCall(Result).CommonBlock := SourceCode;617 TFunctionCall(Result).FunctionRef := SourceCode.Functions.Search(FunctionName);618 if FNextToken = '(' then619 begin620 Expect('(');621 with TFunctionCall(Result) do622 begin623 ParameterExpression.Add(TExpression.Create);624 TExpression(ParameterExpression.Last).CommonBlock := SourceCode;625 ParseExpression(TExpression(ParameterExpression.Last));626 end;627 Expect(')');628 end;629 end630 else631 begin632 Result := nil;633 ErrorMessage(SUnknownIdentifier, [ReadCode]);634 end;635 end636 else637 if FNextToken = ';' then638 else639 begin640 Result := nil;641 ErrorMessage(SIllegalExpression, [ReadCode]);642 end;643 end;644 end;645 646 { TParserModule }647 648 function TPascalParser.ParseModule(ProgramCode: TProgram): TModule;649 begin650 Self.ProgramCode := ProgramCode;651 if FNextToken = 'unit' then begin652 Result := TModuleUnit.Create;653 Result.ParentProgram := ProgramCode;654 ParseUnit(TModuleUnit(Result));655 end else begin //if FNextToken = 'program' then begin656 Result := TModuleProgram.Create;657 Result.ParentProgram := ProgramCode;658 ParseProgram(TModuleProgram(Result));659 end;660 end;661 662 procedure TPascalParser.ParseProgram(SourceCode: TModuleProgram);663 var664 Identifier: string;665 begin666 with SourceCode do begin667 if FNextToken = 'program' then begin668 Expect('program');669 Name := ReadCode;670 Expect(';');671 end else Name := '';672 673 // Uses section674 if FNextToken = 'uses' then675 ParseUses(UsedModules, False);676 677 ParseCommonBlock(Body, '.');678 end;679 end;680 681 procedure TPascalParser.ParseUnit(SourceCode: TModuleUnit);682 var683 NewModule: TModule;684 begin685 Expect('unit');686 with Sourcecode do begin687 Name := ReadCode;688 end;689 Expect(';');690 691 ParseUnitInterface(SourceCode);692 if FNextToken = 'implementation' then693 ParseUnitImplementation(SourceCode);694 end;695 696 procedure TPascalParser.ParseUnitInterface(SourceCode: TModuleUnit);697 begin698 Expect('interface');699 // Uses section700 if FNextToken = 'uses' then701 ParseUses(SourceCode.UsedModules, True);702 703 ParseCommonBlockInterface(SourceCode.Body);704 end;705 706 procedure TPascalParser.ParseUnitImplementation(SourceCode: TModuleUnit);707 begin708 Expect('implementation');709 710 // Uses section711 if FNextToken = 'uses' then712 ParseUses(SourceCode.UsedModules, False);713 714 ParseCommonBlock(SourceCode.Body, '.');715 end;716 717 { TParserCommonBlock }718 719 procedure TPascalParser.ParseCommonBlock(SourceCode: TCommonBlock;720 EndSymbol: char = ';');721 begin722 with SourceCode do723 begin724 while FNextToken <> EndSymbol do725 begin726 if FNextToken = 'var' then727 ParseVariableList(Variables)728 else if FNextToken = 'const' then729 ParseConstantList(Constants)730 else if FNextToken = 'type' then731 ParseTypeList(Types)732 else if FNextToken = 'procedure' then733 ParseFunctionList(Functions)734 else if FNextToken = 'function' then735 ParseFunctionList(Functions)736 else737 begin738 ParseBeginEnd(Code);739 Break;740 end;741 end;742 Expect(EndSymbol);743 end;744 end;745 746 procedure TPascalParser.ParseCommonBlockInterface(SourceCode: TCommonBlock);747 begin748 with SourceCode do begin749 while (FNextToken <> 'implementation') and (FNextTokenType <> ttEndOfFile) do begin750 if FNextToken = 'var' then751 ParseVariableList(Variables)752 else if FNextToken = 'const' then753 ParseConstantList(Constants, True)754 else if FNextToken = 'type' then755 ParseTypeList(Types, True)756 else if FNextToken = 'procedure' then757 ParseFunctionList(Functions, True)758 else if FNextToken = 'function' then759 ParseFunctionList(Functions, True)760 else begin761 ErrorMessage(SUnknownIdentifier, [FNextToken]);762 ReadCode;763 end;764 end;765 end;766 end;767 768 { TParserBeginEnd }769 770 procedure TPascalParser.ParseBeginEnd(SourceCode: TBeginEnd);771 var772 NewCommand: TCommand;773 begin774 //ShowMessage(IntToStr(Integer(SourceCode)) + ' ' + IntToStr(Integer(SourceCode.CommonBlock)));775 with SourceCode do776 begin777 Expect('begin');778 while (FNextToken <> 'end') and (FNextTokenType <> ttEndOfFile) do779 begin780 NewCommand := ParseCommand(CommonBlock);781 if Assigned(NewCommand) then782 Commands.Add(NewCommand);783 //ShowMessage(NextCode);784 if FNextToken = ';' then785 ReadCode;786 end;787 Expect('end');788 end;789 end;790 791 { TParserParseFunctionList }792 793 procedure TPascalParser.ParseFunctionList(SourceCode: TFunctionList; Exported: Boolean = False);794 var795 Identifiers: TStringList;796 NewValueType: TType;797 TypeName: string;798 VariableName: string;799 Variable: TParameter;800 I: integer;801 begin802 Identifiers := TStringList.Create;803 with SourceCode do begin804 with TFunction(Items[Add(TFunction.Create)]) do begin805 Parent := SourceCode.Parent;806 if FNextToken = 'procedure' then807 begin808 Expect('procedure');809 HaveResult := False;810 end811 else812 begin813 Expect('function');814 HaveResult := True;815 end;816 Name := ReadCode;817 818 if FNextToken = '(' then819 begin820 Expect('(');821 while FNextToken <> ')' do822 begin823 // while IsIdentificator(NextCode) do begin824 with TParameterList(Parameters) do825 begin826 VariableName := ReadCode;827 Variable := Search(VariableName);828 if not Assigned(Variable) then829 begin830 Identifiers.Add(VariableName);831 while FNextToken = ',' do832 begin833 Expect(',');834 Identifiers.Add(ReadCode);835 end;836 end837 else838 ErrorMessage(SRedefineIdentifier, [VariableName]);839 Expect(':');840 TypeName := ReadCode;841 NewValueType := Parent.Types.Search(TypeName);842 if not Assigned(NewValueType) then843 ErrorMessage(STypeNotDefined, [TypeName])844 else845 for I := 0 to Identifiers.Count - 1 do846 with TParameter(Items[Add(TParameter.Create)]) do847 begin848 Name := Identifiers[I];849 ValueType := NewValueType;850 end;851 end;852 end;853 Expect(')');854 855 // Parse function result type856 if HaveResult then857 begin858 Expect(':');859 TypeName := ReadCode;860 NewValueType := Parent.Types.Search(TypeName);861 if not Assigned(NewValueType) then862 ErrorMessage(STypeNotDefined, [TypeName])863 else864 begin865 ResultType := NewValueType;866 with TVariable(Parent.Variables.Items[Parent.Variables.Add(867 TVariable.Create)]) do868 begin869 Name := 'Result';870 ValueType := NewValueType;871 end;872 end;873 end;874 end;875 Expect(';');876 877 // Check directives878 if FNextToken = 'internal' then begin879 Expect('internal');880 Expect(';');881 System := True;882 end;883 end;884 885 if not Exported then ParseCommonBlock(TFunction(Last));886 end;887 Identifiers.Destroy;888 end;889 890 { TParserIfThenElse }891 892 procedure TPascalParser.ParseIfThenElse(SourceCode: TIfThenElse);893 begin894 with Sourcecode do895 begin896 Expect('if');897 Condition.CommonBlock := CommonBlock;898 ParseExpression(Condition);899 Expect('then');900 Command := ParseCommand(CommonBlock);901 if FNextToken = 'else' then902 begin903 Expect('else');904 ElseCommand := ParseCommand(CommonBlock);905 end;906 end;907 end;908 909 procedure TPascalParser.ParseForToDo(SourceCode: TForToDo);910 var911 VariableName: string;912 begin913 with SourceCode do914 begin915 Expect('for');916 VariableName := ReadCode;917 ControlVariable := SourceCode.CommonBlock.Variables.Search(VariableName);918 if not Assigned(ControlVariable) then919 ErrorMessage(SUndefinedVariable, [VariableName]);920 Expect(':=');921 Start.CommonBlock := CommonBlock;922 ParseExpression(Start);923 Expect('to');924 Stop.CommonBlock := CommonBlock;925 ParseExpression(Stop);926 Expect('do');927 Command := ParseCommand(CommonBlock);928 end;929 end;930 931 { TParserVariableList }932 933 procedure TPascalParser.ParseVariableList(SourceCode: TVariableList; Exported: Boolean = False);934 var935 Identifiers: TStringList;936 NewValueType: TType;937 TypeName: string;938 VariableName: string;939 Variable: TVariable;940 I: integer;941 begin942 Identifiers := TStringList.Create;943 with SourceCode do944 begin945 Expect('var');946 while IsIdentificator(FNextToken) and (FNextTokenType <> ttEndOfFile) do947 begin948 Identifiers.Clear;949 VariableName := ReadCode;950 Variable := Search(VariableName);951 if not Assigned(Variable) then952 begin953 Identifiers.Add(VariableName);954 while FNextToken = ',' do955 begin956 Expect(',');957 Identifiers.Add(ReadCode);958 end;959 end960 else961 ErrorMessage(SRedefineIdentifier, [VariableName]);962 Expect(':');963 TypeName := ReadCode;964 NewValueType := Parent.Types.Search(TypeName);965 if NewValueType = nil then966 ErrorMessage(STypeNotDefined, [TypeName])967 else968 for I := 0 to Identifiers.Count - 1 do969 with TVariable(Items[Add(TVariable.Create)]) do970 begin971 Name := Identifiers[I];972 ValueType := NewValueType;973 end;974 Expect(';');975 end;976 end;977 Identifiers.Destroy;978 end;979 980 { TParserVariable }981 982 procedure TPascalParser.ParseVariable(SourceCode: TVariable; Exported: Boolean = False);983 begin984 with SourceCode do985 begin986 Name := FNextToken;987 Expect(':=');988 989 end;990 end;991 992 { TParserConstantList }993 994 procedure TPascalParser.ParseConstantList(SourceCode: TConstantList; Exported: Boolean = False);995 var996 Identifiers: TStringList;997 NewValueType: TType;998 TypeName: string;999 ConstantName: string;1000 Constant: TConstant;1001 I: integer;1002 ConstantValue: string;1003 begin1004 Identifiers := TStringList.Create;1005 with SourceCode do1006 begin1007 Expect('const');1008 while IsIdentificator(FNextToken) do1009 begin1010 ConstantName := ReadCode;1011 Constant := Search(ConstantName);1012 if not Assigned(Constant) then1013 begin1014 Identifiers.Add(ConstantName);1015 while FNextToken = ',' do1016 begin1017 Expect(',');1018 Identifiers.Add(ReadCode);1019 end;1020 end1021 else1022 ErrorMessage(SRedefineIdentifier, [ConstantName]);1023 Expect(':');1024 TypeName := ReadCode;1025 NewValueType := Parent.Types.Search(TypeName);1026 Expect('=');1027 ConstantValue := ReadCode;1028 Expect(';');1029 1030 if NewValueType = nil then1031 ErrorMessage(STypeNotDefined, [TypeName])1032 else1033 for I := 0 to Identifiers.Count - 1 do1034 with TConstant(Items[Add(TConstant.Create)]) do1035 begin1036 Name := Identifiers[I];1037 ValueType := NewValueType;1038 Value := ConstantValue;1039 end;1040 end;1041 end;1042 Identifiers.Destroy;1043 end;1044 1045 { TParserTypeList }1046 1047 procedure TPascalParser.ParseTypeList(SourceCode: TTypeList; Exported: Boolean = False);1048 var1049 NewType: TType;1050 begin1051 with SourceCode do1052 begin1053 Expect('type');1054 while IsIdentificator(FNextToken) do begin1055 NewType := ParseType(SourceCode);1056 if Assigned(NewType) then begin1057 NewType.Parent := SourceCode;1058 Add(NewType);1059 end;1060 Expect(';');1061 end;1062 end;1063 end;1064 1065 { TParserType }1066 1067 function TPascalParser.ParseType(TypeList: TTypeList; ExpectName: Boolean = True; AssignSymbol: string = '='): TType;1068 var1069 Name: string;1070 TypeName: string;1071 begin1072 //with SourceCode do1073 begin1074 if ExpectName then begin1075 Name := ReadCode;1076 Expect(AssignSymbol);1077 end;1078 if NextToken = '(' then begin1079 Result := ParseTypeEnumeration(TypeList, Name);1080 end else1081 if NextToken = 'record' then begin1082 Result := ParseTypeRecord(TypeList, Name);1083 end else1084 if NextToken = 'class' then begin1085 Expect('class');1086 Result := TTypeClass.Create;1087 TTypeClass(Result).Parent := TypeList;1088 TTypeClass(Result).Name := Name;1089 if NextToken <> ';' then begin1090 while (NextToken <> 'end') and (FNextTokenType <> ttEndOfFile) do1091 begin1092 TTypeClass(Result).Items.Add(ParseType(TypeList, True, ':'));1093 Expect(';');1094 end;1095 Expect('end');1096 end;1097 end else1098 if NextToken = 'array' then begin1099 Expect('array');1100 Result := TTypeArray.Create;1101 TTypeArray(Result).Parent := TypeList;1102 TType(Result).Name := Name;1103 if NextToken = '[' then begin1104 Expect('[');1105 TypeName := FNextToken;1106 TTypeArray(Result).IndexType := ParseType(TypeList, False);1107 if not Assigned(TTypeArray(Result).IndexType) then1108 ErrorMessage(SUndefinedType, [TypeName]);1109 Expect(']');1110 end;1111 Expect('of');1112 TypeName := FNextToken;1113 TTypeArray(Result).ItemType := ParseType(TypeList, False);1114 if not Assigned(TTypeArray(Result).ItemType) then1115 ErrorMessage(SUndefinedType, [TypeName]);1116 end else1117 if NextToken = '^' then begin1118 Expect('^');1119 Result := TTypePointer.Create;1120 TTypePointer(Result).Parent := TypeList;1121 TTypePointer(Result).Name := Name;1122 TTypePointer(Result).UsedType := ParseType(TypeList, False);1123 end else1124 if NextToken = 'type' then begin1125 Expect('type');1126 Result := TTypeInherited.Create;1127 TTypeInherited(Result).Parent := TypeList;1128 TTypeInherited(Result).Name := Name;1129 if NextToken = '(' then begin1130 Expect('(');1131 TTypeInherited(Result).UsedType := ParseType(TypeList, False);1132 Expect(')');1133 end else TTypeInherited(Result).UsedType := nil;1134 end else begin1135 TypeName := ReadCode;1136 if ExpectName then begin1137 Result := TType.Create;1138 TType(Result).Parent := TypeList;1139 TType(Result).Name := Name;1140 TType(Result).UsedType := TypeList.Search(TypeName);1141 if not Assigned(TType(Result).UsedType) then1142 ErrorMessage(SUndefinedType, [TypeName]);1143 end else begin1144 TType(Result) := TypeList.Search(TypeName);1145 if not Assigned(TType(Result)) then1146 ErrorMessage(SUndefinedType, [TypeName]);1147 end;1148 end;1149 end;1150 end;1151 1152 function TPascalParser.ParseTypeEnumeration(TypeList: TTypeList; Name: string): TType;1153 begin1154 Expect('(');1155 Result := TTypeEnumeration.Create;1156 TTypeEnumeration(Result).Parent := TypeList;1157 TTypeEnumeration(Result).Name := Name;1158 with TTypeEnumeration(Result) do1159 with TEnumItem(Items[Items.Add(TEnumItem.Create)]) do begin1160 Name := ReadCode;1161 if (NextToken = '=') and (FNextTokenType = ttConstantNumber) then begin1162 Expect('=');1163 Index := StrToInt(ReadCode);1164 end;1165 end;1166 while (NextToken = ',') and (FNextTokenType <> ttEndOfFile) do1167 begin1168 Expect(',');1169 with TTypeEnumeration(Result) do1170 with TEnumItem(Items[Items.Add(TEnumItem.Create)]) do begin1171 Name := ReadCode;1172 if (NextToken = '=') and (FNextTokenType = ttConstantNumber) then begin1173 Expect('=');1174 Index := StrToInt(ReadCode);1175 end;1176 end;1177 end;1178 Expect(')');1179 end;1180 1181 function TPascalParser.ParseTypeRecord(TypeList: TTypeList; Name: string1182 ): TType;1183 var1184 Visibility: TTypeVisibility;1185 begin1186 Visibility := tvPublic;1187 Expect('record');1188 Result := TTypeRecord.Create;1189 TTypeRecord(Result).Parent := TypeList;1190 TType(Result).Name := Name;1191 while (NextToken <> 'end') and (FNextTokenType <> ttEndOfFile) do1192 begin1193 if NextToken = 'public' then begin1194 Expect('public');1195 Visibility := tvPublic;1196 end else1197 if NextToken = 'private' then begin1198 Expect('private');1199 Visibility := tvPrivate;1200 end else1201 if NextToken = 'published' then begin1202 Expect('published');1203 Visibility := tvPublished;1204 end else1205 if NextToken = 'protected' then begin1206 Expect('protected');1207 Visibility := tvProtected;1208 end else1209 if NextToken = 'var' then1210 ParseVariableList(TTypeRecord(Result).CommonBlock.Variables)1211 else if FNextToken = 'const' then1212 ParseConstantList(TTypeRecord(Result).CommonBlock.Constants, True)1213 else if FNextToken = 'type' then1214 ParseTypeList(TTypeRecord(Result).CommonBlock.Types, True)1215 else if FNextToken = 'procedure' then1216 ParseFunctionList(TTypeRecord(Result).CommonBlock.Functions, True)1217 else if FNextToken = 'function' then1218 ParseFunctionList(TTypeRecord(Result).CommonBlock.Functions, True)1219 else begin1220 TTypeRecord(Result).CommonBlock.Types.Add(ParseType(TypeList, True, ':'));1221 TType(TTypeRecord(Result).CommonBlock.Types.Last).Visibility := Visibility;1222 end;1223 Expect(';');1224 end;1225 Expect('end');1226 end;1227 1228 constructor TPascalParser.Create;1229 begin1230 end;1231 1232 destructor TPascalParser.Destroy;1233 begin1234 inherited Destroy;1235 end;1236 1237 { TParserUsedModuleList }1238 1239 procedure TPascalParser.ParseUses(SourceCode: TUsedModuleList; AExported: Boolean = False);1240 var1241 NewUsedModule: TUsedModule;1242 begin1243 Expect('uses');1244 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do1245 begin1246 Name := ReadCode;1247 if FNextToken = 'in' then begin1248 Expect('in');1249 Location := ReadCode;1250 end else Location := Name + '.pas';1251 Module := SourceCode.ParentModule.ParentProgram.Modules.Search(Name);1252 if not Assigned(Module) then begin1253 if ParseFile(Name) then begin1254 Module := SourceCode.ParentModule.ParentProgram.Modules.Search(Name);1255 Exported := AExported;1256 end else ErrorMessage(SUnitNotFound, [Name]);1257 end;1258 end;1259 while FNextToken = ',' do begin1260 Expect(',');1261 with TUsedModule(SourceCode.Items[SourceCode.Add(TUsedModule.Create)]) do1262 begin1263 Name := ReadCode;1264 if FNextToken = 'in' then begin1265 Expect('in');1266 Location := ReadCode;1267 end else Location := Name + '.pas';1268 Module := SourceCode.ParentModule.ParentProgram.Modules.Search(Name);1269 if not Assigned(Module) then begin1270 if not ParseFile(Name) then ErrorMessage(SUnitNotFound, [Name]);1271 end;1272 end;1273 end;1274 Expect(';');1275 end;1276 1277 320 end. 1278 321
Note:
See TracChangeset
for help on using the changeset viewer.