summaryrefslogtreecommitdiffstats
path: root/src/declinfo.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/declinfo.l')
-rw-r--r--src/declinfo.l292
1 files changed, 292 insertions, 0 deletions
diff --git a/src/declinfo.l b/src/declinfo.l
new file mode 100644
index 0000000..0f0505d
--- /dev/null
+++ b/src/declinfo.l
@@ -0,0 +1,292 @@
+/******************************************************************************
+ *
+ * $Id$
+ *
+ * Copyright (C) 1997-1999 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * All output generated with Doxygen is not covered by this license.
+ *
+ */
+
+%{
+
+/*
+ * includes
+ */
+#include <stdio.h>
+#include <iostream.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "declinfo.h"
+#include "util.h"
+
+
+#define YY_NO_UNPUT
+
+/* -----------------------------------------------------------------
+ *
+ * statics
+ */
+
+static const char * inputString;
+static int inputPosition;
+static QString scope;
+static QString className;
+static QString classTempList;
+static QString funcTempList;
+static QString type;
+static QString name;
+static QString args;
+static QString tmpType;
+static int sharpCount;
+static bool classTempListFound;
+static bool funcTempListFound;
+static QString exceptionString;
+
+static void addType()
+{
+ //printf("addType() type=`%s' scope=`%s' name=`%s'\n",
+ // type.data(),scope.data(),name.data());
+ if (name.isEmpty() && scope.isEmpty()) return;
+ if (!type.isNull()) type+=' ';
+ if (!scope.isEmpty()) type+=scope+"::";
+ type+=name;
+ scope.resize(0);
+ name.resize(0);
+}
+
+static void addTypeName()
+{
+ //printf("addTypeName() type=`%s' scope=`%s' name=`%s'\n",
+ // type.data(),scope.data(),name.data());
+ if (name.isEmpty()) return;
+ if (!type.isNull()) type+=' ';
+ type+=name;
+ name.resize(0);
+}
+
+#define YY_NEVER_INTERACTIVE 1
+
+/* -----------------------------------------------------------------
+ */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+ int c=0;
+ while( c < max_size && inputString[inputPosition] )
+ {
+ *buf = inputString[inputPosition++] ;
+ c++; buf++;
+ }
+ return c;
+}
+
+%}
+
+B [ \t]
+ID [a-z_A-Z][a-z_A-Z0-9]*
+
+%x Start
+%x Template
+%x ReadArgs
+%x Operator
+%x FuncPtr
+%x EndTemplate
+%x StripTempArgs
+%x SkipSharp
+%x ReadExceptions
+
+%%
+
+<Start>"operator" { // operator rule must be before {ID} rule
+ name += yytext;
+ BEGIN(Operator);
+ }
+<Start>(~{B}*)?{ID} {
+ addTypeName();
+ name += yytext;
+ }
+<Start>{B}*"::"{B}* { // found a scope specifier
+ if (!scope.isEmpty())
+ {
+ scope+="::"+name; // add name to scope
+ }
+ else
+ {
+ scope = name.copy(); // scope becomes name
+ }
+ name.resize(0);
+ }
+<Start>[*&]+ {
+ addType();
+ type+=yytext;
+ }
+<Start>{B}+ {
+ addType();
+ }
+<Start>{B}*"("{B}*"*" {
+ addType();
+ type+="(*";
+ }
+<Start>{B}*")" {
+ type+=")";
+ }
+<Start>{B}*"(" { // TODO: function pointers
+ args+="(";
+ BEGIN(ReadArgs);
+ }
+<Start>{B}*"[" {
+ args+="[";
+ BEGIN(ReadArgs);
+ }
+<Start>{B}*"<" {
+ name+="<";
+ sharpCount=0;
+ BEGIN(Template);
+ }
+<Template>"<" {
+ name+="<";
+ sharpCount++;
+ }
+<Template>">" {
+ name+=">";
+ if (sharpCount)
+ --sharpCount;
+ else
+ {
+ BEGIN(Start);
+ }
+ }
+<Template>. {
+ name+=*yytext;
+ }
+<Operator>{B}*"()"{B}*"<>"{B}*/"(" {
+ name+="() <>";
+ BEGIN(ReadArgs);
+ }
+<Operator>{B}*"()"{B}*/"(" {
+ name+="()";
+ BEGIN(ReadArgs);
+ }
+<Operator>[^(]*{B}*("<>"{B}*)?/"(" {
+ name+=yytext;
+ BEGIN(ReadArgs);
+ }
+<ReadArgs>"throw"{B}*"(" {
+ exceptionString="throw(";
+ BEGIN(ReadExceptions);
+ }
+<ReadArgs>. {
+ args+=*yytext;
+ }
+<ReadExceptions>. {
+ exceptionString+=*yytext;
+ }
+<*>.
+
+%%
+
+/*@ ----------------------------------------------------------------------------
+ */
+
+void parseFuncDecl(const QString &decl,QString &cl,QString &ctl,QString &t,
+ QString &n,QString &a,QString &ftl,QString &exc)
+{
+ inputString = decl;
+ //printf("Input=`%s'\n",inputString);
+ if (inputString==0) return;
+ inputPosition = 0;
+ classTempListFound = FALSE;
+ funcTempListFound = FALSE;
+ scope.resize(0);
+ className.resize(0);
+ classTempList.resize(0);
+ funcTempList.resize(0);
+ name.resize(0);
+ type.resize(0);
+ args.resize(0);
+ exceptionString.resize(0);
+ // first we try to find the type, scope, name and arguments
+ declinfoYYrestart( declinfoYYin );
+ BEGIN( Start );
+ declinfoYYlex();
+
+ cl=scope.copy();
+ int i;
+ if ((i=cl.find('<'))!=-1) // split up scope and template arguments
+ {
+ ctl=removeRedundantWhiteSpace(cl.right(cl.length()-i));
+ cl=cl.left(i);
+ }
+ n=removeRedundantWhiteSpace(name);
+ if ((i=n.find('<'))!=-1 && n.left(8)!="operator")
+ {
+ ftl=removeRedundantWhiteSpace(n.right(n.length()-i));
+ n=n.left(i);
+ }
+
+ //ctl=classTempList.copy();
+ //ftl=funcTempList.copy();
+ t=removeRedundantWhiteSpace(type);
+ a=removeRedundantWhiteSpace(args);
+ exc=removeRedundantWhiteSpace(exceptionString);
+
+ if (t.length()>0 && t.at(t.length()-1)==')')
+ {
+ a.prepend(")");
+ t=t.left(t.length()-1);
+ }
+ //printf("type=`%s' class=`%s' name=`%s' args=`%s'\n",
+ // t.data(),cl.data(),n.data(),a.data());
+
+ return;
+
+
+}
+
+extern "C" { // some bogus code to keep the compiler happy
+ int declinfoYYwrap() { return 1 ; }
+ void declinfoYYdummy() { yy_flex_realloc(0,0); }
+}
+
+#if 0
+void dumpDecl(const char *s)
+{
+ QString className;
+ QString classTNames;
+ QString type;
+ QString name;
+ QString args;
+ QString funcTNames;
+ printf("-----------------------------------------\n");
+ parseFuncDecl(s,className,classTNames,type,name,args,funcTNames);
+ printf("type=`%s' class=`%s' classTempl=`%s' name=`%s' "
+ "funcTemplateNames=`%s' args=`%s'\n",
+ type.data(),className.data(),classTNames.data(),
+ name.data(),funcTNames.data(),args.data()
+ );
+}
+
+// some test code
+int main()
+{
+ dumpDecl("A < T > :: Value * A < T > :: getValue < S > ( const A < T > & a )");
+ dumpDecl("const A<T>::Value* A<T>::getValue<S>(const A<T>&a)");
+ dumpDecl("func()");
+ dumpDecl("friend void bla<>()");
+ dumpDecl("name< T > :: operator () (int bla)");
+ dumpDecl("name< T > :: operator << (int bla)");
+ dumpDecl("name< T > :: operator << <> (int bla)");
+ dumpDecl("className::func()");
+ dumpDecl("void ( * Name < T > :: bla ) ( int, char * )");
+}
+#endif