You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
322 lines
8.4 KiB
322 lines
8.4 KiB
%{ |
|
#include "aidl_language.h" |
|
#include "aidl_language_y.h" |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
|
|
int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *); |
|
|
|
#define lex_scanner ps->Scanner() |
|
|
|
%} |
|
|
|
%parse-param { Parser* ps } |
|
%lex-param { void *lex_scanner } |
|
|
|
%pure-parser |
|
%skeleton "glr.cc" |
|
|
|
%union { |
|
AidlToken* token; |
|
int integer; |
|
std::string *str; |
|
AidlType::Annotation annotation; |
|
AidlType::Annotation annotation_list; |
|
AidlType* type; |
|
AidlType* unannotated_type; |
|
AidlArgument* arg; |
|
AidlArgument::Direction direction; |
|
std::vector<std::unique_ptr<AidlArgument>>* arg_list; |
|
AidlMethod* method; |
|
AidlMember* constant; |
|
std::vector<std::unique_ptr<AidlMember>>* members; |
|
AidlQualifiedName* qname; |
|
AidlInterface* interface_obj; |
|
AidlParcelable* parcelable; |
|
AidlDocument* parcelable_list; |
|
} |
|
|
|
%token<token> IDENTIFIER INTERFACE ONEWAY C_STR HEXVALUE |
|
%token<integer> INTVALUE |
|
|
|
%token '(' ')' ',' '=' '[' ']' '<' '>' '.' '{' '}' ';' |
|
%token IN OUT INOUT PACKAGE IMPORT PARCELABLE CPP_HEADER CONST INT STRING |
|
%token ANNOTATION_NULLABLE ANNOTATION_UTF8 ANNOTATION_UTF8_CPP |
|
|
|
%type<parcelable_list> parcelable_decls |
|
%type<parcelable> parcelable_decl |
|
%type<members> members |
|
%type<interface_obj> interface_decl |
|
%type<method> method_decl |
|
%type<constant> constant_decl |
|
%type<annotation> annotation |
|
%type<annotation_list>annotation_list |
|
%type<type> type |
|
%type<unannotated_type> unannotated_type |
|
%type<arg_list> arg_list |
|
%type<arg> arg |
|
%type<direction> direction |
|
%type<str> generic_list |
|
%type<qname> qualified_name |
|
|
|
%type<token> identifier error |
|
%% |
|
document |
|
: package imports parcelable_decls |
|
{ ps->SetDocument($3); } |
|
| package imports interface_decl |
|
{ ps->SetDocument(new AidlDocument($3)); }; |
|
|
|
/* A couple of tokens that are keywords elsewhere are identifiers when |
|
* occurring in the identifier position. Therefore identifier is a |
|
* non-terminal, which is either an IDENTIFIER token, or one of the |
|
* aforementioned keyword tokens. |
|
*/ |
|
identifier |
|
: IDENTIFIER |
|
{ $$ = $1; } |
|
| CPP_HEADER |
|
{ $$ = new AidlToken("cpp_header", ""); } |
|
| INT |
|
{ $$ = new AidlToken("int", ""); } |
|
| STRING |
|
{ $$ = new AidlToken("String", ""); } |
|
; |
|
|
|
package |
|
: {} |
|
| PACKAGE qualified_name ';' |
|
{ ps->SetPackage($2); }; |
|
|
|
imports |
|
: {} |
|
| import imports {}; |
|
|
|
import |
|
: IMPORT qualified_name ';' |
|
{ ps->AddImport($2, @1.begin.line); }; |
|
|
|
qualified_name |
|
: identifier { |
|
$$ = new AidlQualifiedName($1->GetText(), $1->GetComments()); |
|
delete $1; |
|
} |
|
| qualified_name '.' identifier |
|
{ $$ = $1; |
|
$$->AddTerm($3->GetText()); |
|
delete $3; |
|
}; |
|
|
|
parcelable_decls |
|
: |
|
{ $$ = new AidlDocument(); } |
|
| parcelable_decls parcelable_decl { |
|
$$ = $1; |
|
$$->AddParcelable($2); |
|
} |
|
| parcelable_decls error { |
|
fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n", |
|
ps->FileName().c_str(), |
|
@2.begin.line, $2->GetText().c_str()); |
|
$$ = $1; |
|
}; |
|
|
|
parcelable_decl |
|
: PARCELABLE qualified_name ';' { |
|
$$ = new AidlParcelable($2, @2.begin.line, ps->Package()); |
|
} |
|
| PARCELABLE qualified_name CPP_HEADER C_STR ';' { |
|
$$ = new AidlParcelable($2, @2.begin.line, ps->Package(), $4->GetText()); |
|
} |
|
| PARCELABLE ';' { |
|
fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n", |
|
ps->FileName().c_str(), @1.begin.line); |
|
$$ = NULL; |
|
} |
|
| PARCELABLE error ';' { |
|
fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n", |
|
ps->FileName().c_str(), @2.begin.line, $2->GetText().c_str()); |
|
$$ = NULL; |
|
}; |
|
|
|
interface_decl |
|
: annotation_list INTERFACE identifier '{' members '}' { |
|
$$ = new AidlInterface($3->GetText(), @2.begin.line, $2->GetComments(), |
|
false, $5, ps->Package()); |
|
$$->Annotate($1); |
|
delete $2; |
|
delete $3; |
|
} |
|
| annotation_list ONEWAY INTERFACE identifier '{' members '}' { |
|
$$ = new AidlInterface($4->GetText(), @4.begin.line, $2->GetComments(), |
|
true, $6, ps->Package()); |
|
$$->Annotate($1); |
|
delete $2; |
|
delete $3; |
|
delete $4; |
|
} |
|
| annotation_list INTERFACE error '{' members '}' { |
|
fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected " |
|
"type name, saw \"%s\"\n", |
|
ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str()); |
|
$$ = NULL; |
|
delete $2; |
|
delete $3; |
|
delete $5; |
|
} |
|
| annotation_list INTERFACE error '}' { |
|
fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected " |
|
"type name, saw \"%s\"\n", |
|
ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str()); |
|
$$ = NULL; |
|
delete $2; |
|
delete $3; |
|
}; |
|
|
|
members |
|
: |
|
{ $$ = new std::vector<std::unique_ptr<AidlMember>>(); } |
|
| members method_decl |
|
{ $1->push_back(std::unique_ptr<AidlMember>($2)); } |
|
| members constant_decl |
|
{ $1->push_back(std::unique_ptr<AidlMember>($2)); } |
|
| members error ';' { |
|
fprintf(stderr, "%s:%d: syntax error before ';' " |
|
"(expected method or constant declaration)\n", |
|
ps->FileName().c_str(), @3.begin.line); |
|
$$ = $1; |
|
}; |
|
|
|
constant_decl |
|
: CONST INT identifier '=' INTVALUE ';' { |
|
$$ = new AidlIntConstant($3->GetText(), $5); |
|
delete $3; |
|
} |
|
| CONST INT identifier '=' HEXVALUE ';' { |
|
$$ = new AidlIntConstant($3->GetText(), $5->GetText(), @5.begin.line); |
|
delete $3; |
|
} |
|
| CONST STRING identifier '=' C_STR ';' { |
|
$$ = new AidlStringConstant($3->GetText(), $5->GetText(), @5.begin.line); |
|
delete $3; |
|
delete $5; |
|
} |
|
; |
|
|
|
method_decl |
|
: type identifier '(' arg_list ')' ';' { |
|
$$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line, |
|
$1->GetComments()); |
|
delete $2; |
|
} |
|
| ONEWAY type identifier '(' arg_list ')' ';' { |
|
$$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line, |
|
$1->GetComments()); |
|
delete $1; |
|
delete $3; |
|
} |
|
| type identifier '(' arg_list ')' '=' INTVALUE ';' { |
|
$$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line, |
|
$1->GetComments(), $7); |
|
delete $2; |
|
} |
|
| ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' { |
|
$$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line, |
|
$1->GetComments(), $8); |
|
delete $1; |
|
delete $3; |
|
}; |
|
|
|
arg_list |
|
: |
|
{ $$ = new std::vector<std::unique_ptr<AidlArgument>>(); } |
|
| arg { |
|
$$ = new std::vector<std::unique_ptr<AidlArgument>>(); |
|
$$->push_back(std::unique_ptr<AidlArgument>($1)); |
|
} |
|
| arg_list ',' arg { |
|
$$ = $1; |
|
$$->push_back(std::unique_ptr<AidlArgument>($3)); |
|
} |
|
| error { |
|
fprintf(stderr, "%s:%d: syntax error in parameter list\n", |
|
ps->FileName().c_str(), @1.begin.line); |
|
$$ = new std::vector<std::unique_ptr<AidlArgument>>(); |
|
}; |
|
|
|
arg |
|
: direction type identifier { |
|
$$ = new AidlArgument($1, $2, $3->GetText(), @3.begin.line); |
|
delete $3; |
|
}; |
|
| type identifier { |
|
$$ = new AidlArgument($1, $2->GetText(), @2.begin.line); |
|
delete $2; |
|
}; |
|
|
|
unannotated_type |
|
: qualified_name { |
|
$$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(), false); |
|
delete $1; |
|
} |
|
| qualified_name '[' ']' { |
|
$$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(), |
|
true); |
|
delete $1; |
|
} |
|
| qualified_name '<' generic_list '>' { |
|
$$ = new AidlType($1->GetDotName() + "<" + *$3 + ">", @1.begin.line, |
|
$1->GetComments(), false); |
|
delete $1; |
|
delete $3; |
|
}; |
|
|
|
type |
|
: annotation_list unannotated_type { |
|
$$ = $2; |
|
$2->Annotate($1); |
|
}; |
|
|
|
generic_list |
|
: qualified_name { |
|
$$ = new std::string($1->GetDotName()); |
|
delete $1; |
|
} |
|
| generic_list ',' qualified_name { |
|
$$ = new std::string(*$1 + "," + $3->GetDotName()); |
|
delete $1; |
|
delete $3; |
|
}; |
|
|
|
annotation_list |
|
: |
|
{ $$ = AidlType::AnnotationNone; } |
|
| annotation_list annotation |
|
{ $$ = static_cast<AidlType::Annotation>($1 | $2); }; |
|
|
|
annotation |
|
: ANNOTATION_NULLABLE |
|
{ $$ = AidlType::AnnotationNullable; } |
|
| ANNOTATION_UTF8 |
|
{ $$ = AidlType::AnnotationUtf8; } |
|
| ANNOTATION_UTF8_CPP |
|
{ $$ = AidlType::AnnotationUtf8InCpp; }; |
|
|
|
direction |
|
: IN |
|
{ $$ = AidlArgument::IN_DIR; } |
|
| OUT |
|
{ $$ = AidlArgument::OUT_DIR; } |
|
| INOUT |
|
{ $$ = AidlArgument::INOUT_DIR; }; |
|
|
|
%% |
|
|
|
#include <ctype.h> |
|
#include <stdio.h> |
|
|
|
void yy::parser::error(const yy::parser::location_type& l, |
|
const std::string& errstr) { |
|
ps->ReportError(errstr, l.begin.line); |
|
}
|
|
|