⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uidentparser.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 5 页
字号:
       ExceptionFmt(etSyntax, 'Expected name of parameter after "%s", failed!',
                    [ParameterFormalAttributNames[Kind]]);


     //read all parameters of this type
     repeat
       CheckIdentifierName(Token, 'as a parameter'); //check the name

       Param := TParameter.Create;             //create the parameter
       try
         Param.Kind := Kind;
         Param.Name := Token;                  //the first parameter
         SetPosition(Param);                   //set the positions
         Param.Scope := sLocal;
         List.AddIdent(Param);                 //and add parameter
       except
         Param.Free;
         raise;
       end;
       ParamList.AddIdent(Param);              //add to list of current params

       GetToken(Token);                        //get the "," or ":"
     until (Token <> ',') or not GetToken(Token);

     if Token = '' then
      Exception(etSyntax, 'Unexpected end in parameter-declaration!');
     //follows the type or is it not a call by value?
     if (Token <> ':') and (Kind = pkNormal) then
      Exception(etSyntax,
                'Expected ":" after name(s) of parameter(s), failed!');


     TheType := nil;                //no type for the parameter so far
     if Token = ':' then            //type of parameter specified?
      begin
       TheType := ParseType(Token, [aedEqual], ptkParameter); //read the type
       try
         TParameter(ParamList[0]).ParamType := TheType;
       except
         TheType.Free;
         raise;
       end;
       if (Token = '') and not GetToken(Token) then
        Exception(etSyntax, 'Unexpected end in parameter list-declaration!');
      end;

     Init := '';
     if Token = '=' then            //does a default value follow?
      Token := ParseConstantExpression(Init);



     for i := 0 to ParamList.Count - 1 do //assign values to all parameters
      begin
       Param := TParameter(ParamList[i]);
       Param.DefaultValue := Init;               //assign the default value
       //type specified and not already assigned?
       if (i <> 0) and assigned(TheType) then
        Param.ParamType := TType(TheType.Clone);   //assign the type
      end;


     if Token = ';' then            //semicolon for next parameter
      begin
       if not GetToken(Token) then
        Exception(etSyntax, 'Unexpected end in parameter list-declaration!');
      end
     else
      //")" or "]" for end of parameter list
      if (not PropertyIndices and (Token <> ')')) or
         (PropertyIndices and (Token <> ']')) then
       Exception(etSyntax, 'Expected ";" or ")"/"]" after parameter, failed!');

    end; //while Token <> ')' / ']'


   if (not PropertyIndices and (Token <> ')')) or //list of parameters has to
      (PropertyIndices and (Token <> ']')) then   //end with ")" / "]"
    Exception(etSyntax,
              'Expected ")"/"]" at end of parameter-definition, failed!');

 finally
  ParamList.RemoveAll(False);
  ParamList.Free;                   //free list of together defined parameters
 end;
end;











{Parses and returns a type. By parsing the first token and distinguishing the
 different kinds of types in a case-like if-then-else-if-structure the exact
 type is discovered and the object for the type is created and returned.
 Several kinds of types will be parsed by calling other functions.

 WARNING:~[br]
 When an exception is raised after parsing an enumeration type and it is freed
 again, the items may hold an invalid reference to the type. This is also the
 case for anonymous enumeration types, like used as an index for an array or
 base type of a set or pointer.

~param NextToken     out: '' or the following token
~param EndDirectives the directives to be allowed (to end constant expressions)
~param TypeKind      whether a general type, the type of a parameter or the
                     index of an array should be parsed 
~result the new object of the parsed type }
function TIdentifierParser.ParseType(var NextToken: String;
                              EndDirectives: TAllowedExpressionDirectives = [];
                              TypeKind: TParseTypeKind = ptkGeneral): TType;
         //the two kinds of function types
const    FuncKind: array[Boolean] of TFunctionKind =
                   (fkProcedure, fkFunction);
var      Token, lc        :String;     //the token and the lower case token
         Expr             :String;     //a parsed expressions
         Index            :Integer;    //a general index
         IsPacked         :Boolean;    //is the type packed?
         ArrayIndex       :TType;      //the type of the index of the array
begin
 assert(not (aedIndexName in EndDirectives));

 NextToken := '';

 if not GetToken(Token) or IsEndOfStmtToken(Token) then  //get first token
  Exception(etSyntax, 'Unexpected end in type-declaration!');

 //not possible, but compiler doesn't know, that Exception raises one
 Result := nil;

 if Token = '(' then                   //enumeration?
  begin
   Result := TEnumType.Create;
   try
     ParseEnumItemList(TEnumType(Result)); //parse enumerations items

     //end of statement not been reached?
     if GetToken(NextToken) and not IsEndOfStmtToken(NextToken) and
        ((TypeKind <> ptkArrayIndex) or (Length(NextToken) <> 1) or
         not (NextToken[1] in [',', ']'])) then
      Exception(etSyntax, 'Expecting end of statement after (...) for enumeration type, failed!');
   except
     Result.Free;
     raise;
   end;
  end
 else
  if Token = '^' then                  //pointer type?
   begin
    if TypeKind = ptkArrayIndex then
     Exception(etSyntax, 'Found a pointer type as index type of an array!');

    Result := TPointerType.Create;
    try                                          //parse base type
      TPointerType(Result).BaseType := ParseType(NextToken, EndDirectives);
    except
      Result.Free;
      raise;
    end;
   end
  else
   begin
    lc := LowerCase(Token);            //get lower case of the token
    if lc = 'string' then              //is a string?
     begin
      if TypeKind = ptkArrayIndex then
       Exception(etSyntax, 'Found a string type as index type of an array!');

      Result := TStringType.Create;
      try                                //getting size of short string
        PushPosition;
        if GetToken(Token) and (Token = '[') then
         begin
          LosePosition;

          //will contain the expression for the capacity of the string
          Expr := '';
          if ParseConstantExpression(Expr) <> ']' then  //parse capacity
           Exception(etSyntax, 'Expected "]" after "string[...", failed!');

          //save the capacity of the short string
          TStringType(Result).Size := Expr;
         end
        else
         PopPosition;
      except
        Result.Free;
        raise
      end;
     end
    else
     begin

      IsPacked := lc = 'packed';       //is a packed type?
      if IsPacked then
       begin
        if TypeKind = ptkArrayIndex then
         Exception(etSyntax,
                   'Found keyword "packed" in index type of an array!');

        if not GetToken(Token) then       //get next token
         Exception(etSyntax,
                   'Unexpected end in type-declaration after "packed"!')
        else
         lc := LowerCase(Token);          //get lower case of token
       end;

      if lc = 'file' then              //is a file type?
       begin
        if TypeKind = ptkArrayIndex then
         Exception(etSyntax, 'Found file type as index type of an array!');

        Result := TFileType.Create;
        try
          if GetToken(NextToken) and
             not IsEndOfStmtToken(NextToken, [iseOf]) then  //typed file?
           begin                           //read "of"
            if LowerCase(NextToken) <> 'of' then
             Exception(etSyntax, 'Expected "of" after "file", failed!');

                                        //parse type of the file
            TFileType(Result).FileType := ParseType(NextToken, EndDirectives);
           end;
        except
          Result.Free;
          raise
        end;
       end
      else
       if lc = 'set' then              //is a set?
        begin
         if TypeKind = ptkArrayIndex then
          Exception(etSyntax, 'Found set type as index type of an array!');

         //read of
         if not GetToken(Token) or (LowerCase(Token) <> 'of') then
          Exception(etSyntax,
                    'Unexpected end while searching for "of" after "set"!');

         Result := TSetType.Create;
         try                             //parse type of the set
           TSetType(Result).SetType := ParseType(NextToken, EndDirectives);
         except
           Result.Free;
           raise
         end;
        end
       else
        if lc = 'array' then           //is an array?
         begin
          if TypeKind = ptkArrayIndex then
           Exception(etSyntax, 'Found array type as index type of an array!');

          Result := TArrayType.Create;    //create the array type
          try
            //read indices of the array
            if GetToken(Token) and (Token = '[') then
             begin

              repeat                          //read all indices
                lc := Token;                    //save opening bracket or comma

                //read the index type
                ArrayIndex := ParseType(Token, [], ptkArrayIndex);
                try
                  if not (ArrayIndex is TIdentType) and
                     not (ArrayIndex is TSubRangeType) and
                     not (ArrayIndex is TEnumType) then
                   ExceptionFmt(etSyntax,
                                'Index type of an array is not an ordinal type (%s)!',
                                [ArrayIndex.ClassName]);

                  //add the index type to the array
                  TArrayType(Result).AddIndexType(ArrayIndex, lc = '[');
                except
                  ArrayIndex.Free;
                  raise;
                end;

                if Token = ']' then             //index-bracket closed?
                 GetToken(Token);               //get next token

              //until no further indices follow
              until (Token <> ',') and (Token <> '[');
             end;

            if LowerCase(Token) <> 'of' then  //read "of"?
             Exception(etSyntax,
                       'Expected "of" after "array" and indices, failed!');

            //is an open array parameter?
            if (TypeKind = ptkParameter) and (lc = '') then
             TypeKind := ptkArrayOfParameter    //may be an array of constants
            else
             TypeKind := ptkGeneral;            //normal type

            //read the base type of the array
            TArrayType(Result).BaseType := ParseType(NextToken, EndDirectives,
                                                     TypeKind);
          except
            Result.Free;
            raise
          end;
         end
        else                             //is a class/record-like type?
         if IsWordIn(lc, RecordTypWords, Index) then
          begin
           if TypeKind = ptkArrayIndex then
            Exception(etSyntax,
                      'Found record-like type as index type of an array!');

           PushPosition;                   //save current position
           if not GetToken(NextToken) or   //statement ends?
              IsEndOfStmtToken(NextToken, [iseEnd, iseOf]) then
            begin                           //forward-declaration of the class
             LosePosition;                   //drop saved position
             Result := TRecordType.Create;   //create the identifier
             try                             //set its kind
               TRecordType(Result).Kind := RecordTypWordKinds[Index];
             except
               Result.Free;
               raise
             end
            end
           else
            begin
             if NextToken = '' then
              Exception(etSyntax, 'Unexpected end in type-declaration!');

             if LowerCase(NextToken) = 'of' then //is class reference type?
              begin
               LosePosition;                       //drop saved position
               Result := TClassReferenceType.Create;
               try                                 //parse referenced type
                 TClassReferenceType(Result).BaseClass := ParseType(NextToken,
                                                                EndDirectives);
               except
                 Result.Free;
                 raise
               end;
              end
             else
              begin
               PopPosition;                       //restore save position
               NextToken := '';                   //and un-read the token
               //parse record-like type
               Result := ParseRecordType(RecordTypWordKinds[Index], nil);
              end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -