blob: a700ca35cf5e32c017522be90dca57aba0e8cb20 [file] [log] [blame]
Mark Slee31985722006-05-24 21:45:31 +00001/**
Mark Sleee9ce01c2007-05-16 02:29:53 +00002 * Copyright (c) 2006- Facebook
3 * Distributed under the Thrift Software License
4 *
5 * See accompanying file LICENSE or visit the Thrift site at:
6 * http://developers.facebook.com/thrift/
7 */
8
9/**
Mark Slee31985722006-05-24 21:45:31 +000010 * Thrift scanner.
Mark Slee27ed6ec2007-08-16 01:26:31 +000011 *
Mark Slee31985722006-05-24 21:45:31 +000012 * Tokenizes a thrift definition file.
Mark Slee31985722006-05-24 21:45:31 +000013 */
Mark Sleef5377b32006-10-10 01:42:59 +000014
Mark Slee31985722006-05-24 21:45:31 +000015%{
16
David Reiss82e6fc02009-03-26 23:32:36 +000017#include <string>
David Reissf1454162008-06-30 20:45:47 +000018#include <errno.h>
19
Mark Slee31985722006-05-24 21:45:31 +000020#include "main.h"
David Reisscbd4bac2007-08-14 17:12:33 +000021#include "globals.h"
Mark Slee31985722006-05-24 21:45:31 +000022#include "parse/t_program.h"
23
Mark Sleef5377b32006-10-10 01:42:59 +000024/**
25 * Must be included AFTER parse/t_program.h, but I can't remember why anymore
26 * because I wrote this a while ago.
27 */
Mark Sleeeb0d0242007-01-25 07:58:55 +000028#include "thrifty.h"
Mark Slee31985722006-05-24 21:45:31 +000029
Mark Sleef12865a2007-01-12 00:23:26 +000030void thrift_reserved_keyword(char* keyword) {
31 yyerror("Cannot use reserved language keyword: \"%s\"\n", keyword);
32 exit(1);
33}
34
David Reissf1454162008-06-30 20:45:47 +000035void integer_overflow(char* text) {
36 yyerror("This integer is too big: \"%s\"\n", text);
37 exit(1);
38}
39
Mark Slee31985722006-05-24 21:45:31 +000040%}
41
Mark Sleef5377b32006-10-10 01:42:59 +000042/**
43 * Provides the yylineno global, useful for debugging output
44 */
Mark Slee27ed6ec2007-08-16 01:26:31 +000045%option lex-compat
Mark Slee31985722006-05-24 21:45:31 +000046
Mark Slee27ed6ec2007-08-16 01:26:31 +000047/**
Mark Sleef5377b32006-10-10 01:42:59 +000048 * Helper definitions, comments, constants, and whatnot
49 */
50
Mark Sleebd588222007-11-21 08:43:35 +000051intconstant ([+-]?[0-9]+)
52hexconstant ("0x"[0-9A-Fa-f]+)
53dubconstant ([+-]?[0-9]*(\.[0-9]+)?([eE][+-]?[0-9]+)?)
54identifier ([a-zA-Z_][\.a-zA-Z_0-9]*)
55whitespace ([ \t\r\n]*)
56sillycomm ("/*""*"*"*/")
57multicomm ("/*"[^*]"/"*([^*/]|[^*]"/"|"*"[^/])*"*"*"*/")
58doctext ("/**"([^*/]|[^*]"/"|"*"[^/])*"*"*"*/")
59comment ("//"[^\n]*)
60unixcomment ("#"[^\n]*)
61symbol ([:;\,\{\}\(\)\=<>\[\]])
Mark Sleebd588222007-11-21 08:43:35 +000062st_identifier ([a-zA-Z-][\.a-zA-Z_0-9-]*)
David Reiss82e6fc02009-03-26 23:32:36 +000063literal_begin (['\"])
Mark Slee31985722006-05-24 21:45:31 +000064
65%%
66
Mark Sleebd588222007-11-21 08:43:35 +000067{whitespace} { /* do nothing */ }
68{sillycomm} { /* do nothing */ }
69{multicomm} { /* do nothing */ }
70{comment} { /* do nothing */ }
71{unixcomment} { /* do nothing */ }
Mark Slee31985722006-05-24 21:45:31 +000072
Mark Sleebd588222007-11-21 08:43:35 +000073{symbol} { return yytext[0]; }
Mark Slee9cb7c612006-09-01 22:17:45 +000074
Mark Sleebd588222007-11-21 08:43:35 +000075"namespace" { return tok_namespace; }
76"cpp_namespace" { return tok_cpp_namespace; }
77"cpp_include" { return tok_cpp_include; }
78"cpp_type" { return tok_cpp_type; }
79"java_package" { return tok_java_package; }
80"cocoa_prefix" { return tok_cocoa_prefix; }
David Reiss7f42bcf2008-01-11 20:59:12 +000081"csharp_namespace" { return tok_csharp_namespace; }
Mark Sleebd588222007-11-21 08:43:35 +000082"php_namespace" { return tok_php_namespace; }
83"py_module" { return tok_py_module; }
84"perl_package" { return tok_perl_package; }
85"ruby_namespace" { return tok_ruby_namespace; }
86"smalltalk_category" { return tok_smalltalk_category; }
David Reiss15457c92007-12-14 07:03:03 +000087"smalltalk_prefix" { return tok_smalltalk_prefix; }
Mark Sleebd588222007-11-21 08:43:35 +000088"xsd_all" { return tok_xsd_all; }
89"xsd_optional" { return tok_xsd_optional; }
90"xsd_nillable" { return tok_xsd_nillable; }
91"xsd_namespace" { return tok_xsd_namespace; }
92"xsd_attrs" { return tok_xsd_attrs; }
93"include" { return tok_include; }
94"void" { return tok_void; }
95"bool" { return tok_bool; }
96"byte" { return tok_byte; }
97"i16" { return tok_i16; }
98"i32" { return tok_i32; }
99"i64" { return tok_i64; }
100"double" { return tok_double; }
101"string" { return tok_string; }
102"binary" { return tok_binary; }
103"slist" { return tok_slist; }
104"senum" { return tok_senum; }
105"map" { return tok_map; }
106"list" { return tok_list; }
107"set" { return tok_set; }
David Reisscecbed82009-03-24 20:02:22 +0000108"oneway" { return tok_oneway; }
Mark Sleebd588222007-11-21 08:43:35 +0000109"typedef" { return tok_typedef; }
110"struct" { return tok_struct; }
111"exception" { return tok_xception; }
112"extends" { return tok_extends; }
113"throws" { return tok_throws; }
114"service" { return tok_service; }
115"enum" { return tok_enum; }
116"const" { return tok_const; }
117"required" { return tok_required; }
118"optional" { return tok_optional; }
David Reisscecbed82009-03-24 20:02:22 +0000119"async" {
120 pwarning(0, "\"async\" is deprecated. It is called \"oneway\" now.\n");
121 return tok_oneway;
122}
Mark Sleef0712dc2006-10-25 19:03:57 +0000123
Mark Slee52f643d2006-08-09 00:03:43 +0000124
Mark Sleebd588222007-11-21 08:43:35 +0000125"abstract" { thrift_reserved_keyword(yytext); }
126"and" { thrift_reserved_keyword(yytext); }
Mark Sleec27fc312007-12-21 23:52:19 +0000127"args" { thrift_reserved_keyword(yytext); }
Mark Sleebd588222007-11-21 08:43:35 +0000128"as" { thrift_reserved_keyword(yytext); }
129"assert" { thrift_reserved_keyword(yytext); }
130"break" { thrift_reserved_keyword(yytext); }
131"case" { thrift_reserved_keyword(yytext); }
132"class" { thrift_reserved_keyword(yytext); }
133"continue" { thrift_reserved_keyword(yytext); }
134"declare" { thrift_reserved_keyword(yytext); }
135"def" { thrift_reserved_keyword(yytext); }
136"default" { thrift_reserved_keyword(yytext); }
137"del" { thrift_reserved_keyword(yytext); }
138"delete" { thrift_reserved_keyword(yytext); }
139"do" { thrift_reserved_keyword(yytext); }
140"elif" { thrift_reserved_keyword(yytext); }
141"else" { thrift_reserved_keyword(yytext); }
142"elseif" { thrift_reserved_keyword(yytext); }
143"except" { thrift_reserved_keyword(yytext); }
144"exec" { thrift_reserved_keyword(yytext); }
145"false" { thrift_reserved_keyword(yytext); }
Mark Sleebd588222007-11-21 08:43:35 +0000146"finally" { thrift_reserved_keyword(yytext); }
147"float" { thrift_reserved_keyword(yytext); }
148"for" { thrift_reserved_keyword(yytext); }
149"foreach" { thrift_reserved_keyword(yytext); }
150"function" { thrift_reserved_keyword(yytext); }
151"global" { thrift_reserved_keyword(yytext); }
152"goto" { thrift_reserved_keyword(yytext); }
153"if" { thrift_reserved_keyword(yytext); }
154"implements" { thrift_reserved_keyword(yytext); }
155"import" { thrift_reserved_keyword(yytext); }
156"in" { thrift_reserved_keyword(yytext); }
157"inline" { thrift_reserved_keyword(yytext); }
158"instanceof" { thrift_reserved_keyword(yytext); }
159"interface" { thrift_reserved_keyword(yytext); }
160"is" { thrift_reserved_keyword(yytext); }
161"lambda" { thrift_reserved_keyword(yytext); }
162"native" { thrift_reserved_keyword(yytext); }
163"new" { thrift_reserved_keyword(yytext); }
164"not" { thrift_reserved_keyword(yytext); }
165"or" { thrift_reserved_keyword(yytext); }
166"pass" { thrift_reserved_keyword(yytext); }
167"public" { thrift_reserved_keyword(yytext); }
168"print" { thrift_reserved_keyword(yytext); }
169"private" { thrift_reserved_keyword(yytext); }
170"protected" { thrift_reserved_keyword(yytext); }
171"raise" { thrift_reserved_keyword(yytext); }
172"return" { thrift_reserved_keyword(yytext); }
173"sizeof" { thrift_reserved_keyword(yytext); }
174"static" { thrift_reserved_keyword(yytext); }
175"switch" { thrift_reserved_keyword(yytext); }
176"synchronized" { thrift_reserved_keyword(yytext); }
177"this" { thrift_reserved_keyword(yytext); }
178"throw" { thrift_reserved_keyword(yytext); }
179"transient" { thrift_reserved_keyword(yytext); }
180"true" { thrift_reserved_keyword(yytext); }
181"try" { thrift_reserved_keyword(yytext); }
182"unsigned" { thrift_reserved_keyword(yytext); }
183"var" { thrift_reserved_keyword(yytext); }
184"virtual" { thrift_reserved_keyword(yytext); }
185"volatile" { thrift_reserved_keyword(yytext); }
186"while" { thrift_reserved_keyword(yytext); }
187"with" { thrift_reserved_keyword(yytext); }
188"union" { thrift_reserved_keyword(yytext); }
189"yield" { thrift_reserved_keyword(yytext); }
Mark Sleef12865a2007-01-12 00:23:26 +0000190
Mark Slee4f8da1d2006-10-12 02:47:27 +0000191{intconstant} {
David Reissf1454162008-06-30 20:45:47 +0000192 errno = 0;
193 yylval.iconst = strtoll(yytext, NULL, 10);
194 if (errno == ERANGE) {
195 integer_overflow(yytext);
196 }
Mark Slee4f8da1d2006-10-12 02:47:27 +0000197 return tok_int_constant;
198}
Mark Sleef5377b32006-10-10 01:42:59 +0000199
Mark Slee600cdb32006-11-29 22:06:42 +0000200{hexconstant} {
David Reissf1454162008-06-30 20:45:47 +0000201 errno = 0;
202 yylval.iconst = strtoll(yytext+2, NULL, 16);
203 if (errno == ERANGE) {
204 integer_overflow(yytext);
205 }
Mark Slee600cdb32006-11-29 22:06:42 +0000206 return tok_int_constant;
207}
208
Mark Slee30152872006-11-28 01:24:07 +0000209{dubconstant} {
210 yylval.dconst = atof(yytext);
211 return tok_dub_constant;
212}
213
Mark Slee4f8da1d2006-10-12 02:47:27 +0000214{identifier} {
215 yylval.id = strdup(yytext);
216 return tok_identifier;
217}
218
Mark Sleebd588222007-11-21 08:43:35 +0000219{st_identifier} {
220 yylval.id = strdup(yytext);
221 return tok_st_identifier;
222}
223
David Reiss82e6fc02009-03-26 23:32:36 +0000224{literal_begin} {
225 char mark = yytext[0];
226 std::string result;
227 for(;;)
228 {
229 int ch = yyinput();
230 switch (ch) {
231 case EOF:
232 yyerror("End of file while read string at %d\n", yylineno);
233 exit(1);
234 case '\n':
235 yyerror("End of line while read string at %d\n", yylineno - 1);
236 exit(1);
237 case '\\':
238 ch = yyinput();
239 switch (ch) {
240 case 'r':
241 result.push_back('\r');
242 continue;
243 case 'n':
244 result.push_back('\n');
245 continue;
246 case 't':
247 result.push_back('\t');
248 continue;
249 case '"':
250 result.push_back('"');
251 continue;
252 case '\'':
253 result.push_back('\'');
254 continue;
255 case '\\':
256 result.push_back('\\');
257 continue;
258 default:
259 yyerror("Bad escape character\n");
260 return -1;
261 }
262 break;
263 default:
264 if (ch == mark) {
265 yylval.id = strdup(result.c_str());
266 return tok_literal;
267 } else {
268 result.push_back(ch);
269 }
270 }
271 }
Mark Slee30152872006-11-28 01:24:07 +0000272}
273
Mark Slee31985722006-05-24 21:45:31 +0000274
ccheeverf53b5cf2007-02-05 20:33:11 +0000275{doctext} {
David Reisscbd4bac2007-08-14 17:12:33 +0000276 /* This does not show up in the parse tree. */
277 /* Rather, the parser will grab it out of the global. */
278 if (g_parse_mode == PROGRAM) {
279 clear_doctext();
280 g_doctext = strdup(yytext + 3);
281 g_doctext[strlen(g_doctext) - 2] = '\0';
282 g_doctext = clean_up_doctext(g_doctext);
283 g_doctext_lineno = yylineno;
284 }
ccheeverf53b5cf2007-02-05 20:33:11 +0000285}
286
287
Mark Slee31985722006-05-24 21:45:31 +0000288%%
David Reiss4a054342009-03-26 23:32:27 +0000289
290/* vim: filetype=lex
291*/