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

📄 uidentparser.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 5 页
字号:
~result the next following token }
function TIdentifierParser.ParseConstantExpression(var ExprTokens: String;
                     EndDirectives: TAllowedExpressionDirectives = []): String;

         //keywords (identifiers) that are operators
const    Operators: array[0..10] of String =
                           ('and', 'as',  'div', 'in',  'is',
                            'mod', 'not', 'or',  'shl', 'shr',
                            'xor');


var      Expression        :String;     //the expression tokens
         Token, Token2     :String;     //a token

         Dummy             :Integer;    //index of a token


         //are we parsing an identifier-path (identifiers
         InIdentPath       :(                     //separated by dots etc.)

                             iipNo,     //no, we don't
                             iipIdent,  //yes, we just read an identifier/value
                             iipDot     //yes, we just read a dot
                            );

         ValueWasString    :Boolean;    //if the last value was a string

         //"absolute", "deprecated", "library", "platform" or etc. found?
         DirectiveFound    :Boolean;

         //a keyword found ending the expression (the statement)?
         KeyWordFound      :Boolean;
begin
 Expression := '';
 Token := ExprTokens;
 if (Token = '') and not GetToken(Token) then   //get first token
  Exception(etSyntax, 'No expression before end of file!');


 InIdentPath := iipNo;      //not parsing an identifier at the moment
 ValueWasString := False;   //the current value is no string (no value at all)
 DirectiveFound := False;   //no directive found so far
 KeyWordFound := False;     //statement not end reached

 //as long as no directive or character ending the expression
 //or a closing brace/bracket found
 while not DirectiveFound and not KeyWordFound and
       ((Length(Token) <> 1) or
        not (Token[1] in [';', ',', ':', ')', ']'])) and
       (Token <> ':=') and (Token <> '..') and
       ((LowerCase(Token) <> 'of') or (InIdentPath = iipDot)) do
  begin

   //found an identifier?
   if (Token <> '') and (Token[1] in StartIdentifierChars) and
      not IsWordIn(Token, Operators, Dummy) then
    begin
     if InIdentPath = iipIdent then
      begin
       Token2 := LowerCase(Token);
       if (not (aedAbsolute in EndDirectives) or (Token2 <> 'absolute')) and
          (not (aedIndexName in EndDirectives) or
           ((Token2 <> 'index') and (Token2 <> 'name'))) and
          (not (aedResident in EndDirectives) or (Token2 <> 'resident')) and
          (not (aedPortability in EndDirectives) or
           not IsWordIn(Token2, IdentPortability, Dummy)) and
          (not (aedProperty in EndDirectives) or
           not IsWordIn(Token2, PropertyWords, Dummy)) then
        ExceptionFmt(etSyntax,
                     'Found identifier "%s" directly after another identifier!',
                     [Token]);

       DirectiveFound := True;          //directive found, expression ended
      end
     else
      begin
       InIdentPath := iipIdent;         //we just read an identifier
       ValueWasString := False;

       Expression := Expression + ' ' + Token;
      end;
    end //if Token is an Identifier
   else
    //Token is (, [, ., or ^?
    if (length(Token) = 1) and (Token[1] in ['(', '[', '.', '^']) then
     case Token[1] of
       '.':    begin
                if InIdentPath <> iipIdent then
                 Exception(etSyntax,
                           'Found "." without identifier before it!');

                InIdentPath := iipDot;    //another identifier will be expected

                Expression := Expression + ' .';
               end; //case Token = '.'

       '(':    begin
                //braces are not allowed directly after a dot
                if InIdentPath = iipDot then
                 Exception(etSyntax,
                           'Found "(" after ".", expected identifier!');

                if InIdentPath = iipNo then  //no identifier before this?
                 begin
                  //parse everything between the braces
                  Expression := Expression + ' (';
                  repeat
                    Token2 := '';
                    Token := ParseConstantExpression(Token2);
                    Expression := Expression + ' ' + Token2 + Token;
                  until
                        (Token <> ',') and //initialization of array-constants
//                        (Token <> ':='); //named parameters (automation objects)
                        (Token <> ':') and //initialization of record-constants
                        (Token <> ';');    //initialization of record-constants

                  if Token <> ')' then
                   Exception(etSyntax, 'Expected ")" after "(", failed!');
                 end
                else
                 begin
                  //parse everything between the braces
                  Expression := Expression + ' (';
                  repeat
                    Token2 := '';
                    Token := ParseConstantExpression(Token2);
                    Expression := Expression + ' ' + Token2 + Token;
                  until
                        True;
//                        (Token <> ',');// and //parameter-list of a function-call;
//                        (Token <> ':='); //named parameters (automation objects)
//                        (Token <> ':') and //Write(abc:Width:...)
//                        (Token <> ';');    //initialization of record-constants

                  if Token <> ')' then
                   Exception(etSyntax, 'Expected ")" after "(", failed!');
                 end;

                InIdentPath := iipIdent;
                ValueWasString := False;
               end; //case Token = '('
       '[':    if InIdentPath = iipNo then //no identifier before it?
                begin                        //set-constructor
                 Expression := Expression + ' [';
                 repeat
                   Token2 := '';                 //parse all items/elements
                   Token := ParseConstantExpression(Token2);
                   Expression := Expression + ' ' + Token2 + Token;
                 until (Token <> ',') and        //separated by comma and
                       (Token <> '..');          //double-dots
                 if Token <> ']' then
                  Exception(etSyntax, 'Expected "]" after "[", failed!');
                 InIdentPath := iipIdent;
                 ValueWasString := False;
                end
               else
                begin
                 //brackets are not allowed directly after a dot
                 if InIdentPath = iipDot then
                  Exception(etSyntax,
                            'Found "[" after ".", expected identifier!');

                 Expression := Expression + ' [';
                 repeat
                   Token2 := '';                 //parse all indizes
                   Token := ParseConstantExpression(Token2);
                   Expression := Expression + ' ' + Token2 + Token;
                 until Token <> ',';             //separated by comma
                 if Token <> ']' then
                  Exception(etSyntax, 'Expected "]" after "[", failed!');

                 InIdentPath := iipIdent;
                 ValueWasString := False;
                end; //case Token = '['
       '^':    if InIdentPath = iipDot then      //dereferencing only of idents
                Exception(etSyntax, 'Found "^" after "."!')
               else
                if (InIdentPath = iipIdent) and not ValueWasString then
                 Expression := Expression + '^'
                else
                 begin           //insert control-character: ^C for #3 etc.
                  //an awfull Turbo Pascal remnant
                  if not GetToken(Token) or (length(Token) <> 1) then
                   Exception(etSyntax,
                             'Expected single character after "^" for control-sequence!');
                  if not ValueWasString then         //not in a string?
                   Expression := Expression + ' ';     //add separator
                  Expression := Expression + '^' + Token; //add the char-token
                  InIdentPath := iipIdent;           //read a value
                  ValueWasString := True;            //of type string
                 end; // case Token = '^'

     else
      raise SysUtils.Exception.Create('Error: invalid character in function-body; change and recompile DelphiDoc!');
     end //if Token is (, [, ., or ^    ;    case Token of
    else
     if (Token = '=') and (aedEqual in EndDirectives) then
      DirectiveFound := True
     else
      if (Token[1] in ['0'..'9', '.', '''', '$', '#']) or   //is a value?
         ((PascalDialect = pdFreePascal) and (Token[1] in ['&', '%'])) then
       begin
        if (InIdentPath <> iipNo) and
           (not ValueWasString or not (Token[1] in ['''', '#'])) then
         Exception(etSyntax,
                   'Found number directly after another/identifier!');
        InIdentPath := iipIdent;

        //not another part of a string?
        if not ValueWasString or not (Token[1] in ['''', '#']) then
         Expression := Expression + ' ';          //add separating space

        ValueWasString := Token[1] in ['''', '#'];  //is a string?
        if Token[1] = '#' then     //is a character-sign?
         begin
          if not GetToken(Token) or
             (not (Token[1] in ['0'..'9', '$']) and
              ((PascalDialect <> pdFreePascal) or
               not (Token[1] in ['&', '%']))) then
           Exception(etSyntax,
                     'Expected number of character after "#", failed!');
          Token := '#' + Token;      //prepend the character-sign again
         end;

        Expression := Expression + Token;         //append the token
       end
      else                   //some other operator
       begin
        InIdentPath := iipNo;      //no identifier found so far after operator
        ValueWasString := False;   //and also no string

        //merged with following ident gives a pointer
        Expression := Expression + ' ' + Token;
        //nothing further to do to handle the operator
       end;


   //if not at end of expression (by a directive), get the next token
   if not DirectiveFound then
    begin
     PushPosition;
     if not GetToken(Token) then
      Exception(etSyntax, 'Unexpected end of file in constant expression!');

     //could be a keyword? 
     KeyWordFound := (InIdentPath <> iipDot) and
                     IsWordIn(Token, TopLevelWordsFile, Dummy);

     if KeyWordFound then
      begin
       Token := '';
       PopPosition;
      end
     else
      LosePosition;
    end;

  end; //while Token not EndOfStmt


 Result := Token;          //return next (last known) token
 if (Expression <> '') and (Expression[1] <> '^') then
  begin
   assert(Expression[1] = ' ');
   Delete(Expression, 1, 1);
  end;
 ExprTokens := Expression;
end;









































{Parses a list of definitions of parameters, terminated by a closing brace ")",
 like used in in functions or function types or the list of array indices of
 properties, terminating by a closing bracket "]".
~param List            the list of parameters to which the parsed identifiers
                       should be added
~param PropertyIndices if it's a list of array indices instead of function
                       parameters }
procedure TIdentifierParser.ParseParams(List: TIdentifierList;
                                        PropertyIndices: Boolean);
var       ParamList  :TIdentifierList; //the list of parameters with same type
          Token      :String;          //a token
          //kind of the parameter (normal "", "var", "const" or "out")
          Kind       :TParameterKind;
          Param      :TParameter;      //each parameter
          TheType    :TType;           //type of the parameter
          Init       :String;          //default value
          i          :Integer;         //counter through parameters
begin
 //create list of together defined parameters (share same type etc.)
 ParamList := TIdentifierList.Create;
 try
   Token := '';
   //while list hasn't reached the end
   while ((Token <> '') or GetToken(Token)) and
         ((PropertyIndices or (Token <> ')')) and
          (not PropertyIndices or (Token <> ']'))) do
    begin
     //clear the list of parameters
     ParamList.RemoveAll(False);

     //get kind of the parameter
     Init := LowerCase(Token);
     if Init = ParameterFormalAttributNames[pkReference] then
      Kind := pkReference
     else
      if Init = ParameterFormalAttributNames[pkConstant] then
       Kind := pkConstant
      else
       if Init = ParameterFormalAttributNames[pkOut] then
        Kind := pkOut
       else
        Kind := pkNormal;
     if Kind <> pkNormal then
      if not GetToken(Token) then

⌨️ 快捷键说明

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