]> git.buserror.net Git - polintos/scott/priv.git/blob - idlcomp/scan.lex
Add copyright to idlcomp files that were previously just "Written by:".
[polintos/scott/priv.git] / idlcomp / scan.lex
1 %{
2 // IDL/CDL scanner
3 //
4 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
5 // 
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of
7 // this software and associated documentation files (the "Software"), to deal with
8 // the Software without restriction, including without limitation the rights to
9 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10 // of the Software, and to permit persons to whom the Software is furnished to do
11 // so, subject to the following condition:
12 // 
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
15 // 
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
22 // SOFTWARE.
23
24 #include <idlc.h>
25 #include <parser.h>
26
27 #include <string.h> 
28 #include <string>
29 #include <limits.h>
30 #include <stdlib.h>
31 #include <cmath>
32 #include <cerrno>
33
34 int curline, comment_level=0;
35 %}
36
37 %x COMMENT
38 %x STRING
39 %x LINECOMMENT
40 %%
41
42 interface   return TOK_IFACE;
43 const       return TOK_CONST;
44 \(          return '(';
45 \)          return ')';
46 bool        return TOK_BOOL;
47 ushort      return TOK_USHORT;
48 uint        return TOK_UINT;
49 ulong       return TOK_ULONG;
50 short       return TOK_SHORT;
51 int         return TOK_INT;
52 long        return TOK_LONG;
53 fshort      return TOK_FSHORT;
54 flong       return TOK_FLONG;
55 struct      return TOK_STRUCT;
56 char        return TOK_CHAR;
57 octet       return TOK_OCTET;
58 \{          return '{';
59 \}          return '}';
60 :           return ':';
61 \[          return '[';
62 \]          return ']';
63 \;          return ';';
64 =           return '=';
65 \,          return ',';
66 \<          return '<';
67 \>          return '>';
68 \.\.\.      return TOK_3DOT;
69 \.\.        return TOK_2DOT;
70 \.          return '.';
71 \*          return '*';
72 -           return '-';
73 bitfield    return TOK_BITFIELD;
74 enum        return TOK_ENUM;
75 namespace   return TOK_NAMESPACE;
76 using       return TOK_USING;
77 async       return TOK_ASYNC;
78 out         return TOK_OUT;
79 inout       return TOK_INOUT;
80 shared      return TOK_SHARED;
81 push        return TOK_PUSH;
82 typedef     return TOK_TYPEDEF;
83 alias       return TOK_ALIAS;
84 upcast      return TOK_INVALID;
85 downcast    return TOK_INVALID;
86 ifaceref    return TOK_INVALID;
87 virtual     return TOK_VIRTUAL;
88 guid        return TOK_GUID;
89 inline      return TOK_INLINE;
90 static      return TOK_STATIC;
91 immutable   return TOK_IMMUTABLE;
92 true        return TOK_TRUE;
93 false       return TOK_FALSE;
94
95 name        return TOK_NAME; // CDL tokens
96 method      return TOK_METHOD;
97 class       return TOK_CLASS;
98 copy        return TOK_COPY;
99
100
101 <*>\r   // Put up with DOS files
102
103 [[:alpha:]][[:alnum:]_]* {
104         // Leading underscores and digits are prohibited by the regex.
105         if (yytext[yyleng - 1] == '_') {
106                 yyerrorf("Identifier \"%s\" has a trailing underscore.",
107                          yytext);
108         } else if (strstr(yytext, "__")) {
109                 yyerrorf("Identifier \"%s\" has contiguous underscores.",
110                          yytext);
111         } else if (!strncmp(yytext, "IDL_", 4)) {
112                 yyerrorf("Identifier \"%s\" begins with the reserved "
113                          "\"IDL_\" prefix.", yytext);
114         } else if (strstr(yytext, "IDLNS")) {
115                 yyerrorf("Identifier \"%s\" contains the reserved sequence "
116                          "\"IDLNS\".", yytext);
117         } else if (!strcmp(yytext + yyleng - 3, "_ns")) {
118                 yyerrorf("Identifier \"%s\" ends with the reserved suffix \"_ns\".", yytext);
119         }
120         
121         *yylval_string = new String(yytext, cur_input_file, curline, TOK_IDENT);
122         return TOK_IDENT;
123 }
124
125
126 0[0-9]+ {
127         errno = 0;
128         
129         if (strchr(yytext, '8') || strchr(yytext, '9')) {
130                 yyerrorf("Invalid digit in octal constant %s.", yytext);
131                 yylval_con->type = TOK_INVALID;
132                 yylval_con->con.ucon = 0;
133                 return TOK_INVALID;
134         }
135         
136         yylval_con->con.ucon = strtoull(yytext, NULL, 8);
137         
138         if (errno == ERANGE) {
139                 yyerrorf("Constant %s is out of range.", yytext);
140                 yylval_con->type = TOK_INVALID;
141                 yylval_con->con.ucon = 0;
142         } else if (yylval_con->con.ucon > LLONG_MAX) {
143                 yylval_con->type = TOK_UCON;
144         } else {
145                 yylval_con->type = TOK_ICON;
146         }
147
148         return yylval_con->type;
149 }
150
151 0x[0-9a-f]+ {
152         errno = 0;
153         yylval_con->con.ucon = strtoull(yytext, NULL, 16);
154
155         if (errno == ERANGE) {
156                 yyerrorf("Constant %s is out of range.", yytext);
157                 yylval_con->type = TOK_INVALID;
158                 yylval_con->con.ucon = 0;
159         } else if (yylval_con->con.ucon > LLONG_MAX) {
160                 yylval_con->type = TOK_UCON;
161         } else {
162                 yylval_con->type = TOK_ICON;
163         }
164
165         return yylval_con->type;
166 }
167
168 [0-9]+  {
169         errno = 0;
170         yylval_con->con.ucon = strtoull(yytext, NULL, 10);
171
172         if (errno == ERANGE) {
173                 yyerrorf("Constant %s is out of range.", yytext);
174                 yylval_con->type = TOK_INVALID;
175                 yylval_con->con.ucon = 0;
176         } else if (yylval_con->con.ucon > LLONG_MAX) {
177                 yylval_con->type = TOK_UCON;
178         } else {
179                 yylval_con->type = TOK_ICON;
180         }
181
182         return yylval_con->type;
183 }
184
185 [0-9]*\.[0-9]+([eE][+-][0-9]+)? {
186         errno = 0;
187         yylval_con->con.fcon = strtod(yytext, NULL);
188         
189         if (errno == ERANGE) {
190                 yyerrorf("Constant %s is out of range.", yytext);
191                 yylval_con->con.fcon = 0;
192                 yylval_con->type = TOK_INVALID;
193         } else {
194                 yylval_con->type = TOK_FCON;
195         }
196         
197         return yylval_con->type;
198 }
199
200
201
202 \" {
203         BEGIN(STRING);
204         *yylval_string = new String("", cur_input_file, curline, TOK_STR);
205 }
206
207 <STRING>{
208         \" {
209                 BEGIN(INITIAL);
210                 return TOK_STR;
211         }
212         
213         \\\"    **yylval_string += '"';
214         \\\n    **yylval_string += '\n';
215         \\\\    **yylval_string += '\\';
216         \\. {
217                 yyerrorf("Unknown escape sequence '\\%c'.", yytext[1]);
218                 **yylval_string += yytext[1];
219         }
220         \n {
221                 yyerrorf("Unterminated string literal at line %d.", curline);
222                 BEGIN(INITIAL);
223                 curline++;
224         }
225         [^\\\"\n]+ **yylval_string += yytext;
226 }
227
228 "/*" {
229         comment_level = 1;
230         BEGIN(COMMENT);
231 }
232
233 <COMMENT>{
234         "/*"  comment_level++;
235         "*/"  if (!(--comment_level)) BEGIN(INITIAL);
236         \n    curline++;
237         \*+[^/*\n]*
238         \/+[^/*\n]*
239         [^/*\n]+
240 }
241
242 "//"    BEGIN(LINECOMMENT);
243 <LINECOMMENT>\n {
244         BEGIN(INITIAL);
245         curline++;
246 }
247 <LINECOMMENT>[^\n]+
248
249 [[:blank:]]+    /* Whitespace */
250
251
252 \n                              curline++;
253
254 <<EOF>> {
255         if (comment_level) {
256                 yyerrorf("End of file within comment.");
257                 
258                 // Keep message from occurring twice if parse is OK
259                 comment_level = 0;
260         }
261         
262         return 0;
263 }
264
265 . {
266         if (isprint(yytext[0]))
267                 yyerrorf("Unexpected character '%c'.", yytext[0]);
268         else
269                 yyerrorf("Unexpected character #%d.", yytext[0]);
270 }
271
272 %%
273
274 int finish_lex()
275 {
276         if (comment_level)
277                 yyerrorf("End of file within comment.");
278         
279         return 0;
280 }