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 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 215