X-Git-Url: http://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/4c9cb9b99991c36920bd17e366e2128d1b22eb6e..e10d6e307623d0952f6e1f5d9fee8720ddab4808:/src/lexer.l diff --git a/src/lexer.l b/src/lexer.l index 5f9f742..d896eb2 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -22,17 +22,24 @@ #include "config.h" #include +#include #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; 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 @@ -67,23 +74,71 @@ add_to_cbuf(char *s) <*>\n { line_no++; REJECT; } +<*>MOTHERFUCKER { fprintf(stderr,"You are a bad bad person!\n"); REJECT; } + \/\/.*$ { ; /*comment, ignore*/ } -\/\/.*$ { ; /*comment, ignore*/ } +^#[ \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; +} + +\/\/.*$ { add_to_cbuf(yytext); /*comment, ignore*/ } \/\/.*$ { ; /*comment, ignore*/ } \/\/.*$ { ; /*comment, ignore*/ } \/\* {BEGIN(COMMENT); before_comment = INITIAL; } -\/\* {BEGIN(COMMENT); before_comment = C_CODE; } +\/\* { + add_to_cbuf(yytext); + BEGIN(COMMENT); + before_comment = C_CODE; +} \/\* {BEGIN(COMMENT); before_comment = CLASS_CODE; } \/\* {BEGIN(COMMENT); before_comment = CLASS_CODE_I; } -\*\/ {BEGIN(before_comment);} -. { ; /* comment, ignore */ } -\n { ; /* comment, ignore */ } +\*\/ { + if(before_comment == C_CODE) add_to_cbuf(yytext); + BEGIN(before_comment); + } +. { + /* comment, ignore */ + if(before_comment == C_CODE) add_to_cbuf(yytext); + } +\n { + /* comment, ignore */ + if(before_comment == C_CODE) add_to_cbuf(yytext); + } -^\%h\{ { +^\%(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; - header_c = TRUE; + code_type = HCODE; clear_cbuf(); ccode_line = line_no; } @@ -91,40 +146,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; } ^\%\} { 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; } \'\{\' { add_to_cbuf(yytext); } \'\\\{\' { add_to_cbuf(yytext); } \'\}\' { add_to_cbuf(yytext); } \'\\\}\' { add_to_cbuf(yytext); } +\'\"\' { add_to_cbuf(yytext); } +\'\\\"\' { add_to_cbuf(yytext); } \\. { add_to_cbuf(yytext); } \" { BEGIN(C_CODE_STRING); add_to_cbuf(yytext); } -\\. { - add_to_cbuf(yytext); - } +\\. { add_to_cbuf(yytext); } \" { BEGIN(C_CODE); add_to_cbuf(yytext); } -. { - add_to_cbuf(yytext); - } +. { add_to_cbuf(yytext); } +\n { add_to_cbuf(yytext); } \{ { parenth_depth++; @@ -147,10 +202,47 @@ add_to_cbuf(char *s) \n { add_to_cbuf(yytext); } class { + look_for_includes = 2; BEGIN(CLASS_CODE); 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|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; + } + from {return FROM;} void {return VOID;} @@ -165,9 +257,13 @@ class { float {return FLOAT;} double {return DOUBLE;} char {return CHAR;} +const {return CONST;} + +\.\.\. {return THREEDOTS;} public {yylval.line = line_no; return PUBLIC;} private {yylval.line = line_no; return PRIVATE;} +protected {yylval.line = line_no; return PROTECTED;} argument {yylval.line = line_no; return ARGUMENT;} virtual {yylval.line = line_no; return VIRTUAL;} signal {yylval.line = line_no; return SIGNAL;} @@ -186,6 +282,11 @@ class { return TOKEN; } +(\[[0-9]*\])+ { + yylval.id = g_strdup(yytext); + return ARRAY_DIM; + } + \{ { BEGIN(CLASS_CODE_I); return '{'; @@ -194,8 +295,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 '{'; } \} { @@ -203,9 +305,11 @@ class { return '}'; } -[\n\t ] ; /*ignore*/ +[\t ] ; /*ignore*/ <*>. { yylval.line = line_no; return yytext[0]; } + +<*>[\n\r] ; /*ignore*/