]> git.draconx.ca Git - gob-dx.git/blobdiff - src/lexer.l
Release 0.93.4
[gob-dx.git] / src / lexer.l
index cabafca6a919875378b1baa4f7ffc76fabdf643d..1e7de5356e1c72ba0e8a63f125d11a2abd677396 100644 (file)
 
 #include "config.h"
 #include <glib.h>
+#include <string.h>
 
+#include "treefuncs.h"
 #include "parse.h"
+#include "main.h"
+#include "util.h"
 
 static int parenth_depth = 0;
 static int before_comment = INITIAL;
-static int class_after_c = FALSE;
-static int header_c = FALSE;
+static gboolean class_after_c = FALSE;
+static int code_type = CCODE;
+
+/* GTK+ doc stuff */
+static char *gtk_doc_func = NULL; /* current gtk-doc func */
+GHashTable *gtk_doc_hash = NULL;
 
 static GString *cbuf = NULL;
 int ccode_line = 1;
 
+GList *include_files = NULL;
+/* 0 no, 1 means yes, 2+ means don't even start looking anymore */
+static int look_for_includes = 0;
+
 int line_no = 1;
 
 static void
 clear_cbuf(void)
 {
        if(!cbuf) {
-               cbuf = g_string_new("");
+               cbuf = g_string_new(NULL);
        } else {
-               cbuf = g_string_assign(cbuf,"");
+               cbuf = g_string_assign(cbuf, "");
        }
 }
 
@@ -55,6 +67,21 @@ add_to_cbuf(char *s)
        }
 }
 
+static void
+add_gtk_doc_func(void)
+{
+       if(!gtk_doc_func)
+               return;
+
+       if(!gtk_doc_hash)
+               gtk_doc_hash = g_hash_table_new(g_str_hash, g_str_equal);
+       g_hash_table_insert(gtk_doc_hash, gtk_doc_func, g_strdup(cbuf->str));
+       clear_cbuf();
+
+       gtk_doc_func = NULL;
+}
+
+
 %}
 
 %x COMMENT
@@ -62,30 +89,179 @@ add_to_cbuf(char *s)
 %x C_CODE_STRING
 %x CLASS_CODE
 %x CLASS_CODE_I
+%x GTK_DOC_BEFORE_NAME
+%x GTK_DOC
+%x GTK_DOC_LINE
+
+
 
 %%
 
 <*>\n                  { line_no++; REJECT; }
 
-<*>MOTHERFUCKER                { fprintf(stderr,"You are a bad bad person!\n"); REJECT; }
+<COMMENT>^(I(S.RI).E\(([1-9][0-9]+|[2-9]))/(\))        {
+/* Thy evil easter egg */
+#define QQ(x) long x
+#define KK(x) =atoi(__(&,,x,))
+#define MM(x,a) {QQ(i);for(i=2;i<x;i++){a}}
+#define PP(Q) (P%Q)==0
+#define ___(x,y,z) if(x z y)
+#define __(a,x,y,z) a(yytext[y] x z)
+#define O__O(a,b) fprintf(stderr,"%s is %s!\n",a,b)
+QQ(m)=1;___(__(,==,2,'P'),__(,==,5,'M'),&&
+){QQ(P)KK(8);MM(P,___(PP(i),,)m=0;)}__(,=,
+7,0);___(,,m){O__O(__( &,,8,),__(&,,2,));}
+#undef QQ
+#undef KK
+#undef MM
+#undef PP
+#undef ___
+#undef __
+#undef O__O
+REJECT;
+}
 
 \/\/.*$                        { ; /*comment, ignore*/ }
-<C_CODE>\/\/.*$                { ; /*comment, ignore*/ }
+<C_CODE>^#[ \t]*include[ \t][<"][^\n">]*[>"] {
+       if(look_for_includes==1) {
+               char *p;
+               char *file;
+               char *str = g_strdup(yytext);
+               file = strchr(str,'"');
+               if(!file) file = strchr(str,'<');
+               file++;
+               p = strchr(file,'"');
+               if(!p) p = strchr(file,'>');
+               *p = '\0';
+               include_files = g_list_prepend(include_files,g_strdup(file));
+               g_free(str);
+       }
+       REJECT;
+}
+
+<CLASS_CODE_I>\/\*\*[ \t]*$    {
+                       /* eat out gtk doc stuff */
+                       BEGIN(GTK_DOC_BEFORE_NAME);
+                       clear_cbuf();
+               }
+<GTK_DOC_BEFORE_NAME>^[ \t]*\*[ \t]*$  {
+                       /* empty doc lines */
+                       ;
+               }       
+<GTK_DOC_BEFORE_NAME>^[ \t]*\*\ [_a-zA-Z][_a-zA-Z0-9]*:?[ \t]*$        {
+                       char *p;
+                       BEGIN(GTK_DOC);
+                       p = strchr(yytext, '*');
+                       g_free(gtk_doc_func);
+                       gtk_doc_func = g_strdup(p+2);
+                       p = strchr(gtk_doc_func, ':');
+                       if(p) *p='\0';
+                       g_strstrip(gtk_doc_func);
+               }
+<GTK_DOC_BEFORE_NAME>\*\/      {
+                       BEGIN(CLASS_CODE_I);
+               }
+<GTK_DOC_BEFORE_NAME>. {
+                       BEGIN(COMMENT);
+                       before_comment = CLASS_CODE_I;
+               }
+<GTK_DOC>^[ \t]*\*[ \t]*$      {
+                       /* empty doc lines */
+                       add_to_cbuf(" *\n");
+               }       
+<GTK_DOC>^[ \t]*\*?\*\/        {
+                       BEGIN(CLASS_CODE_I);
+                       add_gtk_doc_func();
+               }
+<GTK_DOC>^[ \t]*\*\    {
+                       fflush(stdout);
+                       add_to_cbuf(" * ");
+                       BEGIN(GTK_DOC_LINE);
+               }
+<GTK_DOC>\*\/  {
+                       BEGIN(CLASS_CODE_I);
+               }
+<GTK_DOC>.     {
+                       BEGIN(COMMENT);
+                       before_comment = CLASS_CODE_I;
+               }
+<GTK_DOC_LINE>\*\/     {
+                       BEGIN(CLASS_CODE_I);
+                       add_to_cbuf("\n");
+                       add_gtk_doc_func();
+               }
+<GTK_DOC_LINE>.$       {
+                       BEGIN(GTK_DOC);
+                       add_to_cbuf(yytext);
+                       add_to_cbuf("\n");
+               }
+<GTK_DOC_LINE>.        {
+                       fflush(stdout);
+                       add_to_cbuf(yytext);
+               }
+
+<C_CODE>\/\/.*$                { add_to_cbuf(yytext); /*comment, ignore*/ }
 <CLASS_CODE>\/\/.*$    { ; /*comment, ignore*/ }
 <CLASS_CODE_I>\/\/.*$  { ; /*comment, ignore*/ }
 \/\*           {BEGIN(COMMENT); before_comment = INITIAL; }
-<C_CODE>\/\*   {BEGIN(COMMENT); before_comment = C_CODE; }
+<C_CODE>\/\*   {
+       add_to_cbuf(yytext);
+       BEGIN(COMMENT);
+       before_comment = C_CODE;
+}
 <CLASS_CODE>\/\*       {BEGIN(COMMENT); before_comment = CLASS_CODE; }
 <CLASS_CODE_I>\/\*     {BEGIN(COMMENT); before_comment = CLASS_CODE_I; }
-<COMMENT>\*\/  {BEGIN(before_comment);}
-<COMMENT>.     { ; /* comment, ignore */ }
-<COMMENT>\n    { ; /* comment, ignore */ }
+<COMMENT>\*\/  {
+       if(before_comment == C_CODE) add_to_cbuf(yytext);
+       BEGIN(before_comment);
+               }
+<COMMENT>.     {
+       /* comment, ignore */
+       if(before_comment == C_CODE) add_to_cbuf(yytext);
+               }
+<COMMENT>\n    {
+       /* comment, ignore */
+       if(before_comment == C_CODE) add_to_cbuf(yytext);
+               }
 
-^\%h\{         {
+^\%(a|all)\{           {
+                       BEGIN(C_CODE);
+                       parenth_depth = 1;
+                       class_after_c = FALSE;
+                       code_type = ACODE;
+                       clear_cbuf();
+                       ccode_line = line_no;
+               }
+^\%(at|alltop)\{               {
                        BEGIN(C_CODE);
                        parenth_depth = 1;
                        class_after_c = FALSE;
-                       header_c = TRUE;
+                       code_type = ATCODE;
+                       clear_cbuf();
+                       ccode_line = line_no;
+               }
+
+^\%(ht|headertop)\{            {
+                       BEGIN(C_CODE);
+                       parenth_depth = 1;
+                       class_after_c = FALSE;
+                       code_type = HTCODE;
+                       clear_cbuf();
+                       ccode_line = line_no;
+               }
+^\%(ph|privateheader)\{                {
+                       BEGIN(C_CODE);
+                       parenth_depth = 1;
+                       class_after_c = FALSE;
+                       code_type = PHCODE;
+                       clear_cbuf();
+                       ccode_line = line_no;
+               }
+^\%(h|header)\{                {
+                       BEGIN(C_CODE);
+                       parenth_depth = 1;
+                       class_after_c = FALSE;
+                       code_type = HCODE;
                        clear_cbuf();
                        ccode_line = line_no;
                }
@@ -93,40 +269,40 @@ add_to_cbuf(char *s)
                        BEGIN(C_CODE);
                        parenth_depth = 1;
                        class_after_c = FALSE;
-                       header_c = FALSE;
+                       code_type = CCODE;
                        clear_cbuf();
                        ccode_line = line_no;
+                       if(look_for_includes==0)
+                               look_for_includes=1;
                }
 <C_CODE>^\%\}  {
                        BEGIN(INITIAL);
                        yylval.cbuf = cbuf;
                        cbuf = NULL;
-                       if(header_c)
-                               return HCODE;
-                       else
-                               return CCODE;
+                       if(look_for_includes==1)
+                               look_for_includes=0;
+                       return code_type;
                }
 
 <C_CODE>\'\{\'         { add_to_cbuf(yytext); }
 <C_CODE>\'\\\{\'       { add_to_cbuf(yytext); }
 <C_CODE>\'\}\'         { add_to_cbuf(yytext); }
 <C_CODE>\'\\\}\'       { add_to_cbuf(yytext); }
+<C_CODE>\'\"\'         { add_to_cbuf(yytext); }
+<C_CODE>\'\\\"\'       { add_to_cbuf(yytext); }
        
 <C_CODE>\\.    { add_to_cbuf(yytext); }
 <C_CODE>\"     {
                        BEGIN(C_CODE_STRING);
                        add_to_cbuf(yytext);
                }
-<C_CODE_STRING>\\.     {
-                               add_to_cbuf(yytext);
-                       }
+<C_CODE_STRING>\\.     { add_to_cbuf(yytext); }
 <C_CODE_STRING>\"      {
                                BEGIN(C_CODE);
                                add_to_cbuf(yytext);
                        }
-<C_CODE_STRING>.       {
-                               add_to_cbuf(yytext);
-                       }
+<C_CODE_STRING>.       { add_to_cbuf(yytext); }
+<C_CODE_STRING>\n      { add_to_cbuf(yytext); }
 
 <C_CODE>\{     {
                        parenth_depth++;
@@ -149,10 +325,55 @@ add_to_cbuf(char *s)
 <C_CODE>\n     { add_to_cbuf(yytext); }
 
 class          {
+                       static int found_classes = 0;
+                       look_for_includes = 2;
                        BEGIN(CLASS_CODE);
+
+                       if(++found_classes > 1) {
+                               print_error(FALSE, 
+                                           "Only one class per file allowed",
+                                           line_no);
+                       }
+
                        return CLASS;
                }
 
+^[ \t]*requires[ \t]+[0-9]+\.[0-9]+\.[0-9]+[\t ]*$     {
+                       int maj = 0,min = 0,pl = 0;
+                       int rmaj = 0,rmin = 0,rpl = 0;
+                       char *p;
+                       
+                       sscanf(VERSION,"%d.%d.%d",&rmaj,&rmin,&rpl);
+                       p = strchr(yytext,'r');
+                       g_assert(p); /* we MUST have found it */
+                       sscanf(p,"requires %d.%d.%d",&maj,&min,&pl);
+                       if(rmaj < maj ||
+                          (rmaj == maj && rmin < min) ||
+                          (rmaj == maj && rmin == min && rpl < pl)) {
+                               char *s;
+                               s = g_strdup_printf(
+                                   "GOB version %d.%d.%d required "
+                                   "(this is %s)\n"
+                                   "To upgrade your gob, see: "
+                                   "http://www.5z.com/jirka/gob.html",
+                                   maj,min,pl,VERSION);
+                               print_error(FALSE, s, line_no);
+                               g_free(s);
+                       }
+               }
+
+<CLASS_CODE,CLASS_CODE_I>class|this    {
+                       if(for_cpp) {
+                               char *s;
+                               s = g_strdup_printf("'%s' keyword should not "
+                                                   "be used when generating "
+                                                   "C++ code", yytext);
+                               print_error(TRUE, s, line_no);
+                               g_free(s);
+                       }
+                       REJECT;
+               }
+
 <CLASS_CODE>from       {return FROM;}
 
 <CLASS_CODE_I>void     {return VOID;}
@@ -173,16 +394,23 @@ class             {
 
 <CLASS_CODE_I>public   {yylval.line = line_no; return PUBLIC;}
 <CLASS_CODE_I>private  {yylval.line = line_no; return PRIVATE;}
+<CLASS_CODE_I>protected        {yylval.line = line_no; return PROTECTED;}
+<CLASS_CODE_I>classwide        {yylval.line = line_no; return CLASSWIDE;}
 <CLASS_CODE_I>argument {yylval.line = line_no; return ARGUMENT;}
 <CLASS_CODE_I>virtual  {yylval.line = line_no; return VIRTUAL;}
 <CLASS_CODE_I>signal   {yylval.line = line_no; return SIGNAL;}
 <CLASS_CODE_I>override {yylval.line = line_no; return OVERRIDE;}
-<CLASS_CODE_I>onerror  {return ONERROR;}
 <CLASS_CODE_I>0|[1-9][0-9]*|0x[0-9a-fA-F]+|0[0-7]+|[0-9]*\.[0-9]+|\.[0-9][0-9]*        {
                        yylval.id = g_strdup(yytext);
                        return NUMBER;
                }
-<CLASS_CODE,CLASS_CODE_I>:?[A-Za-z_][A-Za-z0-9_]*(:[A-Za-z0-9_]*)+     {
+<CLASS_CODE,CLASS_CODE_I>[A-Za-z_][A-Za-z0-9_]*(:[A-Za-z0-9_]*)+       {
+                       /* this one is for a classname with a namespace */
+                       yylval.id = g_strdup(yytext);
+                       return TYPETOKEN;
+               }
+<CLASS_CODE,CLASS_CODE_I>:[A-Za-z_][A-Za-z0-9_]*(:[A-Za-z0-9_]*)*      {
+                       /* this is for a classname with an empty namespace */
                        yylval.id = g_strdup(yytext);
                        return TYPETOKEN;
                }
@@ -191,6 +419,11 @@ class              {
                        return TOKEN;
                }
 
+<CLASS_CODE_I>(\[[0-9]*\])+    {
+                       yylval.id = g_strdup(yytext);
+                       return ARRAY_DIM;
+               }
+
 <CLASS_CODE>\{ {
                        BEGIN(CLASS_CODE_I);
                        return '{';
@@ -199,8 +432,9 @@ class               {
                        BEGIN(C_CODE);
                        parenth_depth=1;
                        class_after_c = TRUE;
-                       ccode_line = line_no;
                        yylval.line = line_no;
+                       clear_cbuf();
+                       ccode_line = line_no;
                        return '{';
                }
 <CLASS_CODE_I>\}       {
@@ -208,9 +442,11 @@ class              {
                                return '}';
                        }
 
-<CLASS_CODE,CLASS_CODE_I,INITIAL>[\n\t ]       ;  /*ignore*/
+<CLASS_CODE,CLASS_CODE_I,INITIAL>[\t ] ;  /*ignore*/
 
 <*>.           {
                        yylval.line = line_no;
                        return yytext[0];
                }
+
+<*>[\n\r]      ;  /*ignore*/