1%{ 2#include "aidl_language.h" 3#include "aidl_language_y.h" 4#include <stdio.h> 5#include <stdlib.h> 6#include <string.h> 7 8int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *); 9 10#define lex_scanner ps->Scanner() 11 12%} 13 14%parse-param { Parser* ps } 15%lex-param { void *lex_scanner } 16 17%pure-parser 18%skeleton "glr.cc" 19 20%union { 21 AidlToken* token; 22 int integer; 23 std::string *str; 24 AidlType::Annotation annotation; 25 AidlType::Annotation annotation_list; 26 AidlType* type; 27 AidlType* unannotated_type; 28 AidlArgument* arg; 29 AidlArgument::Direction direction; 30 std::vector<std::unique_ptr<AidlArgument>>* arg_list; 31 AidlMethod* method; 32 AidlMember* constant; 33 std::vector<std::unique_ptr<AidlMember>>* members; 34 AidlQualifiedName* qname; 35 AidlInterface* interface_obj; 36 AidlParcelable* parcelable; 37 AidlDocument* parcelable_list; 38} 39 40%token<token> IDENTIFIER INTERFACE ONEWAY C_STR HEXVALUE 41%token<integer> INTVALUE 42 43%token '(' ')' ',' '=' '[' ']' '<' '>' '.' '{' '}' ';' 44%token IN OUT INOUT PACKAGE IMPORT PARCELABLE CPP_HEADER CONST INT STRING 45%token ANNOTATION_NULLABLE ANNOTATION_UTF8 ANNOTATION_UTF8_CPP 46 47%type<parcelable_list> parcelable_decls 48%type<parcelable> parcelable_decl 49%type<members> members 50%type<interface_obj> interface_decl 51%type<method> method_decl 52%type<constant> constant_decl 53%type<annotation> annotation 54%type<annotation_list>annotation_list 55%type<type> type 56%type<unannotated_type> unannotated_type 57%type<arg_list> arg_list 58%type<arg> arg 59%type<direction> direction 60%type<str> generic_list 61%type<qname> qualified_name 62 63%type<token> identifier error 64%% 65document 66 : package imports parcelable_decls 67 { ps->SetDocument($3); } 68 | package imports interface_decl 69 { ps->SetDocument(new AidlDocument($3)); }; 70 71/* A couple of tokens that are keywords elsewhere are identifiers when 72 * occurring in the identifier position. Therefore identifier is a 73 * non-terminal, which is either an IDENTIFIER token, or one of the 74 * aforementioned keyword tokens. 75 */ 76identifier 77 : IDENTIFIER 78 { $$ = $1; } 79 | CPP_HEADER 80 { $$ = new AidlToken("cpp_header", ""); } 81 | INT 82 { $$ = new AidlToken("int", ""); } 83 | STRING 84 { $$ = new AidlToken("String", ""); } 85 ; 86 87package 88 : {} 89 | PACKAGE qualified_name ';' 90 { ps->SetPackage($2); }; 91 92imports 93 : {} 94 | import imports {}; 95 96import 97 : IMPORT qualified_name ';' 98 { ps->AddImport($2, @1.begin.line); }; 99 100qualified_name 101 : identifier { 102 $$ = new AidlQualifiedName($1->GetText(), $1->GetComments()); 103 delete $1; 104 } 105 | qualified_name '.' identifier 106 { $$ = $1; 107 $$->AddTerm($3->GetText()); 108 }; 109 110parcelable_decls 111 : 112 { $$ = new AidlDocument(); } 113 | parcelable_decls parcelable_decl { 114 $$ = $1; 115 $$->AddParcelable($2); 116 } 117 | parcelable_decls error { 118 fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n", 119 ps->FileName().c_str(), 120 @2.begin.line, $2->GetText().c_str()); 121 $$ = $1; 122 }; 123 124parcelable_decl 125 : PARCELABLE qualified_name ';' { 126 $$ = new AidlParcelable($2, @2.begin.line, ps->Package()); 127 } 128 | PARCELABLE qualified_name CPP_HEADER C_STR ';' { 129 $$ = new AidlParcelable($2, @2.begin.line, ps->Package(), $4->GetText()); 130 } 131 | PARCELABLE ';' { 132 fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n", 133 ps->FileName().c_str(), @1.begin.line); 134 $$ = NULL; 135 } 136 | PARCELABLE error ';' { 137 fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n", 138 ps->FileName().c_str(), @2.begin.line, $2->GetText().c_str()); 139 $$ = NULL; 140 }; 141 142interface_decl 143 : annotation_list INTERFACE identifier '{' members '}' { 144 $$ = new AidlInterface($3->GetText(), @2.begin.line, $2->GetComments(), 145 false, $5, ps->Package()); 146 $$->Annotate($1); 147 delete $2; 148 delete $3; 149 } 150 | annotation_list ONEWAY INTERFACE identifier '{' members '}' { 151 $$ = new AidlInterface($4->GetText(), @4.begin.line, $2->GetComments(), 152 true, $6, ps->Package()); 153 $$->Annotate($1); 154 delete $2; 155 delete $3; 156 delete $4; 157 } 158 | annotation_list INTERFACE error '{' members '}' { 159 fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected " 160 "type name, saw \"%s\"\n", 161 ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str()); 162 $$ = NULL; 163 delete $2; 164 delete $3; 165 delete $5; 166 } 167 | annotation_list INTERFACE error '}' { 168 fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected " 169 "type name, saw \"%s\"\n", 170 ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str()); 171 $$ = NULL; 172 delete $2; 173 delete $3; 174 }; 175 176members 177 : 178 { $$ = new std::vector<std::unique_ptr<AidlMember>>(); } 179 | members method_decl 180 { $1->push_back(std::unique_ptr<AidlMember>($2)); } 181 | members constant_decl 182 { $1->push_back(std::unique_ptr<AidlMember>($2)); } 183 | members error ';' { 184 fprintf(stderr, "%s:%d: syntax error before ';' " 185 "(expected method or constant declaration)\n", 186 ps->FileName().c_str(), @3.begin.line); 187 $$ = $1; 188 }; 189 190constant_decl 191 : CONST INT identifier '=' INTVALUE ';' { 192 $$ = new AidlIntConstant($3->GetText(), $5); 193 delete $3; 194 } 195 | CONST INT identifier '=' HEXVALUE ';' { 196 $$ = new AidlIntConstant($3->GetText(), $5->GetText(), @5.begin.line); 197 delete $3; 198 } 199 | CONST STRING identifier '=' C_STR ';' { 200 $$ = new AidlStringConstant($3->GetText(), $5->GetText(), @5.begin.line); 201 delete $3; 202 delete $5; 203 } 204 ; 205 206method_decl 207 : type identifier '(' arg_list ')' ';' { 208 $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line, 209 $1->GetComments()); 210 delete $2; 211 } 212 | ONEWAY type identifier '(' arg_list ')' ';' { 213 $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line, 214 $1->GetComments()); 215 delete $1; 216 delete $3; 217 } 218 | type identifier '(' arg_list ')' '=' INTVALUE ';' { 219 $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line, 220 $1->GetComments(), $7); 221 delete $2; 222 } 223 | ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' { 224 $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line, 225 $1->GetComments(), $8); 226 delete $1; 227 delete $3; 228 }; 229 230arg_list 231 : 232 { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); } 233 | arg { 234 $$ = new std::vector<std::unique_ptr<AidlArgument>>(); 235 $$->push_back(std::unique_ptr<AidlArgument>($1)); 236 } 237 | arg_list ',' arg { 238 $$ = $1; 239 $$->push_back(std::unique_ptr<AidlArgument>($3)); 240 } 241 | error { 242 fprintf(stderr, "%s:%d: syntax error in parameter list\n", 243 ps->FileName().c_str(), @1.begin.line); 244 $$ = new std::vector<std::unique_ptr<AidlArgument>>(); 245 }; 246 247arg 248 : direction type identifier { 249 $$ = new AidlArgument($1, $2, $3->GetText(), @3.begin.line); 250 delete $3; 251 }; 252 | type identifier { 253 $$ = new AidlArgument($1, $2->GetText(), @2.begin.line); 254 delete $2; 255 }; 256 257unannotated_type 258 : qualified_name { 259 $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(), false); 260 delete $1; 261 } 262 | qualified_name '[' ']' { 263 $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(), 264 true); 265 delete $1; 266 } 267 | qualified_name '<' generic_list '>' { 268 $$ = new AidlType($1->GetDotName() + "<" + *$3 + ">", @1.begin.line, 269 $1->GetComments(), false); 270 delete $1; 271 delete $3; 272 }; 273 274type 275 : annotation_list unannotated_type { 276 $$ = $2; 277 $2->Annotate($1); 278 }; 279 280generic_list 281 : qualified_name { 282 $$ = new std::string($1->GetDotName()); 283 delete $1; 284 } 285 | generic_list ',' qualified_name { 286 $$ = new std::string(*$1 + "," + $3->GetDotName()); 287 delete $1; 288 delete $3; 289 }; 290 291annotation_list 292 : 293 { $$ = AidlType::AnnotationNone; } 294 | annotation_list annotation 295 { $$ = static_cast<AidlType::Annotation>($1 | $2); }; 296 297annotation 298 : ANNOTATION_NULLABLE 299 { $$ = AidlType::AnnotationNullable; } 300 | ANNOTATION_UTF8 301 { $$ = AidlType::AnnotationUtf8; } 302 | ANNOTATION_UTF8_CPP 303 { $$ = AidlType::AnnotationUtf8InCpp; }; 304 305direction 306 : IN 307 { $$ = AidlArgument::IN_DIR; } 308 | OUT 309 { $$ = AidlArgument::OUT_DIR; } 310 | INOUT 311 { $$ = AidlArgument::INOUT_DIR; }; 312 313%% 314 315#include <ctype.h> 316#include <stdio.h> 317 318void yy::parser::error(const yy::parser::location_type& l, 319 const std::string& errstr) { 320 ps->ReportError(errstr, l.begin.line); 321} 322