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