aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-02-19 13:29:34 +0100
committerHarald Welte <laforge@gnumonks.org>2011-02-19 13:29:34 +0100
commit334493f3b253438a4393c9a470a091799c65578c (patch)
tree54623c3a7fc3affb17b60ce39d264e0e6c8fd19f
parent832889c5e76f27dd9ae556416bd7428081038464 (diff)
Enhance grammar with AST rewrite rules
It now generates a pretty meaningful AST representation of the input data.
-rw-r--r--osmo_codegen.g62
1 files changed, 48 insertions, 14 deletions
diff --git a/osmo_codegen.g b/osmo_codegen.g
index 05a0335..68125e9 100644
--- a/osmo_codegen.g
+++ b/osmo_codegen.g
@@ -1,26 +1,44 @@
grammar osmo_codegen;
-//options {
+options {
//language = Python;
-//}
+ output = AST;
+}
+tokens {
+ PDUFIELD_OPT;
+ FIELD_VAL;
+ PDUFIELD_SIZE;
+ IEFIELD_ENDIAN;
+ IEFIELD_COND;
+
+ IE_SPECS;
+ IE_ALIASES;
+ PDU_SPECS;
+}
+
root :
(pdu_spec | ie_spec | ie_alias)*
+ -> ^(IE_SPECS ie_spec*) ^(IE_ALIASES ie_alias*) ^(PDU_SPECS pdu_spec*)
;
/* INFORMATION ELEMENTS */
/* An alias in the form "ie_alias new_name existing_field" */
-ie_alias: 'ie_alias' ie_name ie_name;
+ie_alias: 'ie_alias' ie_name ie_name
+ -> ^(ie_name ie_name)
+ ;
ie_name : ID;
ie_spec : 'ie_spec' ID
ie_field_def*
'end_ie_spec'
+ -> ^(ID ie_field_def*)
;
ie_field_def
- : ie_field_name ie_field_len ie_field_type ie_field_opts
+ : ie_field_name ie_field_len ie_field_type ie_field_opt*
+ -> ^(ie_field_name ie_field_type ie_field_len ie_field_opt*)
;
ie_field_name
@@ -34,16 +52,22 @@ ie_field_type
| 'bit' | 'bits'
| 'bcd' // BCD digits, always 'lower nibble, upper nibble, lower nibble, ...
);
-ie_field_opts
- : field_val? ie_field_cond? ie_field_endian?;
+ie_field_opt
+ : (field_val | ie_field_cond | ie_field_endian)
+ ;
ie_field_cond
- : 'if (' ie_field_name ('&' ie_field_cond_mask)? COMP_OP ie_field_cond_reference ')';
+ : '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)
+ ;
ie_field_cond_mask
: NUMERIC;
ie_field_cond_reference
: NUMERIC;
ie_field_endian
- : ('big' | 'little');
+ : ( 'big' -> ^(IEFIELD_ENDIAN 'big')
+ | 'little' -> ^(IEFIELD_ENDIAN 'little')
+ )
+ ;
/* PDU DEFINITIONS*/
@@ -51,20 +75,26 @@ ie_field_endian
pdu_spec
: 'pdu_spec' ID
pdu_field_def*
- 'end_pdu_spec'
+ 'end_pdu_spec' -> ^(ID pdu_field_def*)
;
pdu_field_mode
: 'mand' | 'opt' | 'cond';
field_val
- : ('val'|'value') NUMERIC; // Field always has to have indicated value
+ : ('val'|'value') NUMERIC // Field always has to have indicated value
+ -> ^(FIELD_VAL NUMERIC)
+ ;
field_tag
- : 'tag' NUMERIC; // for tagged fields
+ : 'tag' NUMERIC // for tagged fields
+ -> ^('tag' NUMERIC)
+ ;
pdu_field_size
- : NUMERIC ('-' NUMERIC)? ; // fixed length or range
+ : NUMERIC ('-' NUMERIC)? // fixed length or range
+ -> ^(PDUFIELD_SIZE NUMERIC*)
+ ;
pdu_field_opts
: pdu_up_downlink | pdu_opt_ie
@@ -72,7 +102,9 @@ pdu_field_opts
pdu_up_downlink
: 'uplink_only' | 'downlink_only'; // only valid in uplink or downlink
pdu_opt_ie
- : 'ie' ID; // use speciifed IE definition
+ : 'ie' ID // use speciifed IE definition
+ -> ^('ie' ID)
+ ;
pdu_field_type
: (
@@ -87,7 +119,9 @@ pdu_field_type
) pdu_field_opts*;
pdu_field_def
- : ID pdu_field_mode pdu_field_type;
+ : ID pdu_field_mode pdu_field_type
+ -> ^(ID pdu_field_mode pdu_field_type)
+ ;
/* LEXER RULES */