322 lines
8.4 KiB
Text
322 lines
8.4 KiB
Text
%{
|
|
#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);
|
|
}
|