diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 54b6cfa9a9e5b861a9930af873580d6dc20f773c (patch) | |
tree | 35051494d2af230dce54d6b31c6af8fc24091316 /tools/aidl/aidl_language_y.y | |
download | frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.zip frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.gz frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.bz2 |
Initial Contribution
Diffstat (limited to 'tools/aidl/aidl_language_y.y')
-rw-r--r-- | tools/aidl/aidl_language_y.y | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/tools/aidl/aidl_language_y.y b/tools/aidl/aidl_language_y.y new file mode 100644 index 0000000..3d65f17 --- /dev/null +++ b/tools/aidl/aidl_language_y.y @@ -0,0 +1,288 @@ +%{ +#include "aidl_language.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int yyerror(char* errstr); +int yylex(void); +extern int yylineno; + +static int count_brackets(const char*); + +%} + +%token IMPORT +%token PACKAGE +%token IDENTIFIER +%token GENERIC +%token ARRAY +%token PARCELABLE +%token INTERFACE +%token IN +%token OUT +%token INOUT +%token ONEWAY + +%% +document: + document_items { g_callbacks->document($1.document_item); } + | headers document_items { g_callbacks->document($2.document_item); } + ; + +headers: + package { } + | imports { } + | package imports { } + ; + +package: + PACKAGE { } + ; + +imports: + IMPORT { g_callbacks->import(&($1.buffer)); } + | IMPORT imports { g_callbacks->import(&($1.buffer)); } + ; + +document_items: + { $$.document_item = NULL; } + | document_items declaration { + if ($2.document_item == NULL) { + // error cases only + $$ = $1; + } else { + document_item_type* p = $1.document_item; + while (p && p->next) { + p=p->next; + } + if (p) { + p->next = (document_item_type*)$2.document_item; + $$ = $1; + } else { + $$.document_item = (document_item_type*)$2.document_item; + } + } + } + | document_items error { + fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n", g_currentFilename, + $2.buffer.lineno, $2.buffer.data); + $$ = $1; + } + ; + +declaration: + parcelable_decl { $$.document_item = (document_item_type*)$1.parcelable; } + | interface_decl { $$.document_item = (document_item_type*)$1.interface_item; } + ; + +parcelable_decl: + PARCELABLE IDENTIFIER ';' { + parcelable_type* b = (parcelable_type*)malloc(sizeof(parcelable_type)); + b->document_item.item_type = PARCELABLE_TYPE; + b->document_item.next = NULL; + b->parcelable_token = $1.buffer; + b->name = $2.buffer; + b->package = g_currentPackage ? strdup(g_currentPackage) : NULL; + b->semicolon_token = $3.buffer; + $$.parcelable = b; + } + | PARCELABLE ';' { + fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n", + g_currentFilename, $1.buffer.lineno); + $$.parcelable = NULL; + } + | PARCELABLE error ';' { + fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n", + g_currentFilename, $2.buffer.lineno, $2.buffer.data); + $$.parcelable = NULL; + } + ; + +interface_header: + INTERFACE { + interface_type* c = (interface_type*)malloc(sizeof(interface_type)); + c->interface_token = $1.buffer; + c->oneway = false; + memset(&c->oneway_token, 0, sizeof(buffer_type)); + c->comments_token = &c->interface_token; + $$.interface_obj = c; + } + | ONEWAY INTERFACE { + interface_type* c = (interface_type*)malloc(sizeof(interface_type)); + c->interface_token = $2.buffer; + c->oneway = true; + c->oneway_token = $1.buffer; + c->comments_token = &c->oneway_token; + $$.interface_obj = c; + } + ; + +interface_decl: + interface_header IDENTIFIER '{' interface_items '}' { + interface_type* c = $1.interface_obj; + c->document_item.item_type = INTERFACE_TYPE; + c->document_item.next = NULL; + c->name = $2.buffer; + c->package = g_currentPackage ? strdup(g_currentPackage) : NULL; + c->open_brace_token = $3.buffer; + c->interface_items = $4.interface_item; + c->close_brace_token = $5.buffer; + $$.interface_obj = c; + } + | INTERFACE error '{' interface_items '}' { + fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n", + g_currentFilename, $2.buffer.lineno, $2.buffer.data); + $$.document_item = NULL; + } + | INTERFACE error '}' { + fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n", + g_currentFilename, $2.buffer.lineno, $2.buffer.data); + $$.document_item = NULL; + } + + ; + +interface_items: + { $$.interface_item = NULL; } + | interface_items method_decl { + interface_item_type* p=$1.interface_item; + while (p && p->next) { + p=p->next; + } + if (p) { + p->next = (interface_item_type*)$2.method; + $$ = $1; + } else { + $$.interface_item = (interface_item_type*)$2.method; + } + } + | interface_items error ';' { + fprintf(stderr, "%s:%d: syntax error before ';' (expected method declaration)\n", + g_currentFilename, $3.buffer.lineno); + $$ = $1; + } + ; + +method_decl: + type IDENTIFIER '(' arg_list ')' ';' { + method_type *method = (method_type*)malloc(sizeof(method_type)); + method->interface_item.item_type = METHOD_TYPE; + method->interface_item.next = NULL; + method->type = $1.type; + method->oneway = false; + memset(&method->oneway_token, 0, sizeof(buffer_type)); + method->name = $2.buffer; + method->open_paren_token = $3.buffer; + method->args = $4.arg; + method->close_paren_token = $5.buffer; + method->semicolon_token = $6.buffer; + method->comments_token = &method->type.type; + $$.method = method; + } + | ONEWAY type IDENTIFIER '(' arg_list ')' ';' { + method_type *method = (method_type*)malloc(sizeof(method_type)); + method->interface_item.item_type = METHOD_TYPE; + method->interface_item.next = NULL; + method->oneway = true; + method->oneway_token = $1.buffer; + method->type = $2.type; + method->name = $3.buffer; + method->open_paren_token = $4.buffer; + method->args = $5.arg; + method->close_paren_token = $6.buffer; + method->semicolon_token = $7.buffer; + method->comments_token = &method->oneway_token; + $$.method = method; + } + ; + +arg_list: + { $$.arg = NULL; } + | arg { $$ = $1; } + | arg_list ',' arg { + if ($$.arg != NULL) { + // only NULL on error + $$ = $1; + arg_type *p = $1.arg; + while (p && p->next) { + p=p->next; + } + $3.arg->comma_token = $2.buffer; + p->next = $3.arg; + } + } + | error { + fprintf(stderr, "%s:%d: syntax error in parameter list\n", g_currentFilename, $1.buffer.lineno); + $$.arg = NULL; + } + ; + +arg: + direction type IDENTIFIER { + arg_type* arg = (arg_type*)malloc(sizeof(arg_type)); + memset(&arg->comma_token, 0, sizeof(buffer_type)); + arg->direction = $1.buffer; + arg->type = $2.type; + arg->name = $3.buffer; + arg->next = NULL; + $$.arg = arg; + } + ; + +type: + IDENTIFIER { + $$.type.type = $1.buffer; + init_buffer_type(&$$.type.array_token, yylineno); + $$.type.dimension = 0; + } + | IDENTIFIER ARRAY { + $$.type.type = $1.buffer; + $$.type.array_token = $2.buffer; + $$.type.dimension = count_brackets($2.buffer.data); + } + | GENERIC { + $$.type.type = $1.buffer; + init_buffer_type(&$$.type.array_token, yylineno); + $$.type.dimension = 0; + } + ; + +direction: + { init_buffer_type(&$$.buffer, yylineno); } + | IN { $$.buffer = $1.buffer; } + | OUT { $$.buffer = $1.buffer; } + | INOUT { $$.buffer = $1.buffer; } + ; + +%% + +#include <ctype.h> +#include <stdio.h> + +int g_error = 0; + +int yyerror(char* errstr) +{ + fprintf(stderr, "%s:%d: %s\n", g_currentFilename, yylineno, errstr); + g_error = 1; + return 1; +} + +void init_buffer_type(buffer_type* buf, int lineno) +{ + buf->lineno = lineno; + buf->token = 0; + buf->data = NULL; + buf->extra = NULL; +} + +static int count_brackets(const char* s) +{ + int n=0; + while (*s) { + if (*s == '[') n++; + s++; + } + return n; +} |