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