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