2011-01-10 17:58:00 +00:00
|
|
|
grammar osmo_codegen;
|
|
|
|
|
2011-02-19 12:29:34 +00:00
|
|
|
options {
|
2011-01-10 17:58:00 +00:00
|
|
|
//language = Python;
|
2011-02-19 12:29:34 +00:00
|
|
|
output = AST;
|
|
|
|
}
|
|
|
|
tokens {
|
|
|
|
PDUFIELD_OPT;
|
|
|
|
FIELD_VAL;
|
|
|
|
PDUFIELD_SIZE;
|
|
|
|
IEFIELD_ENDIAN;
|
|
|
|
IEFIELD_COND;
|
|
|
|
|
|
|
|
IE_SPECS;
|
|
|
|
IE_ALIASES;
|
|
|
|
PDU_SPECS;
|
|
|
|
}
|
|
|
|
|
2011-01-10 17:58:00 +00:00
|
|
|
root :
|
2011-01-10 22:38:58 +00:00
|
|
|
(pdu_spec | ie_spec | ie_alias)*
|
2011-02-19 05:55:49 +00:00
|
|
|
-> ^(IE_SPECS ie_spec*)
|
|
|
|
^(IE_ALIASES ie_alias*)
|
|
|
|
^(PDU_SPECS pdu_spec*)
|
2011-01-10 17:58:00 +00:00
|
|
|
;
|
2011-01-10 23:11:43 +00:00
|
|
|
|
|
|
|
/* INFORMATION ELEMENTS */
|
2011-01-10 17:58:00 +00:00
|
|
|
|
2011-01-10 23:11:43 +00:00
|
|
|
/* An alias in the form "ie_alias new_name existing_field" */
|
2011-02-19 12:29:34 +00:00
|
|
|
ie_alias: 'ie_alias' ie_name ie_name
|
|
|
|
-> ^(ie_name ie_name)
|
|
|
|
;
|
2011-01-10 22:38:58 +00:00
|
|
|
|
|
|
|
ie_name : ID;
|
|
|
|
|
|
|
|
ie_spec : 'ie_spec' ID
|
|
|
|
ie_field_def*
|
|
|
|
'end_ie_spec'
|
2011-02-19 12:29:34 +00:00
|
|
|
-> ^(ID ie_field_def*)
|
2011-01-10 22:38:58 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
ie_field_def
|
2011-02-19 12:29:34 +00:00
|
|
|
: ie_field_name ie_field_len ie_field_type ie_field_opt*
|
|
|
|
-> ^(ie_field_name ie_field_type ie_field_len ie_field_opt*)
|
2011-01-10 22:38:58 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
ie_field_name
|
|
|
|
: ID;
|
|
|
|
ie_field_len
|
2011-01-10 23:11:43 +00:00
|
|
|
: (NUMERIC
|
|
|
|
| '*' // * only permitted in last field, menas 'all remaining octets/bits'
|
|
|
|
);
|
2011-01-10 22:38:58 +00:00
|
|
|
ie_field_type
|
2011-01-10 23:11:43 +00:00
|
|
|
: ('byte' | 'bytes'
|
|
|
|
| 'bit' | 'bits'
|
|
|
|
| 'bcd' // BCD digits, always 'lower nibble, upper nibble, lower nibble, ...
|
|
|
|
);
|
2011-02-19 12:29:34 +00:00
|
|
|
ie_field_opt
|
2011-02-19 05:55:49 +00:00
|
|
|
: (field_val | ie_field_cond | ie_field_endian | ie_field_enum)
|
2011-02-19 12:29:34 +00:00
|
|
|
;
|
2011-01-10 22:38:58 +00:00
|
|
|
ie_field_cond
|
2011-02-19 12:29:34 +00:00
|
|
|
: 'if (' ie_field_name ('&' ie_field_cond_mask)? COMP_OP ie_field_cond_reference ')'
|
|
|
|
-> ^(IEFIELD_COND ie_field_name ie_field_cond_mask? COMP_OP ie_field_cond_reference)
|
|
|
|
;
|
2011-01-10 23:11:43 +00:00
|
|
|
ie_field_cond_mask
|
|
|
|
: NUMERIC;
|
|
|
|
ie_field_cond_reference
|
|
|
|
: NUMERIC;
|
2011-01-10 22:38:58 +00:00
|
|
|
ie_field_endian
|
2011-02-19 12:29:34 +00:00
|
|
|
: ( 'big' -> ^(IEFIELD_ENDIAN 'big')
|
|
|
|
| 'little' -> ^(IEFIELD_ENDIAN 'little')
|
|
|
|
)
|
|
|
|
;
|
2011-02-19 05:55:49 +00:00
|
|
|
ie_field_enum
|
|
|
|
: 'enum' ID -> ^('enum' ID)
|
|
|
|
;
|
|
|
|
|
2011-01-10 22:38:58 +00:00
|
|
|
|
2011-01-10 23:11:43 +00:00
|
|
|
/* PDU DEFINITIONS*/
|
2011-01-10 22:38:58 +00:00
|
|
|
|
2011-01-10 17:58:00 +00:00
|
|
|
pdu_spec
|
2011-01-10 22:38:58 +00:00
|
|
|
: 'pdu_spec' ID
|
|
|
|
pdu_field_def*
|
2011-02-19 12:29:34 +00:00
|
|
|
'end_pdu_spec' -> ^(ID pdu_field_def*)
|
2011-01-10 17:58:00 +00:00
|
|
|
;
|
|
|
|
|
2011-01-10 22:38:58 +00:00
|
|
|
pdu_field_mode
|
2011-01-10 17:58:00 +00:00
|
|
|
: 'mand' | 'opt' | 'cond';
|
|
|
|
|
|
|
|
field_val
|
2011-02-19 12:29:34 +00:00
|
|
|
: ('val'|'value') NUMERIC // Field always has to have indicated value
|
|
|
|
-> ^(FIELD_VAL NUMERIC)
|
|
|
|
;
|
2011-01-10 17:58:00 +00:00
|
|
|
|
|
|
|
field_tag
|
2011-02-19 12:29:34 +00:00
|
|
|
: 'tag' NUMERIC // for tagged fields
|
|
|
|
-> ^('tag' NUMERIC)
|
|
|
|
;
|
2011-01-10 17:58:00 +00:00
|
|
|
|
2011-01-10 22:38:58 +00:00
|
|
|
pdu_field_size
|
2011-02-19 12:29:34 +00:00
|
|
|
: NUMERIC ('-' NUMERIC)? // fixed length or range
|
|
|
|
-> ^(PDUFIELD_SIZE NUMERIC*)
|
|
|
|
;
|
2011-01-10 17:58:00 +00:00
|
|
|
|
2011-01-10 22:38:58 +00:00
|
|
|
pdu_field_opts
|
2011-02-19 05:55:49 +00:00
|
|
|
: pdu_up_downlink | pdu_opt_ie | pdu_opt_enum
|
2011-01-10 19:05:37 +00:00
|
|
|
;
|
2011-01-10 23:00:37 +00:00
|
|
|
pdu_up_downlink
|
2011-01-10 23:11:43 +00:00
|
|
|
: 'uplink_only' | 'downlink_only'; // only valid in uplink or downlink
|
2011-01-10 23:00:37 +00:00
|
|
|
pdu_opt_ie
|
2011-02-19 12:29:34 +00:00
|
|
|
: 'ie' ID // use speciifed IE definition
|
|
|
|
-> ^('ie' ID)
|
|
|
|
;
|
2011-02-19 05:55:49 +00:00
|
|
|
pdu_opt_enum
|
|
|
|
: 'enum' ID
|
|
|
|
-> ^('enum' ID)
|
|
|
|
;
|
2011-01-10 19:05:37 +00:00
|
|
|
|
2011-01-10 22:38:58 +00:00
|
|
|
pdu_field_type
|
2011-01-10 17:58:00 +00:00
|
|
|
: (
|
2011-01-10 23:11:43 +00:00
|
|
|
('V4u' field_val?) // 4 bits in the upper nibble
|
|
|
|
| ('V4l' field_val?) // 4 bits in the lower nibble
|
|
|
|
| ('V' pdu_field_size field_val?) // 8bit value-only
|
|
|
|
| ('TLV' pdu_field_size? field_val? field_tag) // full TLV
|
|
|
|
| ('LV' pdu_field_size field_val?) // LV without Tag
|
|
|
|
| ('TV' pdu_field_size field_val? field_tag) // TV with fixed length value
|
|
|
|
| ('T' field_val? field_tag) // T only
|
|
|
|
| ('TV4' field_val? field_tag) // T is upper nibble, value lower nibble
|
2011-01-10 22:38:58 +00:00
|
|
|
) pdu_field_opts*;
|
2011-01-10 17:58:00 +00:00
|
|
|
|
2011-01-10 22:38:58 +00:00
|
|
|
pdu_field_def
|
2011-02-19 12:29:34 +00:00
|
|
|
: ID pdu_field_mode pdu_field_type
|
|
|
|
-> ^(ID pdu_field_mode pdu_field_type)
|
|
|
|
;
|
2011-01-10 17:58:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* LEXER RULES */
|
|
|
|
|
|
|
|
fragment
|
|
|
|
NEWLINE : '\r'? '\n';
|
|
|
|
|
|
|
|
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
|
|
|
|
;
|
|
|
|
|
|
|
|
NUMERIC : INT | HEX ;
|
|
|
|
|
|
|
|
COMMENT
|
|
|
|
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
|
|
|
|
| '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
|
|
|
|
| '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
|
|
|
|
;
|
|
|
|
|
|
|
|
WS : ( ' '
|
|
|
|
| '\t'
|
|
|
|
| '\r'
|
|
|
|
| '\n'
|
|
|
|
) {$channel=HIDDEN;}
|
|
|
|
;
|
|
|
|
|
|
|
|
STRING
|
|
|
|
: '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
|
|
|
|
;
|
|
|
|
|
2011-01-10 22:38:58 +00:00
|
|
|
COMP_OP : '==' | '<' | '>' | '>=' | '<=' | '!=';
|
|
|
|
|
2011-01-10 17:58:00 +00:00
|
|
|
fragment
|
|
|
|
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
|
|
|
|
|
|
|
|
fragment
|
|
|
|
ESC_SEQ
|
|
|
|
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
|
|
|
|
| UNICODE_ESC
|
|
|
|
| OCTAL_ESC
|
|
|
|
;
|
|
|
|
|
|
|
|
fragment
|
|
|
|
OCTAL_ESC
|
|
|
|
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
|
|
|
|
| '\\' ('0'..'7') ('0'..'7')
|
|
|
|
| '\\' ('0'..'7')
|
|
|
|
;
|
|
|
|
|
|
|
|
fragment
|
|
|
|
UNICODE_ESC
|
|
|
|
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
|
|
|
|
;
|
|
|
|
fragment
|
|
|
|
INT : '0'..'9'+
|
|
|
|
;
|
|
|
|
|
|
|
|
fragment
|
|
|
|
HEX : '0x' HEX_DIGIT+
|
|
|
|
;
|