Orb/Doxygen/src/declinfo.l
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     6  *
       
     7  * Permission to use, copy, modify, and distribute this software and its
       
     8  * documentation under the terms of the GNU General Public License is hereby 
       
     9  * granted. No representations are made about the suitability of this software 
       
    10  * for any purpose. It is provided "as is" without express or implied warranty.
       
    11  * See the GNU General Public License for more details.
       
    12  *
       
    13  * Documents produced by Doxygen are derivative works derived from the
       
    14  * input used in their production; they are not affected by this license.
       
    15  *
       
    16  */
       
    17 
       
    18 %{
       
    19 
       
    20 /*
       
    21  *	includes
       
    22  */
       
    23 #include <stdio.h>
       
    24 //#include <iostream.h>
       
    25 #include <assert.h>
       
    26 #include <ctype.h>
       
    27 
       
    28 #include "declinfo.h"
       
    29 #include "util.h"
       
    30 #include "message.h"
       
    31   
       
    32 /* -----------------------------------------------------------------
       
    33  *
       
    34  *	statics
       
    35  */
       
    36   
       
    37 static const char * inputString;
       
    38 static int	    inputPosition;
       
    39 static QCString      scope;
       
    40 static QCString      className;
       
    41 static QCString      classTempList;
       
    42 static QCString      funcTempList;
       
    43 static QCString      type;
       
    44 static QCString      name;
       
    45 static QCString      args;
       
    46 static QCString      tmpType;
       
    47 static int          sharpCount;
       
    48 static bool         classTempListFound;
       
    49 static bool         funcTempListFound;
       
    50 static QCString      exceptionString;
       
    51 static bool          insideObjC;
       
    52 
       
    53 static void addType()
       
    54 {
       
    55   //printf("addType() type=`%s' scope=`%s' name=`%s'\n",
       
    56   //       type.data(),scope.data(),name.data());
       
    57   if (name.isEmpty() && scope.isEmpty()) return;
       
    58   if (!type.isEmpty()) type+=" ";
       
    59   if (!scope.isEmpty()) type+=scope+"::";
       
    60   type+=name;
       
    61   scope.resize(0);
       
    62   name.resize(0);
       
    63 }
       
    64   
       
    65 static void addTypeName()
       
    66 {
       
    67   //printf("addTypeName() type=`%s' scope=`%s' name=`%s'\n",
       
    68   //       type.data(),scope.data(),name.data());
       
    69   if (name.isEmpty() || 
       
    70       name.at(name.length()-1)==':')  // end of Objective-C keyword => append to name not type
       
    71   {
       
    72     return;
       
    73   }
       
    74   if (!type.isEmpty()) type+=' ';
       
    75   type+=name;
       
    76   name.resize(0);
       
    77 }
       
    78   
       
    79 #define YY_NEVER_INTERACTIVE 1
       
    80   
       
    81 /* -----------------------------------------------------------------
       
    82  */
       
    83 #undef	YY_INPUT
       
    84 #define	YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
       
    85 
       
    86 static int yyread(char *buf,int max_size)
       
    87 {
       
    88     int c=0;
       
    89     while( c < max_size && inputString[inputPosition] )
       
    90     {
       
    91 	*buf = inputString[inputPosition++] ;
       
    92 	c++; buf++;
       
    93     }
       
    94     return c;
       
    95 }
       
    96 
       
    97 %}
       
    98 
       
    99 B       [ \t]
       
   100 ID	"$"?([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+)
       
   101 
       
   102 %option nounput
       
   103 %option noyywrap
       
   104 
       
   105 %x      Start
       
   106 %x	Template
       
   107 %x	ReadArgs
       
   108 %x	Operator
       
   109 %x	FuncPtr
       
   110 %x	EndTemplate
       
   111 %x	StripTempArgs
       
   112 %x	SkipSharp
       
   113 %x      ReadExceptions
       
   114 
       
   115 %%
       
   116 
       
   117 <Start>"operator"/({B}*"["{B}*"]")* 	{ // operator rule must be before {ID} rule
       
   118   				  name += yytext;
       
   119   				  BEGIN(Operator);
       
   120   				}
       
   121 <Start>{ID}{B}*"("{B}*{ID}{B}*")" { // Objective-C class categories
       
   122   				  if (!insideObjC) 
       
   123 				  {
       
   124 				    REJECT;
       
   125 				  }
       
   126 				  else 
       
   127 				  {
       
   128 				    name += yytext;
       
   129 				  }
       
   130   				}
       
   131 <Start>(~{B}*)?{ID}/({B}*"["{B}*"]")* { // the []'s are for Java, 
       
   132                                         // the / was add to deal with multi-
       
   133                                         // dimensional C++ arrays like A[][15]
       
   134   				  addTypeName();
       
   135 				  name += yytext;
       
   136   				}
       
   137 <Start>{B}*"::"{B}*		{ // found a scope specifier
       
   138  				  if (!scope.isEmpty())
       
   139 				  {
       
   140 				    scope+="::"+name; // add name to scope
       
   141 				  }
       
   142 				  else
       
   143 				  {
       
   144   				    scope = name.copy(); // scope becomes name
       
   145 				  }
       
   146 				  name.resize(0);
       
   147   				}
       
   148 <Start>{B}*":"			{ // Objective-C argument separator
       
   149   				  name+=yytext;
       
   150   				}
       
   151 <Start>[*&]+			{
       
   152   				  addType();
       
   153   				  type+=yytext;
       
   154   				}
       
   155 <Start>{B}+			{
       
   156   				  addType();
       
   157   				}
       
   158 <Start>{B}*"("({ID}"::")*{B}*[&*]({B}*("const"|"volatile"){B}+)?	{
       
   159   				  addType();
       
   160 				  QCString text=yytext;
       
   161 				  type+=text.stripWhiteSpace();
       
   162   				}
       
   163 <Start>{B}*")"			{
       
   164   				  type+=")";
       
   165   				}
       
   166 <Start>{B}*"("			{ // TODO: function pointers
       
   167   				  args+="(";
       
   168   				  BEGIN(ReadArgs);
       
   169   				}
       
   170 <Start>{B}*"["			{
       
   171   				  args+="[";
       
   172 				  BEGIN(ReadArgs);
       
   173   				}
       
   174 <Start>{B}*"<"			{
       
   175   				  name+="<";
       
   176 				  sharpCount=0;
       
   177   				  BEGIN(Template);
       
   178   				}
       
   179 <Template>"<<"			{ name+="<<"; }
       
   180 <Template>">>"			{ name+=">>"; }
       
   181 <Template>"<"			{
       
   182   				  name+="<";
       
   183   				  sharpCount++;
       
   184   				}
       
   185 <Template>">"			{
       
   186   				  name+=">";
       
   187   				  if (sharpCount)
       
   188 				    --sharpCount;
       
   189 				  else
       
   190 				  {
       
   191 				    BEGIN(Start);
       
   192 				  }
       
   193   				}
       
   194 <Template>.			{
       
   195   				  name+=*yytext;
       
   196   				}
       
   197 <Operator>{B}*"("{B}*")"{B}*"<>"{B}*/"("	{
       
   198   				  name+="() <>";
       
   199 				  BEGIN(ReadArgs);
       
   200   				}
       
   201 <Operator>{B}*"("{B}*")"{B}*/"("	{
       
   202   				  name+="()";
       
   203 				  BEGIN(ReadArgs);
       
   204   				}
       
   205 <Operator>[^(]*{B}*("<>"{B}*)?/"(" {
       
   206   				  name+=yytext;
       
   207 				  BEGIN(ReadArgs);
       
   208   				}
       
   209 <ReadArgs>"throw"{B}*"("	{
       
   210   				  exceptionString="throw(";
       
   211 				  BEGIN(ReadExceptions);
       
   212   				}
       
   213 <ReadArgs>.			{
       
   214   				  args+=*yytext;
       
   215   				}
       
   216 <ReadExceptions>.		{
       
   217   				  exceptionString+=*yytext;
       
   218   				}
       
   219 <*>.
       
   220 <*>\n
       
   221 
       
   222 %%
       
   223 
       
   224 /*@ ----------------------------------------------------------------------------
       
   225  */
       
   226 
       
   227 void parseFuncDecl(const QCString &decl,bool objC,QCString &cl,QCString &t,
       
   228                    QCString &n,QCString &a,QCString &ftl,QCString &exc)
       
   229 {
       
   230   inputString   = decl;
       
   231   //printf("Input=`%s'\n",inputString);
       
   232   if (inputString==0) return;
       
   233   inputPosition      = 0;
       
   234   classTempListFound = FALSE;
       
   235   funcTempListFound  = FALSE;
       
   236   insideObjC = objC;
       
   237   scope.resize(0);
       
   238   className.resize(0);
       
   239   classTempList.resize(0);
       
   240   funcTempList.resize(0);
       
   241   name.resize(0);
       
   242   type.resize(0);
       
   243   args.resize(0);
       
   244   exceptionString.resize(0);
       
   245   // first we try to find the type, scope, name and arguments
       
   246   declinfoYYrestart( declinfoYYin );
       
   247   BEGIN( Start );
       
   248   declinfoYYlex();
       
   249 
       
   250   //printf("type=`%s' class=`%s' name=`%s' args=`%s'\n",
       
   251   //        type.data(),scope.data(),name.data(),args.data());
       
   252 
       
   253   int nb = name.findRev('[');
       
   254   if (nb!=-1 && args.isEmpty()) // correct for [] in name ambigity (due to Java return type allowing [])
       
   255   {
       
   256     args.prepend(name.right(name.length()-nb));
       
   257     name=name.left(nb);
       
   258   }
       
   259 
       
   260 #if 0
       
   261   {
       
   262     int l=scope.length();
       
   263     int i=0;
       
   264     int skipCount=0;
       
   265     cl.resize(0);
       
   266     ctl.resize(0);
       
   267     for (i=0;i<l;i++)
       
   268     {
       
   269       char c=scope.at(i);
       
   270       if (c=='<') 
       
   271 	skipCount++;
       
   272       else if (c=='>') 
       
   273 	skipCount--;
       
   274       else if (skipCount==0) 
       
   275 	cl+=c;
       
   276     }
       
   277   }
       
   278   cl=stripTemplateSpecifiersFromScope(removeRedundantWhiteSpace(scope),FALSE); 
       
   279   ctl.resize(0);
       
   280 #endif
       
   281 
       
   282   cl=scope;
       
   283   n=removeRedundantWhiteSpace(name);
       
   284   int il,ir;
       
   285   if ((il=n.find('<'))!=-1 && (ir=n.findRev('>'))!=-1)
       
   286     // TODO: handle cases like where n="operator<< <T>" 
       
   287   {
       
   288     ftl=removeRedundantWhiteSpace(n.right(n.length()-il));
       
   289     n=n.left(il);
       
   290   }
       
   291   
       
   292   //ctl=classTempList.copy();
       
   293   //ftl=funcTempList.copy();
       
   294   t=removeRedundantWhiteSpace(type);
       
   295   a=removeRedundantWhiteSpace(args);
       
   296   exc=removeRedundantWhiteSpace(exceptionString);
       
   297   
       
   298   if (!t.isEmpty() && t.at(t.length()-1)==')') // for function pointers
       
   299   {
       
   300     a.prepend(")");
       
   301     t=t.left(t.length()-1);
       
   302   }
       
   303   //printf("type=`%s' class=`%s' name=`%s' args=`%s'\n",
       
   304   //        t.data(),cl.data(),n.data(),a.data());
       
   305 
       
   306   return;
       
   307   
       
   308   
       
   309 }
       
   310 
       
   311 //extern "C" { // some bogus code to keep the compiler happy
       
   312 //  int  declinfoYYwrap() { return 1 ; }
       
   313 //  void declinfoYYdummy() { yy_flex_realloc(0,0); } 
       
   314 //}
       
   315 
       
   316 #if 0
       
   317 void dumpDecl(const char *s)
       
   318 {
       
   319   QCString className;
       
   320   QCString classTNames;
       
   321   QCString type;
       
   322   QCString name;
       
   323   QCString args;
       
   324   QCString funcTNames;
       
   325   msg("-----------------------------------------\n");
       
   326   parseFuncDecl(s,className,classTNames,type,name,args,funcTNames);
       
   327   msg("type=`%s' class=`%s' classTempl=`%s' name=`%s' "
       
   328          "funcTemplateNames=`%s' args=`%s'\n",
       
   329 	    type.data(),className.data(),classTNames.data(),
       
   330 	    name.data(),funcTNames.data(),args.data()
       
   331 	);
       
   332 }
       
   333 
       
   334 // some test code
       
   335 int main()
       
   336 {
       
   337   dumpDecl("A < T > :: Value * A < T > :: getValue < S > ( const A < T > & a )");
       
   338   dumpDecl("const A<T>::Value* A<T>::getValue<S>(const A<T>&a)");
       
   339   dumpDecl("func()");
       
   340   dumpDecl("friend void bla<>()");
       
   341   dumpDecl("name< T > :: operator () (int bla)");
       
   342   dumpDecl("name< T > :: operator << (int bla)");
       
   343   dumpDecl("name< T > :: operator << <> (int bla)");
       
   344   dumpDecl("className::func()");
       
   345   dumpDecl("void ( * Name < T > :: bla ) ( int, char * )"); 
       
   346 }
       
   347 #endif
       
   348 
       
   349 #if !defined(YY_FLEX_SUBMINOR_VERSION) 
       
   350 //----------------------------------------------------------------------------
       
   351 extern "C" { // some bogus code to keep the compiler happy
       
   352   void declinfoYYdummy() { yy_flex_realloc(0,0); } 
       
   353 }
       
   354 #endif
       
   355