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 delete $3; 109 }; 110 111 parcelable_decls 112 : 113 { $$ = new AidlDocument(); } 114 | parcelable_decls parcelable_decl { 115 $$ = $1; 116 $$->AddParcelable($2); 117 } 118 | parcelable_decls error { 119 fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n", 120 ps->FileName().c_str(), 121 @2.begin.line, $2->GetText().c_str()); 122 $$ = $1; 123 }; 124 125 parcelable_decl 126 : PARCELABLE qualified_name ';' { 127 $$ = new AidlParcelable($2, @2.begin.line, ps->Package()); 128 } 129 | PARCELABLE qualified_name CPP_HEADER C_STR ';' { 130 $$ = new AidlParcelable($2, @2.begin.line, ps->Package(), $4->GetText()); 131 } 132 | PARCELABLE ';' { 133 fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n", 134 ps->FileName().c_str(), @1.begin.line); 135 $$ = NULL; 136 } 137 | PARCELABLE error ';' { 138 fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n", 139 ps->FileName().c_str(), @2.begin.line, $2->GetText().c_str()); 140 $$ = NULL; 141 }; 142 143 interface_decl 144 : annotation_list INTERFACE identifier '{' members '}' { 145 $$ = new AidlInterface($3->GetText(), @2.begin.line, $2->GetComments(), 146 false, $5, ps->Package()); 147 $$->Annotate($1); 148 delete $2; 149 delete $3; 150 } 151 | annotation_list ONEWAY INTERFACE identifier '{' members '}' { 152 $$ = new AidlInterface($4->GetText(), @4.begin.line, $2->GetComments(), 153 true, $6, ps->Package()); 154 $$->Annotate($1); 155 delete $2; 156 delete $3; 157 delete $4; 158 } 159 | annotation_list INTERFACE error '{' members '}' { 160 fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected " 161 "type name, saw \"%s\"\n", 162 ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str()); 163 $$ = NULL; 164 delete $2; 165 delete $3; 166 delete $5; 167 } 168 | annotation_list INTERFACE error '}' { 169 fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected " 170 "type name, saw \"%s\"\n", 171 ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str()); 172 $$ = NULL; 173 delete $2; 174 delete $3; 175 }; 176 177 members 178 : 179 { $$ = new std::vector<std::unique_ptr<AidlMember>>(); } 180 | members method_decl 181 { $1->push_back(std::unique_ptr<AidlMember>($2)); } 182 | members constant_decl 183 { $1->push_back(std::unique_ptr<AidlMember>($2)); } 184 | members error ';' { 185 fprintf(stderr, "%s:%d: syntax error before ';' " 186 "(expected method or constant declaration)\n", 187 ps->FileName().c_str(), @3.begin.line); 188 $$ = $1; 189 }; 190 191 constant_decl 192 : CONST INT identifier '=' INTVALUE ';' { 193 $$ = new AidlIntConstant($3->GetText(), $5); 194 delete $3; 195 } 196 | CONST INT identifier '=' HEXVALUE ';' { 197 $$ = new AidlIntConstant($3->GetText(), $5->GetText(), @5.begin.line); 198 delete $3; 199 } 200 | CONST STRING identifier '=' C_STR ';' { 201 $$ = new AidlStringConstant($3->GetText(), $5->GetText(), @5.begin.line); 202 delete $3; 203 delete $5; 204 } 205 ; 206 207 method_decl 208 : type identifier '(' arg_list ')' ';' { 209 $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line, 210 $1->GetComments()); 211 delete $2; 212 } 213 | ONEWAY type identifier '(' arg_list ')' ';' { 214 $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line, 215 $1->GetComments()); 216 delete $1; 217 delete $3; 218 } 219 | type identifier '(' arg_list ')' '=' INTVALUE ';' { 220 $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line, 221 $1->GetComments(), $7); 222 delete $2; 223 } 224 | ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' { 225 $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line, 226 $1->GetComments(), $8); 227 delete $1; 228 delete $3; 229 }; 230 231 arg_list 232 : 233 { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); } 234 | arg { 235 $$ = new std::vector<std::unique_ptr<AidlArgument>>(); 236 $$->push_back(std::unique_ptr<AidlArgument>($1)); 237 } 238 | arg_list ',' arg { 239 $$ = $1; 240 $$->push_back(std::unique_ptr<AidlArgument>($3)); 241 } 242 | error { 243 fprintf(stderr, "%s:%d: syntax error in parameter list\n", 244 ps->FileName().c_str(), @1.begin.line); 245 $$ = new std::vector<std::unique_ptr<AidlArgument>>(); 246 }; 247 248 arg 249 : direction type identifier { 250 $$ = new AidlArgument($1, $2, $3->GetText(), @3.begin.line); 251 delete $3; 252 }; 253 | type identifier { 254 $$ = new AidlArgument($1, $2->GetText(), @2.begin.line); 255 delete $2; 256 }; 257 258 unannotated_type 259 : qualified_name { 260 $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(), false); 261 delete $1; 262 } 263 | qualified_name '[' ']' { 264 $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(), 265 true); 266 delete $1; 267 } 268 | qualified_name '<' generic_list '>' { 269 $$ = new AidlType($1->GetDotName() + "<" + *$3 + ">", @1.begin.line, 270 $1->GetComments(), false); 271 delete $1; 272 delete $3; 273 }; 274 275 type 276 : annotation_list unannotated_type { 277 $$ = $2; 278 $2->Annotate($1); 279 }; 280 281 generic_list 282 : qualified_name { 283 $$ = new std::string($1->GetDotName()); 284 delete $1; 285 } 286 | generic_list ',' qualified_name { 287 $$ = new std::string(*$1 + "," + $3->GetDotName()); 288 delete $1; 289 delete $3; 290 }; 291 292 annotation_list 293 : 294 { $$ = AidlType::AnnotationNone; } 295 | annotation_list annotation 296 { $$ = static_cast<AidlType::Annotation>($1 | $2); }; 297 298 annotation 299 : ANNOTATION_NULLABLE 300 { $$ = AidlType::AnnotationNullable; } 301 | ANNOTATION_UTF8 302 { $$ = AidlType::AnnotationUtf8; } 303 | ANNOTATION_UTF8_CPP 304 { $$ = AidlType::AnnotationUtf8InCpp; }; 305 306 direction 307 : IN 308 { $$ = AidlArgument::IN_DIR; } 309 | OUT 310 { $$ = AidlArgument::OUT_DIR; } 311 | INOUT 312 { $$ = AidlArgument::INOUT_DIR; }; 313 314 %% 315 316 #include <ctype.h> 317 #include <stdio.h> 318 319 void yy::parser::error(const yy::parser::location_type& l, 320 const std::string& errstr) { 321 ps->ReportError(errstr, l.begin.line); 322 } 323