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 8 int 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 %% 65 document 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 */ 76 identifier 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 87 package 88 : {} 89 | PACKAGE qualified_name ';' 90 { ps->SetPackage($2); }; 91 92 imports 93 : {} 94 | import imports {}; 95 96 import 97 : IMPORT qualified_name ';' 98 { ps->AddImport($2, @1.begin.line); }; 99 100 qualified_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 110 parcelable_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 124 parcelable_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 142 interface_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 176 members 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 190 constant_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 206 method_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 230 arg_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 247 arg 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 257 unannotated_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 274 type 275 : annotation_list unannotated_type { 276 $$ = $2; 277 $2->Annotate($1); 278 }; 279 280 generic_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 291 annotation_list 292 : 293 { $$ = AidlType::AnnotationNone; } 294 | annotation_list annotation 295 { $$ = static_cast<AidlType::Annotation>($1 | $2); }; 296 297 annotation 298 : ANNOTATION_NULLABLE 299 { $$ = AidlType::AnnotationNullable; } 300 | ANNOTATION_UTF8 301 { $$ = AidlType::AnnotationUtf8; } 302 | ANNOTATION_UTF8_CPP 303 { $$ = AidlType::AnnotationUtf8InCpp; }; 304 305 direction 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 318 void yy::parser::error(const yy::parser::location_type& l, 319 const std::string& errstr) { 320 ps->ReportError(errstr, l.begin.line); 321 } 322