android_frameworks_base/tools/aidl/aidl_language_l.l
Maurice Chu 02822d0590 Enhance AIDL to take an explicit id for methods
This adds an annotation to methods in AIDL of the form
"void myMethod() = 3;" to explicitly set the onTransact
id for the method.  Either all methods must have explicitly
annotated id's or none of them should be explicitly annotated.
There is error checking in the AIDL compiler
for duplicate id's and id's outside of the valid range.

Bug: 7353910
Change-Id: I868045e3f112c9a279c573cea368a621116cbf77
2012-10-18 14:47:13 -07:00

215 lines
6.6 KiB
Plaintext

%{
#include "aidl_language.h"
#include "aidl_language_y.h"
#include "search_path.h"
#include <string.h>
#include <stdlib.h>
extern YYSTYPE yylval;
// comment and whitespace handling
// these functions save a copy of the buffer
static void begin_extra_text(unsigned lineno, which_extra_text which);
static void append_extra_text(char* text);
static extra_text_type* get_extra_text(void); // you now own the object
// this returns
static void drop_extra_text(void);
// package handling
static void do_package_statement(const char* importText);
#define SET_BUFFER(t) \
do { \
yylval.buffer.lineno = yylineno; \
yylval.buffer.token = (t); \
yylval.buffer.data = strdup(yytext); \
yylval.buffer.extra = get_extra_text(); \
} while(0)
%}
%option yylineno
%option noyywrap
%x COPYING LONG_COMMENT
identifier [_a-zA-Z][_a-zA-Z0-9\.]*
whitespace ([ \t\n\r]+)
brackets \[{whitespace}?\]
idvalue (0|[1-9][0-9]*)
%%
\%\%\{ { begin_extra_text(yylineno, COPY_TEXT); BEGIN(COPYING); }
<COPYING>\}\%\% { BEGIN(INITIAL); }
<COPYING>.*\n { append_extra_text(yytext); }
<COPYING>.* { append_extra_text(yytext); }
<COPYING>\n+ { append_extra_text(yytext); }
\/\* { begin_extra_text(yylineno, (which_extra_text)LONG_COMMENT);
BEGIN(LONG_COMMENT); }
<LONG_COMMENT>[^*]* { append_extra_text(yytext); }
<LONG_COMMENT>\*+[^/] { append_extra_text(yytext); }
<LONG_COMMENT>\n { append_extra_text(yytext); }
<LONG_COMMENT>\**\/ { BEGIN(INITIAL); }
^{whitespace}?import{whitespace}[^ \t\r\n]+{whitespace}?; {
SET_BUFFER(IMPORT);
return IMPORT;
}
^{whitespace}?package{whitespace}[^ \t\r\n]+{whitespace}?; {
do_package_statement(yytext);
SET_BUFFER(PACKAGE);
return PACKAGE;
}
<<EOF>> { yyterminate(); }
\/\/.*\n { begin_extra_text(yylineno, SHORT_COMMENT);
append_extra_text(yytext); }
{whitespace} { /* begin_extra_text(yylineno, WHITESPACE);
append_extra_text(yytext); */ }
; { SET_BUFFER(';'); return ';'; }
\{ { SET_BUFFER('{'); return '{'; }
\} { SET_BUFFER('}'); return '}'; }
\( { SET_BUFFER('('); return '('; }
\) { SET_BUFFER(')'); return ')'; }
, { SET_BUFFER(','); return ','; }
= { SET_BUFFER('='); return '='; }
/* keywords */
parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; }
interface { SET_BUFFER(INTERFACE); return INTERFACE; }
flattenable { SET_BUFFER(FLATTENABLE); return FLATTENABLE; }
rpc { SET_BUFFER(INTERFACE); return RPC; }
in { SET_BUFFER(IN); return IN; }
out { SET_BUFFER(OUT); return OUT; }
inout { SET_BUFFER(INOUT); return INOUT; }
oneway { SET_BUFFER(ONEWAY); return ONEWAY; }
{brackets}+ { SET_BUFFER(ARRAY); return ARRAY; }
{idvalue} { SET_BUFFER(IDVALUE); return IDVALUE; }
{identifier} { SET_BUFFER(IDENTIFIER); return IDENTIFIER; }
{identifier}\<{whitespace}*{identifier}({whitespace}*,{whitespace}*{identifier})*{whitespace}*\> {
SET_BUFFER(GENERIC); return GENERIC; }
/* syntax error! */
. { printf("UNKNOWN(%s)", yytext);
yylval.buffer.lineno = yylineno;
yylval.buffer.token = IDENTIFIER;
yylval.buffer.data = strdup(yytext);
return IDENTIFIER;
}
%%
// comment and whitespace handling
// ================================================
extra_text_type* g_extraText = NULL;
extra_text_type* g_nextExtraText = NULL;
void begin_extra_text(unsigned lineno, which_extra_text which)
{
extra_text_type* text = (extra_text_type*)malloc(sizeof(extra_text_type));
text->lineno = lineno;
text->which = which;
text->data = NULL;
text->len = 0;
text->next = NULL;
if (g_nextExtraText == NULL) {
g_extraText = text;
} else {
g_nextExtraText->next = text;
}
g_nextExtraText = text;
}
void append_extra_text(char* text)
{
if (g_nextExtraText->data == NULL) {
g_nextExtraText->data = strdup(text);
g_nextExtraText->len = strlen(text);
} else {
char* orig = g_nextExtraText->data;
unsigned oldLen = g_nextExtraText->len;
unsigned len = strlen(text);
g_nextExtraText->len += len;
g_nextExtraText->data = (char*)malloc(g_nextExtraText->len+1);
memcpy(g_nextExtraText->data, orig, oldLen);
memcpy(g_nextExtraText->data+oldLen, text, len);
g_nextExtraText->data[g_nextExtraText->len] = '\0';
free(orig);
}
}
extra_text_type*
get_extra_text(void)
{
extra_text_type* result = g_extraText;
g_extraText = NULL;
g_nextExtraText = NULL;
return result;
}
void drop_extra_text(void)
{
extra_text_type* p = g_extraText;
while (p) {
extra_text_type* next = p->next;
free(p->data);
free(p);
free(next);
}
g_extraText = NULL;
g_nextExtraText = NULL;
}
// package handling
// ================================================
void do_package_statement(const char* importText)
{
if (g_currentPackage) free((void*)g_currentPackage);
g_currentPackage = parse_import_statement(importText);
}
// main parse function
// ================================================
char const* g_currentFilename = NULL;
char const* g_currentPackage = NULL;
int yyparse(void);
int parse_aidl(char const *filename)
{
yyin = fopen(filename, "r");
if (yyin) {
char const* oldFilename = g_currentFilename;
char const* oldPackage = g_currentPackage;
g_currentFilename = strdup(filename);
g_error = 0;
yylineno = 1;
int rv = yyparse();
if (g_error != 0) {
rv = g_error;
}
free((void*)g_currentFilename);
g_currentFilename = oldFilename;
if (g_currentPackage) free((void*)g_currentPackage);
g_currentPackage = oldPackage;
return rv;
} else {
fprintf(stderr, "aidl: unable to open file for read: %s\n", filename);
return 1;
}
}