Home | History | Annotate | Download | only in aidl
      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