|
Packit |
1c1d7e |
/******************************************************************************
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Copyright (C) 1997-2015 by Dimitri van Heesch.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Permission to use, copy, modify, and distribute this software and its
|
|
Packit |
1c1d7e |
* documentation under the terms of the GNU General Public License is hereby
|
|
Packit |
1c1d7e |
* granted. No representations are made about the suitability of this software
|
|
Packit |
1c1d7e |
* for any purpose. It is provided "as is" without express or implied warranty.
|
|
Packit |
1c1d7e |
* See the GNU General Public License for more details.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Documents produced by Doxygen are derivative works derived from the
|
|
Packit |
1c1d7e |
* input used in their production; they are not affected by this license.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
%option never-interactive
|
|
Packit |
1c1d7e |
%option prefix="declinfoYY"
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%{
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*
|
|
Packit |
1c1d7e |
* includes
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
#include <stdio.h>
|
|
Packit |
1c1d7e |
//#include <iostream.h>
|
|
Packit |
1c1d7e |
#include <assert.h>
|
|
Packit |
1c1d7e |
#include <ctype.h>
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#include "declinfo.h"
|
|
Packit |
1c1d7e |
#include "util.h"
|
|
Packit |
1c1d7e |
#include "message.h"
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#define YY_NO_INPUT 1
|
|
Packit |
1c1d7e |
#define YY_NO_UNISTD_H 1
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/* -----------------------------------------------------------------
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* statics
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static const char * inputString;
|
|
Packit |
1c1d7e |
static int inputPosition;
|
|
Packit |
1c1d7e |
static QCString scope;
|
|
Packit |
1c1d7e |
static QCString className;
|
|
Packit |
1c1d7e |
static QCString classTempList;
|
|
Packit |
1c1d7e |
static QCString funcTempList;
|
|
Packit |
1c1d7e |
static QCString type;
|
|
Packit |
1c1d7e |
static QCString name;
|
|
Packit |
1c1d7e |
static QCString args;
|
|
Packit |
1c1d7e |
static int sharpCount;
|
|
Packit |
1c1d7e |
static bool classTempListFound;
|
|
Packit |
1c1d7e |
static bool funcTempListFound;
|
|
Packit |
1c1d7e |
static QCString exceptionString;
|
|
Packit |
1c1d7e |
static bool insideObjC;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void addType()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("addType() type=`%s' scope=`%s' name=`%s'\n",
|
|
Packit |
1c1d7e |
// type.data(),scope.data(),name.data());
|
|
Packit |
1c1d7e |
if (name.isEmpty() && scope.isEmpty()) return;
|
|
Packit |
1c1d7e |
if (!type.isEmpty()) type+=" ";
|
|
Packit |
1c1d7e |
if (!scope.isEmpty()) type+=scope+"::";
|
|
Packit |
1c1d7e |
type+=name;
|
|
Packit |
1c1d7e |
scope.resize(0);
|
|
Packit |
1c1d7e |
name.resize(0);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void addTypeName()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("addTypeName() type=`%s' scope=`%s' name=`%s'\n",
|
|
Packit |
1c1d7e |
// type.data(),scope.data(),name.data());
|
|
Packit |
1c1d7e |
if (name.isEmpty() ||
|
|
Packit |
1c1d7e |
name.at(name.length()-1)==':') // end of Objective-C keyword => append to name not type
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (!type.isEmpty()) type+=' ';
|
|
Packit |
1c1d7e |
type+=name;
|
|
Packit |
1c1d7e |
name.resize(0);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#define YY_NEVER_INTERACTIVE 1
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/* -----------------------------------------------------------------
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
#undef YY_INPUT
|
|
Packit |
1c1d7e |
#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static int yyread(char *buf,int max_size)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int c=0;
|
|
Packit |
1c1d7e |
while( c < max_size && inputString[inputPosition] )
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
*buf = inputString[inputPosition++] ;
|
|
Packit |
1c1d7e |
c++; buf++;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return c;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
B [ \t]
|
|
Packit |
1c1d7e |
ID "$"?([a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*)|(@[0-9]+)
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%option nounput
|
|
Packit |
1c1d7e |
%option noyywrap
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%x Start
|
|
Packit |
1c1d7e |
%x Template
|
|
Packit |
1c1d7e |
%x ReadArgs
|
|
Packit |
1c1d7e |
%x Operator
|
|
Packit |
1c1d7e |
%x FuncPtr
|
|
Packit |
1c1d7e |
%x EndTemplate
|
|
Packit |
1c1d7e |
%x StripTempArgs
|
|
Packit |
1c1d7e |
%x SkipSharp
|
|
Packit |
1c1d7e |
%x ReadExceptions
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%%
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<Start>"operator"/({B}*"["{B}*"]")* { // operator rule must be before {ID} rule
|
|
Packit |
1c1d7e |
name += yytext;
|
|
Packit |
1c1d7e |
BEGIN(Operator);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>{ID}{B}*"("{B}*{ID}{B}*")" { // Objective-C class categories
|
|
Packit |
1c1d7e |
if (!insideObjC)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
REJECT;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
name += yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>([~!]{B}*)?{ID}/({B}*"["{B}*"]")* { // the []'s are for Java,
|
|
Packit |
1c1d7e |
// the / was add to deal with multi-
|
|
Packit |
1c1d7e |
// dimensional C++ arrays like A[][15]
|
|
Packit |
1c1d7e |
// the leading ~ is for a destructor
|
|
Packit |
1c1d7e |
// the leading ! is for a C++/CLI finalizer (see bug 456475 and 635198)
|
|
Packit |
1c1d7e |
addTypeName();
|
|
Packit |
1c1d7e |
name += yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>{B}*"::"{B}* { // found a scope specifier
|
|
Packit |
1c1d7e |
if (!scope.isEmpty())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
scope+="::"+name; // add name to scope
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
scope = name.copy(); // scope becomes name
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
name.resize(0);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>{B}*":" { // Objective-C argument separator
|
|
Packit |
1c1d7e |
name+=yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>[*&]+ {
|
|
Packit |
1c1d7e |
addType();
|
|
Packit |
1c1d7e |
type+=yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>{B}+ {
|
|
Packit |
1c1d7e |
addType();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>{B}*"("({ID}"::")*{B}*[&*]({B}*("const"|"volatile"){B}+)? {
|
|
Packit |
1c1d7e |
addType();
|
|
Packit |
1c1d7e |
QCString text=yytext;
|
|
Packit |
1c1d7e |
type+=text.stripWhiteSpace();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>{B}*")" {
|
|
Packit |
1c1d7e |
type+=")";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>{B}*"(" { // TODO: function pointers
|
|
Packit |
1c1d7e |
args+="(";
|
|
Packit |
1c1d7e |
BEGIN(ReadArgs);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>{B}*"[" {
|
|
Packit |
1c1d7e |
args+="[";
|
|
Packit |
1c1d7e |
BEGIN(ReadArgs);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Start>{B}*"<" {
|
|
Packit |
1c1d7e |
name+="<";
|
|
Packit |
1c1d7e |
sharpCount=0;
|
|
Packit |
1c1d7e |
BEGIN(Template);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Template>"<<" { name+="<<"; }
|
|
Packit |
1c1d7e |
<Template>">>" { name+=">>"; }
|
|
Packit |
1c1d7e |
<Template>"<" {
|
|
Packit |
1c1d7e |
name+="<";
|
|
Packit |
1c1d7e |
sharpCount++;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Template>">" {
|
|
Packit |
1c1d7e |
name+=">";
|
|
Packit |
1c1d7e |
if (sharpCount)
|
|
Packit |
1c1d7e |
--sharpCount;
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
BEGIN(Start);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Template>. {
|
|
Packit |
1c1d7e |
name+=*yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Operator>{B}*"("{B}*")"{B}*"<>"{B}*/"(" {
|
|
Packit |
1c1d7e |
name+="() <>";
|
|
Packit |
1c1d7e |
BEGIN(ReadArgs);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Operator>{B}*"("{B}*")"{B}*/"(" {
|
|
Packit |
1c1d7e |
name+="()";
|
|
Packit |
1c1d7e |
BEGIN(ReadArgs);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Operator>[^(]*{B}*("<>"{B}*)?/"(" {
|
|
Packit |
1c1d7e |
name+=yytext;
|
|
Packit |
1c1d7e |
BEGIN(ReadArgs);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<ReadArgs>"throw"{B}*"(" {
|
|
Packit |
1c1d7e |
exceptionString="throw(";
|
|
Packit |
1c1d7e |
BEGIN(ReadExceptions);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<ReadArgs>. {
|
|
Packit |
1c1d7e |
args+=*yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<ReadExceptions>. {
|
|
Packit |
1c1d7e |
exceptionString+=*yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<*>.
|
|
Packit |
1c1d7e |
<*>\n
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%%
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*@ ----------------------------------------------------------------------------
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void parseFuncDecl(const QCString &decl,bool objC,QCString &cl,QCString &t,
|
|
Packit |
1c1d7e |
QCString &n,QCString &a,QCString &ftl,QCString &exc)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
printlex(yy_flex_debug, TRUE, __FILE__, NULL);
|
|
Packit |
1c1d7e |
inputString = decl;
|
|
Packit |
1c1d7e |
//printf("Input=`%s'\n",inputString);
|
|
Packit |
1c1d7e |
if (inputString==0) return;
|
|
Packit |
1c1d7e |
inputPosition = 0;
|
|
Packit |
1c1d7e |
classTempListFound = FALSE;
|
|
Packit |
1c1d7e |
funcTempListFound = FALSE;
|
|
Packit |
1c1d7e |
insideObjC = objC;
|
|
Packit |
1c1d7e |
scope.resize(0);
|
|
Packit |
1c1d7e |
className.resize(0);
|
|
Packit |
1c1d7e |
classTempList.resize(0);
|
|
Packit |
1c1d7e |
funcTempList.resize(0);
|
|
Packit |
1c1d7e |
name.resize(0);
|
|
Packit |
1c1d7e |
type.resize(0);
|
|
Packit |
1c1d7e |
args.resize(0);
|
|
Packit |
1c1d7e |
exceptionString.resize(0);
|
|
Packit |
1c1d7e |
// first we try to find the type, scope, name and arguments
|
|
Packit |
1c1d7e |
declinfoYYrestart( declinfoYYin );
|
|
Packit |
1c1d7e |
BEGIN( Start );
|
|
Packit |
1c1d7e |
declinfoYYlex();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//printf("type=`%s' class=`%s' name=`%s' args=`%s'\n",
|
|
Packit |
1c1d7e |
// type.data(),scope.data(),name.data(),args.data());
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
int nb = name.findRev('[');
|
|
Packit |
1c1d7e |
if (nb!=-1 && args.isEmpty()) // correct for [] in name ambigity (due to Java return type allowing [])
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
args.prepend(name.right(name.length()-nb));
|
|
Packit |
1c1d7e |
name=name.left(nb);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#if 0
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int l=scope.length();
|
|
Packit |
1c1d7e |
int i=0;
|
|
Packit |
1c1d7e |
int skipCount=0;
|
|
Packit |
1c1d7e |
cl.resize(0);
|
|
Packit |
1c1d7e |
ctl.resize(0);
|
|
Packit |
1c1d7e |
for (i=0;i
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
char c=scope.at(i);
|
|
Packit |
1c1d7e |
if (c=='<')
|
|
Packit |
1c1d7e |
skipCount++;
|
|
Packit |
1c1d7e |
else if (c=='>')
|
|
Packit |
1c1d7e |
skipCount--;
|
|
Packit |
1c1d7e |
else if (skipCount==0)
|
|
Packit |
1c1d7e |
cl+=c;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
cl=stripTemplateSpecifiersFromScope(removeRedundantWhiteSpace(scope),FALSE);
|
|
Packit |
1c1d7e |
ctl.resize(0);
|
|
Packit |
1c1d7e |
#endif
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
cl=scope;
|
|
Packit |
1c1d7e |
n=removeRedundantWhiteSpace(name);
|
|
Packit |
1c1d7e |
int il,ir;
|
|
Packit |
1c1d7e |
if ((il=n.find('<'))!=-1 && (ir=n.findRev('>'))!=-1)
|
|
Packit |
1c1d7e |
// TODO: handle cases like where n="operator<< <T>"
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ftl=removeRedundantWhiteSpace(n.right(n.length()-il));
|
|
Packit |
1c1d7e |
n=n.left(il);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//ctl=classTempList.copy();
|
|
Packit |
1c1d7e |
//ftl=funcTempList.copy();
|
|
Packit |
1c1d7e |
t=removeRedundantWhiteSpace(type);
|
|
Packit |
1c1d7e |
a=removeRedundantWhiteSpace(args);
|
|
Packit |
1c1d7e |
exc=removeRedundantWhiteSpace(exceptionString);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (!t.isEmpty() && t.at(t.length()-1)==')') // for function pointers
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
a.prepend(")");
|
|
Packit |
1c1d7e |
t=t.left(t.length()-1);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//printf("type=`%s' class=`%s' name=`%s' args=`%s'\n",
|
|
Packit |
1c1d7e |
// t.data(),cl.data(),n.data(),a.data());
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
printlex(yy_flex_debug, FALSE, __FILE__, NULL);
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//extern "C" { // some bogus code to keep the compiler happy
|
|
Packit |
1c1d7e |
// int declinfoYYwrap() { return 1 ; }
|
|
Packit |
1c1d7e |
// void declinfoYYdummy() { yy_flex_realloc(0,0); }
|
|
Packit |
1c1d7e |
//}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#if 0
|
|
Packit |
1c1d7e |
void dumpDecl(const char *s)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QCString className;
|
|
Packit |
1c1d7e |
QCString classTNames;
|
|
Packit |
1c1d7e |
QCString type;
|
|
Packit |
1c1d7e |
QCString name;
|
|
Packit |
1c1d7e |
QCString args;
|
|
Packit |
1c1d7e |
QCString funcTNames;
|
|
Packit |
1c1d7e |
msg("-----------------------------------------\n");
|
|
Packit |
1c1d7e |
parseFuncDecl(s,className,classTNames,type,name,args,funcTNames);
|
|
Packit |
1c1d7e |
msg("type=`%s' class=`%s' classTempl=`%s' name=`%s' "
|
|
Packit |
1c1d7e |
"funcTemplateNames=`%s' args=`%s'\n",
|
|
Packit |
1c1d7e |
type.data(),className.data(),classTNames.data(),
|
|
Packit |
1c1d7e |
name.data(),funcTNames.data(),args.data()
|
|
Packit |
1c1d7e |
);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// some test code
|
|
Packit |
1c1d7e |
int main()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
dumpDecl("A < T > :: Value * A < T > :: getValue < S > ( const A < T > & a )");
|
|
Packit |
1c1d7e |
dumpDecl("const A<T>::Value* A<T>::getValue<S>(const A<T>&a)");
|
|
Packit |
1c1d7e |
dumpDecl("func()");
|
|
Packit |
1c1d7e |
dumpDecl("friend void bla<>()");
|
|
Packit |
1c1d7e |
dumpDecl("name< T > :: operator () (int bla)");
|
|
Packit |
1c1d7e |
dumpDecl("name< T > :: operator << (int bla)");
|
|
Packit |
1c1d7e |
dumpDecl("name< T > :: operator << <> (int bla)");
|
|
Packit |
1c1d7e |
dumpDecl("className::func()");
|
|
Packit |
1c1d7e |
dumpDecl("void ( * Name < T > :: bla ) ( int, char * )");
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
#endif
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#if !defined(YY_FLEX_SUBMINOR_VERSION)
|
|
Packit |
1c1d7e |
//----------------------------------------------------------------------------
|
|
Packit |
1c1d7e |
extern "C" { // some bogus code to keep the compiler happy
|
|
Packit |
1c1d7e |
void declinfoYYdummy() { yy_flex_realloc(0,0); }
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
#endif
|
|
Packit |
1c1d7e |
|