]> git.draconx.ca Git - gob-dx.git/blob - src/lexer.l
aabc7ade293994f01028835795228ce5b36cb5cc
[gob-dx.git] / src / lexer.l
1 /* GOB C Preprocessor
2  * Copyright (C) 1999 the Free Software Foundation.
3  *
4  * Author: George Lebl
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the  Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19  * USA.
20  */
21 %{
22
23 #include "config.h"
24 #include <glib.h>
25
26 #include "parse.h"
27 #include "main.h"
28
29 extern gboolean for_cpp;
30
31 static int parenth_depth = 0;
32 static int before_comment = INITIAL;
33 static int class_after_c = FALSE;
34 static int header_c = FALSE;
35
36 static GString *cbuf = NULL;
37 int ccode_line = 1;
38
39 int line_no = 1;
40
41 static void
42 clear_cbuf(void)
43 {
44         if(!cbuf) {
45                 cbuf = g_string_new("");
46         } else {
47                 cbuf = g_string_assign(cbuf,"");
48         }
49 }
50
51 static void
52 add_to_cbuf(char *s)
53 {
54         if(!cbuf) {
55                 cbuf = g_string_new(s);
56         } else {
57                 cbuf = g_string_append(cbuf,s);
58         }
59 }
60
61 %}
62
63 %x COMMENT
64 %x C_CODE
65 %x C_CODE_STRING
66 %x CLASS_CODE
67 %x CLASS_CODE_I
68
69 %%
70
71 <*>\n                   { line_no++; REJECT; }
72
73 <*>MOTHERFUCKER         { fprintf(stderr,"You are a bad bad person!\n"); REJECT; }
74
75 \/\/.*$                 { ; /*comment, ignore*/ }
76 <C_CODE>\/\/.*$         { add_to_cbuf(yytext); /*comment, ignore*/ }
77 <CLASS_CODE>\/\/.*$     { ; /*comment, ignore*/ }
78 <CLASS_CODE_I>\/\/.*$   { ; /*comment, ignore*/ }
79 \/\*            {BEGIN(COMMENT); before_comment = INITIAL; }
80 <C_CODE>\/\*    {
81         add_to_cbuf(yytext);
82         BEGIN(COMMENT);
83         before_comment = C_CODE;
84 }
85 <CLASS_CODE>\/\*        {BEGIN(COMMENT); before_comment = CLASS_CODE; }
86 <CLASS_CODE_I>\/\*      {BEGIN(COMMENT); before_comment = CLASS_CODE_I; }
87 <COMMENT>\*\/   {
88         if(before_comment == C_CODE) add_to_cbuf(yytext);
89         BEGIN(before_comment);
90                 }
91 <COMMENT>.      {
92         /* comment, ignore */
93         if(before_comment == C_CODE) add_to_cbuf(yytext);
94                 }
95 <COMMENT>\n     {
96         /* comment, ignore */
97         if(before_comment == C_CODE) add_to_cbuf(yytext);
98                 }
99
100 ^\%h\{          {
101                         BEGIN(C_CODE);
102                         parenth_depth = 1;
103                         class_after_c = FALSE;
104                         header_c = TRUE;
105                         clear_cbuf();
106                         ccode_line = line_no;
107                 }
108 ^\%\{           {
109                         BEGIN(C_CODE);
110                         parenth_depth = 1;
111                         class_after_c = FALSE;
112                         header_c = FALSE;
113                         clear_cbuf();
114                         ccode_line = line_no;
115                 }
116 <C_CODE>^\%\}   {
117                         BEGIN(INITIAL);
118                         yylval.cbuf = cbuf;
119                         cbuf = NULL;
120                         if(header_c)
121                                 return HCODE;
122                         else
123                                 return CCODE;
124                 }
125
126 <C_CODE>\'\{\'          { add_to_cbuf(yytext); }
127 <C_CODE>\'\\\{\'        { add_to_cbuf(yytext); }
128 <C_CODE>\'\}\'          { add_to_cbuf(yytext); }
129 <C_CODE>\'\\\}\'        { add_to_cbuf(yytext); }
130 <C_CODE>\'\"\'          { add_to_cbuf(yytext); }
131 <C_CODE>\'\\\"\'        { add_to_cbuf(yytext); }
132         
133 <C_CODE>\\.     { add_to_cbuf(yytext); }
134 <C_CODE>\"      {
135                         BEGIN(C_CODE_STRING);
136                         add_to_cbuf(yytext);
137                 }
138 <C_CODE_STRING>\\.      { add_to_cbuf(yytext); }
139 <C_CODE_STRING>\"       {
140                                 BEGIN(C_CODE);
141                                 add_to_cbuf(yytext);
142                         }
143 <C_CODE_STRING>.        { add_to_cbuf(yytext); }
144 <C_CODE_STRING>\n       { add_to_cbuf(yytext); }
145
146 <C_CODE>\{      {
147                         parenth_depth++;
148                         add_to_cbuf(yytext);
149                 }
150 <C_CODE>\}      {
151                         parenth_depth--;
152                         if(parenth_depth<0) {
153                                 REJECT;
154                         } else if(parenth_depth==0 && class_after_c) {
155                                 BEGIN(CLASS_CODE_I);
156                                 yylval.cbuf = cbuf;
157                                 cbuf = NULL;
158                                 return CCODE;
159                         }
160                         add_to_cbuf(yytext);
161                 }
162
163 <C_CODE>.       { add_to_cbuf(yytext); }
164 <C_CODE>\n      { add_to_cbuf(yytext); }
165
166 class           {
167                         BEGIN(CLASS_CODE);
168                         return CLASS;
169                 }
170
171 <CLASS_CODE,CLASS_CODE_I>class|this     {
172                         if(for_cpp) {
173                                 char *s;
174                                 s = g_strdup_printf("'%s' keyword should not "
175                                                     "be used when generating "
176                                                     "C++ code",yytext);
177                                 print_error(TRUE,s, line_no);
178                                 g_free(s);
179                         }
180                         REJECT;
181                 }
182
183 <CLASS_CODE>from        {return FROM;}
184
185 <CLASS_CODE_I>void      {return VOID;}
186 <CLASS_CODE_I>struct    {return STRUCT;}
187 <CLASS_CODE_I>union     {return UNION;}
188 <CLASS_CODE_I>enum      {return ENUM;}
189 <CLASS_CODE_I>signed    {return SIGNED;}
190 <CLASS_CODE_I>unsigned  {return UNSIGNED;}
191 <CLASS_CODE_I>long      {return LONG;}
192 <CLASS_CODE_I>short     {return SHORT;}
193 <CLASS_CODE_I>int       {return INT;}
194 <CLASS_CODE_I>float     {return FLOAT;}
195 <CLASS_CODE_I>double    {return DOUBLE;}
196 <CLASS_CODE_I>char      {return CHAR;}
197 <CLASS_CODE_I>const     {return CONST;}
198
199 <CLASS_CODE_I>\.\.\.    {return THREEDOTS;}
200
201 <CLASS_CODE_I>public    {yylval.line = line_no; return PUBLIC;}
202 <CLASS_CODE_I>private   {yylval.line = line_no; return PRIVATE;}
203 <CLASS_CODE_I>argument  {yylval.line = line_no; return ARGUMENT;}
204 <CLASS_CODE_I>virtual   {yylval.line = line_no; return VIRTUAL;}
205 <CLASS_CODE_I>signal    {yylval.line = line_no; return SIGNAL;}
206 <CLASS_CODE_I>override  {yylval.line = line_no; return OVERRIDE;}
207 <CLASS_CODE_I>onerror   {return ONERROR;}
208 <CLASS_CODE_I>0|[1-9][0-9]*|0x[0-9a-fA-F]+|0[0-7]+|[0-9]*\.[0-9]+|\.[0-9][0-9]* {
209                         yylval.id = g_strdup(yytext);
210                         return NUMBER;
211                 }
212 <CLASS_CODE,CLASS_CODE_I>:?[A-Za-z_][A-Za-z0-9_]*(:[A-Za-z0-9_]*)+      {
213                         yylval.id = g_strdup(yytext);
214                         return TYPETOKEN;
215                 }
216 <CLASS_CODE,CLASS_CODE_I>[A-Za-z_][A-Za-z0-9_]* {
217                         yylval.id = g_strdup(yytext);
218                         return TOKEN;
219                 }
220
221 <CLASS_CODE>\{  {
222                         BEGIN(CLASS_CODE_I);
223                         return '{';
224                 }
225 <CLASS_CODE_I>\{        {
226                         BEGIN(C_CODE);
227                         parenth_depth=1;
228                         class_after_c = TRUE;
229                         ccode_line = line_no;
230                         yylval.line = line_no;
231                         return '{';
232                 }
233 <CLASS_CODE_I>\}        {
234                                 BEGIN(INITIAL);
235                                 return '}';
236                         }
237
238 <CLASS_CODE,CLASS_CODE_I,INITIAL>[\t ]  ;  /*ignore*/
239
240 <*>.            {
241                         yylval.line = line_no;
242                         return yytext[0];
243                 }
244
245 <*>[\n\r]       ;  /*ignore*/