grammar Aidl; @members { int oneway = 0; } aidl: packageStatement? ( parcelableStatement | importStatement* interfaceStatement )?; packageStatement: PACKAGE name SE; parcelableStatement: PARCELABLE id SE; importStatement: IMPORT path SE; interfaceStatement: {oneway = 0;} (ONEWAY {oneway = 1;})? INTERFACE id LC interfaceSubStatement* RC; interfaceSubStatement: methodStatement | constStatement; methodStatement: {oneway &= 1;} (ONEWAY {oneway |= 2;})? methodReturnType id LP paramList? RP (EQ INT)? SE; constStatement: CONST INT id EQ INTEGER SE | CONST STRING id EQ LITERALSTRING SE; methodReturnType: {oneway==0}? (NULLABLE? type) | VOID; paramList: param (CO param)*; param: NULLABLE? paramTag? paramType[$paramTag.text] id; paramTag: IN | {oneway==0}? (OUT | INOUT); paramType[String tag] locals [int tid = 0]: {$tag==null}? ( (PRIMITIVE | STRING | interfaceName {$tid = 1;}) ) | {$tag!=null}? ( MAP | CHARSEQUENCE | list | ( name {$tid = -1;} | type {$tid = $type.tid;} ) {$tag.equals("in")}? | className {$tid = 2;} | type LB RB ); type returns [int tid = 0]: (PRIMITIVE | STRING | CHARSEQUENCE | MAP | list | className {$tid = 2;}) (LB RB)*; list: LIST (LA type RA)?; interfaceName: IBINDER | name; className: name; name: ID | PATH; path: PATH; id: ID; PRIMITIVE: BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | BOOLEAN | CHAR; BYTE: 'byte'; SHORT: 'short'; INT: 'int'; LONG: 'long'; FLOAT: 'float'; DOUBLE: 'double'; BOOLEAN: 'boolean'; CHAR: 'char'; PACKAGE: 'package'; PARCELABLE: 'parcelable'; IMPORT: 'import'; INTERFACE: 'interface'; ONEWAY: 'oneway'; VOID: 'void'; CONST: 'const'; NULLABLE: '@nullable'; INOUT: 'inout'; IN: 'in'; OUT: 'out'; STRING: 'String'; CHARSEQUENCE: 'CharSequence'; MAP: 'Map'; LIST: 'List'; IBINDER: 'IBinder'; LP: '('; RP: ')'; LC: '{'; RC: '}'; LB: '['; RB: ']'; LA: '<'; RA: '>'; DOT: '.'; CO: ','; SE: ';'; EQ: '='; PATH: ID (DOT ID)+; ID: [_a-zA-Z][_a-zA-Z0-9]*; INTEGER: [0-9]+; LITERALSTRING: '"' (ESC | .)*? '"'; fragment ESC: '\\"' | '\\\\'; WS: [ \t\r\n]+ -> channel(1); COMMENT_BLOCK: '/*' .*? '*/' -> channel(2); COMMENT_LINE: '//' .*? EL -> channel(2); fragment EL: '\r\n' | '\n' | '\n\r' | EOF;