// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false
// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging
grammar FlatBuffers;
// Parser rules
schema
: include_* (
namespace_decl
| type_decl
| enum_decl
| union_decl
| root_decl
| file_extension_decl
| file_identifier_decl
| attribute_decl
| rpc_decl
| object_
)* EOF
;
include_
: (INCLUDE | NATIVE_INCLUDE) STRING_CONSTANT SEMI
;
namespace_decl
: NAMESPACE identifier (DOT identifier)* SEMI
;
attribute_decl
: ATTRIBUTE STRING_CONSTANT SEMI
;
type_decl
: (TABLE | STRUCT) identifier metadata LC (field_decl)* RC
;
enum_decl
: ENUM identifier (COLON type_)? metadata LC commasep_enumval_decl RC
;
union_decl
: UNION identifier metadata LC commasep_unionval_with_opt_alias RC
;
root_decl
: ROOT_TYPE identifier SEMI
;
field_decl
: identifier COLON type_ (EQ scalar)? metadata SEMI
;
rpc_decl
: RPC_SERVICE identifier LC rpc_method+ RC
;
rpc_method
: identifier LP identifier RP COLON identifier metadata SEMI
;
type_
: LB type_ (COLON integer_const)? RB
| BASE_TYPE_NAME
| ns_ident
;
enumval_decl
: ns_ident (EQ integer_const)?
;
commasep_enumval_decl
: enumval_decl (COMMA enumval_decl)* COMMA?
;
unionval_with_opt_alias
: ns_ident (COLON ns_ident)? (EQ integer_const)?
;
commasep_unionval_with_opt_alias
: unionval_with_opt_alias (COMMA unionval_with_opt_alias)* COMMA?
;
ident_with_opt_single_value
: identifier (COLON single_value)?
;
commasep_ident_with_opt_single_value
: ident_with_opt_single_value (COMMA ident_with_opt_single_value)*
;
metadata
: (LP commasep_ident_with_opt_single_value RP)?
;
scalar
: INTEGER_CONSTANT
| HEX_INTEGER_CONSTANT
| FLOAT_CONSTANT
| identifier
;
object_
: LC commasep_ident_with_value RC
;
ident_with_value
: identifier COLON value
;
commasep_ident_with_value
: ident_with_value (COMMA ident_with_value)* COMMA?
;
single_value
: scalar
| STRING_CONSTANT
;
value
: single_value
| object_
| LB commasep_value RB
;
commasep_value
: value (COMMA value)* COMMA?
;
file_extension_decl
: FILE_EXTENSION STRING_CONSTANT SEMI
;
file_identifier_decl
: FILE_IDENTIFIER STRING_CONSTANT SEMI
;
ns_ident
: identifier (DOT identifier)*
;
integer_const
: INTEGER_CONSTANT
| HEX_INTEGER_CONSTANT
;
identifier
: IDENT
| keywords
;
keywords
: ATTRIBUTE
| ENUM
| FILE_EXTENSION
| FILE_IDENTIFIER
| INCLUDE
| NATIVE_INCLUDE
| NAMESPACE
| ROOT_TYPE
| RPC_SERVICE
| STRUCT
| TABLE
| UNION
;
// Lexer rules
// keywords
ATTRIBUTE
: 'attribute'
;
ENUM
: 'enum'
;
FILE_EXTENSION
: 'file_extension'
;
FILE_IDENTIFIER
: 'file_identifier'
;
INCLUDE
: 'include'
;
NATIVE_INCLUDE
: 'native_include'
;
NAMESPACE
: 'namespace'
;
ROOT_TYPE
: 'root_type'
;
RPC_SERVICE
: 'rpc_service'
;
STRUCT
: 'struct'
;
TABLE
: 'table'
;
UNION
: 'union'
;
// symbols
SEMI
: ';'
;
EQ
: '='
;
LP
: '('
;
RP
: ')'
;
LB
: '['
;
RB
: ']'
;
LC
: '{'
;
RC
: '}'
;
DOT
: '.'
;
COMMA
: ','
;
COLON
: ':'
;
PLUS
: '+'
;
MINUS
: '-'
;
fragment DECIMAL_DIGIT
: [0-9]
;
fragment HEXADECIMAL_DIGIT
: [0-9a-fA-F]
;
fragment ESCAPE_SEQUENCE
: SIMPLE_ESCAPE_SEQUENCE
| HEXADECIMAL_ESCAPE_SEQUENCE
| UNICODE_ESCAPE_SEQUENCE
;
fragment SIMPLE_ESCAPE_SEQUENCE
: '\\' ['"?bfnrtv\\/]
;
fragment HEXADECIMAL_ESCAPE_SEQUENCE
: '\\x' HEXADECIMAL_DIGIT+
;
fragment UNICODE_ESCAPE_SEQUENCE
: '\\u' HEXADECIMAL_DIGIT+
;
STRING_CONSTANT
: '"' SCHAR_SEQUENCE? '"'
;
fragment SCHAR_SEQUENCE
: SCHAR+
;
fragment SCHAR
: ~["\\\r\n]
| ESCAPE_SEQUENCE
;
BASE_TYPE_NAME
: 'bool'
| 'byte'
| 'ubyte'
| 'short'
| 'ushort'
| 'int'
| 'uint'
| 'float'
| 'long'
| 'ulong'
| 'double'
| 'int8'
| 'uint8'
| 'int16'
| 'uint16'
| 'int32'
| 'uint32'
| 'int64'
| 'uint64'
| 'float32'
| 'float64'
| 'string'
;
INTEGER_CONSTANT
: [-+]? DECIMAL_DIGIT+
| 'true'
| 'false'
;
IDENT
: [a-zA-Z_] [a-zA-Z0-9_]*
;
HEX_INTEGER_CONSTANT
: [-+]? '0' [xX] HEXADECIMAL_DIGIT+
;
FLOAT_CONSTANT
: (PLUS | MINUS)? FLOATLIT
;
// Floating-point literals
fragment FLOATLIT
: (DECIMALS DOT DECIMALS? EXPONENT? | DECIMALS EXPONENT | DOT DECIMALS EXPONENT?)
| 'inf'
| 'nan'
;
fragment DECIMALS
: DECIMAL_DIGIT+
;
fragment EXPONENT
: ('e' | 'E') (PLUS | MINUS)? DECIMALS
;
BLOCK_COMMENT
: '/*' .*? '*/' -> channel(HIDDEN)
;
// fixed original grammar: allow line comments
COMMENT
: '//' ~[\r\n]* -> channel(HIDDEN)
;
WS
: [ \t\r\n] -> skip
;