1 %{
2 #include "aidl_language.h"
3 #include "aidl_language_y.h"
4 #include "search_path.h"
5 #include <string.h>
6 #include <stdlib.h>
7
8 extern YYSTYPE yylval;
9
10 // comment and whitespace handling
11 // these functions save a copy of the buffer
12 static void begin_extra_text(unsigned lineno, which_extra_text which);
13 static void append_extra_text(char* text);
14 static extra_text_type* get_extra_text(void); // you now own the object
15 // this returns
16 static void drop_extra_text(void);
17
18 // package handling
19 static void do_package_statement(const char* importText);
20
21 #define SET_BUFFER(t) \
22 do { \
23 yylval.buffer.lineno = yylineno; \
24 yylval.buffer.token = (t); \
25 yylval.buffer.data = strdup(yytext); \
26 yylval.buffer.extra = get_extra_text(); \
27 } while(0)
28
29 %}
30
31 %option yylineno
32 %option noyywrap
33
34 %x COPYING LONG_COMMENT
35
36 identifier [_a-zA-Z][_a-zA-Z0-9\.]*
37 whitespace ([ \t\n\r]+)
38 brackets \[{whitespace}?\]
39
40 %%
41
42
43 \%\%\{ { begin_extra_text(yylineno, COPY_TEXT); BEGIN(COPYING); }
44 <COPYING>\}\%\% { BEGIN(INITIAL); }
45 <COPYING>.*\n { append_extra_text(yytext); }
46 <COPYING>.* { append_extra_text(yytext); }
47 <COPYING>\n+ { append_extra_text(yytext); }
48
49
50 \/\* { begin_extra_text(yylineno, (which_extra_text)LONG_COMMENT);
51 BEGIN(LONG_COMMENT); }
52 <LONG_COMMENT>[^*]* { append_extra_text(yytext); }
53 <LONG_COMMENT>\*+[^/] { append_extra_text(yytext); }
54 <LONG_COMMENT>\n { append_extra_text(yytext); }
55 <LONG_COMMENT>\**\/ { BEGIN(INITIAL); }
56
57 ^{whitespace}?import{whitespace}[^ \t\r\n]+{whitespace}?; {
58 SET_BUFFER(IMPORT);
59 return IMPORT;
60 }
61 ^{whitespace}?package{whitespace}[^ \t\r\n]+{whitespace}?; {
62 do_package_statement(yytext);
63 SET_BUFFER(PACKAGE);
64 return PACKAGE;
65 }
66 <<EOF>> { yyterminate(); }
67
68 \/\/.*\n { begin_extra_text(yylineno, SHORT_COMMENT);
69 append_extra_text(yytext); }
70
71 {whitespace} { /* begin_extra_text(yylineno, WHITESPACE);
72 append_extra_text(yytext); */ }
73
74 ; { SET_BUFFER(';'); return ';'; }
75 \{ { SET_BUFFER('{'); return '{'; }
76 \} { SET_BUFFER('}'); return '}'; }
77 \( { SET_BUFFER('('); return '('; }
78 \) { SET_BUFFER(')'); return ')'; }
79 , { SET_BUFFER(','); return ','; }
80
81 /* keywords */
82 parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; }
83 interface { SET_BUFFER(INTERFACE); return INTERFACE; }
84 flattenable { SET_BUFFER(FLATTENABLE); return FLATTENABLE; }
85 rpc { SET_BUFFER(INTERFACE); return RPC; }
86 in { SET_BUFFER(IN); return IN; }
87 out { SET_BUFFER(OUT); return OUT; }
88 inout { SET_BUFFER(INOUT); return INOUT; }
89 oneway { SET_BUFFER(ONEWAY); return ONEWAY; }
90
91 {brackets}+ { SET_BUFFER(ARRAY); return ARRAY; }
92
93 {identifier} { SET_BUFFER(IDENTIFIER); return IDENTIFIER; }
94 {identifier}\<{whitespace}*{identifier}({whitespace}*,{whitespace}*{identifier})*{whitespace}*\> {
95 SET_BUFFER(GENERIC); return GENERIC; }
96
97 /* syntax error! */
98 . { printf("UNKNOWN(%s)", yytext);
99 yylval.buffer.lineno = yylineno;
100 yylval.buffer.token = IDENTIFIER;
101 yylval.buffer.data = strdup(yytext);
102 return IDENTIFIER;
103 }
104
105 %%
106
107 // comment and whitespace handling
108 // ================================================
109 extra_text_type* g_extraText = NULL;
110 extra_text_type* g_nextExtraText = NULL;
111
begin_extra_text(unsigned lineno,which_extra_text which)112 void begin_extra_text(unsigned lineno, which_extra_text which)
113 {
114 extra_text_type* text = (extra_text_type*)malloc(sizeof(extra_text_type));
115 text->lineno = lineno;
116 text->which = which;
117 text->data = NULL;
118 text->len = 0;
119 text->next = NULL;
120 if (g_nextExtraText == NULL) {
121 g_extraText = text;
122 } else {
123 g_nextExtraText->next = text;
124 }
125 g_nextExtraText = text;
126 }
127
append_extra_text(char * text)128 void append_extra_text(char* text)
129 {
130 if (g_nextExtraText->data == NULL) {
131 g_nextExtraText->data = strdup(text);
132 g_nextExtraText->len = strlen(text);
133 } else {
134 char* orig = g_nextExtraText->data;
135 unsigned oldLen = g_nextExtraText->len;
136 unsigned len = strlen(text);
137 g_nextExtraText->len += len;
138 g_nextExtraText->data = (char*)malloc(g_nextExtraText->len+1);
139 memcpy(g_nextExtraText->data, orig, oldLen);
140 memcpy(g_nextExtraText->data+oldLen, text, len);
141 g_nextExtraText->data[g_nextExtraText->len] = '\0';
142 free(orig);
143 }
144 }
145
146 extra_text_type*
get_extra_text(void)147 get_extra_text(void)
148 {
149 extra_text_type* result = g_extraText;
150 g_extraText = NULL;
151 g_nextExtraText = NULL;
152 return result;
153 }
154
drop_extra_text(void)155 void drop_extra_text(void)
156 {
157 extra_text_type* p = g_extraText;
158 while (p) {
159 extra_text_type* next = p->next;
160 free(p->data);
161 free(p);
162 free(next);
163 }
164 g_extraText = NULL;
165 g_nextExtraText = NULL;
166 }
167
168
169 // package handling
170 // ================================================
do_package_statement(const char * importText)171 void do_package_statement(const char* importText)
172 {
173 if (g_currentPackage) free((void*)g_currentPackage);
174 g_currentPackage = parse_import_statement(importText);
175 }
176
177
178 // main parse function
179 // ================================================
180 char const* g_currentFilename = NULL;
181 char const* g_currentPackage = NULL;
182
183 int yyparse(void);
184
parse_aidl(char const * filename)185 int parse_aidl(char const *filename)
186 {
187 yyin = fopen(filename, "r");
188 if (yyin) {
189 char const* oldFilename = g_currentFilename;
190 char const* oldPackage = g_currentPackage;
191 g_currentFilename = strdup(filename);
192
193 g_error = 0;
194 yylineno = 1;
195 int rv = yyparse();
196 if (g_error != 0) {
197 rv = g_error;
198 }
199
200 free((void*)g_currentFilename);
201 g_currentFilename = oldFilename;
202
203 if (g_currentPackage) free((void*)g_currentPackage);
204 g_currentPackage = oldPackage;
205
206 return rv;
207 } else {
208 fprintf(stderr, "aidl: unable to open file for read: %s\n", filename);
209 return 1;
210 }
211 }
212
213