Adam Lesinski | 282e181 | 2014-01-23 18:17:42 -0800 | [diff] [blame^] | 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 | |