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}?\] 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 */ 82parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; } 83interface { SET_BUFFER(INTERFACE); return INTERFACE; } 84in { SET_BUFFER(IN); return IN; } 85out { SET_BUFFER(OUT); return OUT; } 86inout { SET_BUFFER(INOUT); return INOUT; } 87oneway { SET_BUFFER(ONEWAY); return ONEWAY; } 88 89{brackets}+ { SET_BUFFER(ARRAY); return ARRAY; } 90 91{identifier} { SET_BUFFER(IDENTIFIER); return IDENTIFIER; } 92{identifier}\<{whitespace}*{identifier}({whitespace}*,{whitespace}*{identifier})*{whitespace}*\> { 93 SET_BUFFER(GENERIC); return GENERIC; } 94 95 /* syntax error! */ 96. { printf("UNKNOWN(%s)", yytext); 97 yylval.buffer.lineno = yylineno; 98 yylval.buffer.token = IDENTIFIER; 99 yylval.buffer.data = strdup(yytext); 100 return IDENTIFIER; 101 } 102 103%% 104 105// comment and whitespace handling 106// ================================================ 107extra_text_type* g_extraText = NULL; 108extra_text_type* g_nextExtraText = NULL; 109 110void begin_extra_text(unsigned lineno, which_extra_text which) 111{ 112 extra_text_type* text = (extra_text_type*)malloc(sizeof(extra_text_type)); 113 text->lineno = lineno; 114 text->which = which; 115 text->data = NULL; 116 text->len = 0; 117 text->next = NULL; 118 if (g_nextExtraText == NULL) { 119 g_extraText = text; 120 } else { 121 g_nextExtraText->next = text; 122 } 123 g_nextExtraText = text; 124} 125 126void append_extra_text(char* text) 127{ 128 if (g_nextExtraText->data == NULL) { 129 g_nextExtraText->data = strdup(text); 130 g_nextExtraText->len = strlen(text); 131 } else { 132 char* orig = g_nextExtraText->data; 133 unsigned oldLen = g_nextExtraText->len; 134 unsigned len = strlen(text); 135 g_nextExtraText->len += len; 136 g_nextExtraText->data = (char*)malloc(g_nextExtraText->len+1); 137 memcpy(g_nextExtraText->data, orig, oldLen); 138 memcpy(g_nextExtraText->data+oldLen, text, len); 139 g_nextExtraText->data[g_nextExtraText->len] = '\0'; 140 free(orig); 141 } 142} 143 144extra_text_type* 145get_extra_text(void) 146{ 147 extra_text_type* result = g_extraText; 148 g_extraText = NULL; 149 g_nextExtraText = NULL; 150 return result; 151} 152 153void drop_extra_text(void) 154{ 155 extra_text_type* p = g_extraText; 156 while (p) { 157 extra_text_type* next = p->next; 158 free(p->data); 159 free(p); 160 free(next); 161 } 162 g_extraText = NULL; 163 g_nextExtraText = NULL; 164} 165 166 167// package handling 168// ================================================ 169void do_package_statement(const char* importText) 170{ 171 if (g_currentPackage) free((void*)g_currentPackage); 172 g_currentPackage = parse_import_statement(importText); 173} 174 175 176// main parse function 177// ================================================ 178char const* g_currentFilename = NULL; 179char const* g_currentPackage = NULL; 180 181int yyparse(void); 182 183int parse_aidl(char const *filename) 184{ 185 yyin = fopen(filename, "r"); 186 if (yyin) { 187 char const* oldFilename = g_currentFilename; 188 char const* oldPackage = g_currentPackage; 189 g_currentFilename = strdup(filename); 190 191 g_error = 0; 192 yylineno = 1; 193 int rv = yyparse(); 194 if (g_error != 0) { 195 rv = g_error; 196 } 197 198 free((void*)g_currentFilename); 199 g_currentFilename = oldFilename; 200 201 if (g_currentPackage) free((void*)g_currentPackage); 202 g_currentPackage = oldPackage; 203 204 return rv; 205 } else { 206 fprintf(stderr, "aidl: unable to open file for read: %s\n", filename); 207 return 1; 208 } 209} 210 211