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 idvalue (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 */ 84 parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; } 85 interface { SET_BUFFER(INTERFACE); return INTERFACE; } 86 flattenable { SET_BUFFER(FLATTENABLE); return FLATTENABLE; } 87 rpc { SET_BUFFER(INTERFACE); return RPC; } 88 in { SET_BUFFER(IN); return IN; } 89 out { SET_BUFFER(OUT); return OUT; } 90 inout { SET_BUFFER(INOUT); return INOUT; } 91 oneway { 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 // ================================================ 111 extra_text_type* g_extraText = NULL; 112 extra_text_type* g_nextExtraText = NULL; 113 114 void 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 130 void 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 148 extra_text_type* 149 get_extra_text(void) 150 { 151 extra_text_type* result = g_extraText; 152 g_extraText = NULL; 153 g_nextExtraText = NULL; 154 return result; 155 } 156 157 void 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 // ================================================ 173 void 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 // ================================================ 182 char const* g_currentFilename = NULL; 183 char const* g_currentPackage = NULL; 184 185 int yyparse(void); 186 187 int 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