211 lines
6.3 KiB
Plaintext
211 lines
6.3 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}?\]
|
||
|
|
||
|
%%
|
||
|
|
||
|
|
||
|
\%\%\{ { 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 ','; }
|
||
|
|
||
|
/* keywords */
|
||
|
parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; }
|
||
|
interface { SET_BUFFER(INTERFACE); return INTERFACE; }
|
||
|
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; }
|
||
|
|
||
|
{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;
|
||
|
}
|
||
|
}
|
||
|
|