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