blob: 2a8ab67e9f8d43e6c404938ec2eafd4f5c1c8807 [file] [log] [blame]
Gavin McDonald0b75e1a2010-10-28 02:12:01 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20/**
21 * Thrift scanner.
22 *
23 * Tokenizes a thrift definition file.
24 */
25
26%{
27
28#include <string>
29#include <errno.h>
30
31#include "main.h"
32#include "globals.h"
33#include "parse/t_program.h"
34
35/**
36 * Must be included AFTER parse/t_program.h, but I can't remember why anymore
37 * because I wrote this a while ago.
38 */
39#include "thrifty.h"
40
41void thrift_reserved_keyword(char* keyword) {
42 yyerror("Cannot use reserved language keyword: \"%s\"\n", keyword);
43 exit(1);
44}
45
46void integer_overflow(char* text) {
47 yyerror("This integer is too big: \"%s\"\n", text);
48 exit(1);
49}
50
51%}
52
53/**
54 * Provides the yylineno global, useful for debugging output
55 */
56%option lex-compat
57
58/**
59 * Helper definitions, comments, constants, and whatnot
60 */
61
62intconstant ([+-]?[0-9]+)
63hexconstant ("0x"[0-9A-Fa-f]+)
64dubconstant ([+-]?[0-9]*(\.[0-9]+)?([eE][+-]?[0-9]+)?)
65identifier ([a-zA-Z_][\.a-zA-Z_0-9]*)
66whitespace ([ \t\r\n]*)
67sillycomm ("/*""*"*"*/")
68multicomm ("/*"[^*]"/"*([^*/]|[^*]"/"|"*"[^/])*"*"*"*/")
69doctext ("/**"([^*/]|[^*]"/"|"*"[^/])*"*"*"*/")
70comment ("//"[^\n]*)
71unixcomment ("#"[^\n]*)
72symbol ([:;\,\{\}\(\)\=<>\[\]])
73st_identifier ([a-zA-Z-][\.a-zA-Z_0-9-]*)
74literal_begin (['\"])
75
76%%
77
78{whitespace} { /* do nothing */ }
79{sillycomm} { /* do nothing */ }
80{multicomm} { /* do nothing */ }
81{comment} { /* do nothing */ }
82{unixcomment} { /* do nothing */ }
83
84{symbol} { return yytext[0]; }
85
86"namespace" { return tok_namespace; }
87"cpp_namespace" { return tok_cpp_namespace; }
88"cpp_include" { return tok_cpp_include; }
89"cpp_type" { return tok_cpp_type; }
90"java_package" { return tok_java_package; }
91"cocoa_prefix" { return tok_cocoa_prefix; }
92"csharp_namespace" { return tok_csharp_namespace; }
93"php_namespace" { return tok_php_namespace; }
94"py_module" { return tok_py_module; }
95"perl_package" { return tok_perl_package; }
96"ruby_namespace" { return tok_ruby_namespace; }
97"smalltalk_category" { return tok_smalltalk_category; }
98"smalltalk_prefix" { return tok_smalltalk_prefix; }
99"xsd_all" { return tok_xsd_all; }
100"xsd_optional" { return tok_xsd_optional; }
101"xsd_nillable" { return tok_xsd_nillable; }
102"xsd_namespace" { return tok_xsd_namespace; }
103"xsd_attrs" { return tok_xsd_attrs; }
104"include" { return tok_include; }
105"void" { return tok_void; }
106"bool" { return tok_bool; }
107"byte" { return tok_byte; }
108"i16" { return tok_i16; }
109"i32" { return tok_i32; }
110"i64" { return tok_i64; }
111"double" { return tok_double; }
112"string" { return tok_string; }
113"binary" { return tok_binary; }
114"slist" { return tok_slist; }
115"senum" { return tok_senum; }
116"map" { return tok_map; }
117"list" { return tok_list; }
118"set" { return tok_set; }
119"oneway" { return tok_oneway; }
120"typedef" { return tok_typedef; }
121"struct" { return tok_struct; }
122"exception" { return tok_xception; }
123"extends" { return tok_extends; }
124"throws" { return tok_throws; }
125"service" { return tok_service; }
126"enum" { return tok_enum; }
127"const" { return tok_const; }
128"required" { return tok_required; }
129"optional" { return tok_optional; }
130"async" {
131 pwarning(0, "\"async\" is deprecated. It is called \"oneway\" now.\n");
132 return tok_oneway;
133}
134
135
136"abstract" { thrift_reserved_keyword(yytext); }
137"and" { thrift_reserved_keyword(yytext); }
138"args" { thrift_reserved_keyword(yytext); }
139"as" { thrift_reserved_keyword(yytext); }
140"assert" { thrift_reserved_keyword(yytext); }
141"break" { thrift_reserved_keyword(yytext); }
142"case" { thrift_reserved_keyword(yytext); }
143"class" { thrift_reserved_keyword(yytext); }
144"continue" { thrift_reserved_keyword(yytext); }
145"declare" { thrift_reserved_keyword(yytext); }
146"def" { thrift_reserved_keyword(yytext); }
147"default" { thrift_reserved_keyword(yytext); }
148"del" { thrift_reserved_keyword(yytext); }
149"delete" { thrift_reserved_keyword(yytext); }
150"do" { thrift_reserved_keyword(yytext); }
151"elif" { thrift_reserved_keyword(yytext); }
152"else" { thrift_reserved_keyword(yytext); }
153"elseif" { thrift_reserved_keyword(yytext); }
154"except" { thrift_reserved_keyword(yytext); }
155"exec" { thrift_reserved_keyword(yytext); }
156"false" { thrift_reserved_keyword(yytext); }
157"finally" { thrift_reserved_keyword(yytext); }
158"float" { thrift_reserved_keyword(yytext); }
159"for" { thrift_reserved_keyword(yytext); }
160"foreach" { thrift_reserved_keyword(yytext); }
161"function" { thrift_reserved_keyword(yytext); }
162"global" { thrift_reserved_keyword(yytext); }
163"goto" { thrift_reserved_keyword(yytext); }
164"if" { thrift_reserved_keyword(yytext); }
165"implements" { thrift_reserved_keyword(yytext); }
166"import" { thrift_reserved_keyword(yytext); }
167"in" { thrift_reserved_keyword(yytext); }
168"inline" { thrift_reserved_keyword(yytext); }
169"instanceof" { thrift_reserved_keyword(yytext); }
170"interface" { thrift_reserved_keyword(yytext); }
171"is" { thrift_reserved_keyword(yytext); }
172"lambda" { thrift_reserved_keyword(yytext); }
173"native" { thrift_reserved_keyword(yytext); }
174"new" { thrift_reserved_keyword(yytext); }
175"not" { thrift_reserved_keyword(yytext); }
176"or" { thrift_reserved_keyword(yytext); }
177"pass" { thrift_reserved_keyword(yytext); }
178"public" { thrift_reserved_keyword(yytext); }
179"print" { thrift_reserved_keyword(yytext); }
180"private" { thrift_reserved_keyword(yytext); }
181"protected" { thrift_reserved_keyword(yytext); }
182"raise" { thrift_reserved_keyword(yytext); }
183"return" { thrift_reserved_keyword(yytext); }
184"sizeof" { thrift_reserved_keyword(yytext); }
185"static" { thrift_reserved_keyword(yytext); }
186"switch" { thrift_reserved_keyword(yytext); }
187"synchronized" { thrift_reserved_keyword(yytext); }
188"this" { thrift_reserved_keyword(yytext); }
189"throw" { thrift_reserved_keyword(yytext); }
190"transient" { thrift_reserved_keyword(yytext); }
191"true" { thrift_reserved_keyword(yytext); }
192"try" { thrift_reserved_keyword(yytext); }
193"unsigned" { thrift_reserved_keyword(yytext); }
194"var" { thrift_reserved_keyword(yytext); }
195"virtual" { thrift_reserved_keyword(yytext); }
196"volatile" { thrift_reserved_keyword(yytext); }
197"while" { thrift_reserved_keyword(yytext); }
198"with" { thrift_reserved_keyword(yytext); }
199"union" { thrift_reserved_keyword(yytext); }
200"yield" { thrift_reserved_keyword(yytext); }
201
202{intconstant} {
203 errno = 0;
204 yylval.iconst = strtoll(yytext, NULL, 10);
205 if (errno == ERANGE) {
206 integer_overflow(yytext);
207 }
208 return tok_int_constant;
209}
210
211{hexconstant} {
212 errno = 0;
213 yylval.iconst = strtoll(yytext+2, NULL, 16);
214 if (errno == ERANGE) {
215 integer_overflow(yytext);
216 }
217 return tok_int_constant;
218}
219
220{dubconstant} {
221 yylval.dconst = atof(yytext);
222 return tok_dub_constant;
223}
224
225{identifier} {
226 yylval.id = strdup(yytext);
227 return tok_identifier;
228}
229
230{st_identifier} {
231 yylval.id = strdup(yytext);
232 return tok_st_identifier;
233}
234
235{literal_begin} {
236 char mark = yytext[0];
237 std::string result;
238 for(;;)
239 {
240 int ch = yyinput();
241 switch (ch) {
242 case EOF:
243 yyerror("End of file while read string at %d\n", yylineno);
244 exit(1);
245 case '\n':
246 yyerror("End of line while read string at %d\n", yylineno - 1);
247 exit(1);
248 case '\\':
249 ch = yyinput();
250 switch (ch) {
251 case 'r':
252 result.push_back('\r');
253 continue;
254 case 'n':
255 result.push_back('\n');
256 continue;
257 case 't':
258 result.push_back('\t');
259 continue;
260 case '"':
261 result.push_back('"');
262 continue;
263 case '\'':
264 result.push_back('\'');
265 continue;
266 case '\\':
267 result.push_back('\\');
268 continue;
269 default:
270 yyerror("Bad escape character\n");
271 return -1;
272 }
273 break;
274 default:
275 if (ch == mark) {
276 yylval.id = strdup(result.c_str());
277 return tok_literal;
278 } else {
279 result.push_back(ch);
280 }
281 }
282 }
283}
284
285
286{doctext} {
287 /* This does not show up in the parse tree. */
288 /* Rather, the parser will grab it out of the global. */
289 if (g_parse_mode == PROGRAM) {
290 clear_doctext();
291 g_doctext = strdup(yytext + 3);
292 g_doctext[strlen(g_doctext) - 2] = '\0';
293 g_doctext = clean_up_doctext(g_doctext);
294 g_doctext_lineno = yylineno;
295 }
296}
297
298
299%%
300
301/* vim: filetype=lex
302*/