Tuesday, 30 September 2014

Completing Data Type reference in Xtext Grammar

As described in overview from the first post, its almost close to produce CSV artefacts containing OID short name, Oid in dot notation number, derived data type and its primitive data type.

The part missing from model now is the data type information. This can be completed with following modification to Xtext grammar and Xcore.


Mib.xtext
ObjectType:
 name=ID imp=[Macro] 
 'SYNTAX' type=mibType2
 'ACCESS' access=AccessEnum 
 'STATUS' status=StatusEnum 
 ('DESCRIPTION' description=STRING)? 
 ('REFERENCE' reference=STRING)? 
 ('INDEX' '{' mibType (',' mibType)* '}')? 
 ('DEFVAL' '{' INT | STRING '}')? 
 value=OidValue;

ObjectType class will now contain feature type of mibType2 among others. mibType2 is similiar to mibType, the reason I have created another instance of mibType is as it used in lot of places such as Macro, Object Type Index, Choice etc. All these rightfully need to be changed as well, however for now I want to keep it simple - it can be overwhelming otherwise.


Mib.xtext
mibType2:
 (sequence?=SequenceOf)? 
 dataType=DataType
 ('(' 'SIZE' '(' (INT '..')? INT ')'')')? 
 ('(' (INT '..')? (INT | 'MAX') ')')? 
 ('{' ID '(' INT ')' (',' ID '(' INT ')')* '}')?;

DataType:
 name=(OctectString | 'INTEGER' | ObjectIdentifier) |
 derived=[TypeDefinition];

SequenceOf:
 'SEQUENCE' 'OF';
 
ObjectIdentifier:
 'OBJECT' 'IDENTIFIER';

OctectString:
 'OCTET' 'STRING';


One trick I learned here is that if there are multiple keywords make up a syntax, its better to push those down to its own rule e.g SequenceOf - Xtext  intelligent enough to know this is terminal like rule and will not create an EClass for it.

Datatype takes primitive data types (3 types) or a derived data type from TypeDefinition.  Note that this 'TypeDefinition' used to be called 'DataType' earlier - re-factored to reflect semantic better.


Mib.xtext
Definition:
 name=ID 'DEFINITIONS' '::=' 'BEGIN'
 Export?
 imports=Import?
 (identifiers+=Identifier | typedef+=TypeDefinition | macros+=Macro)+
 'END';

TypeDefinition:
 name=ID '::=' ('[' 'APPLICATION' INT ']')? 
 'IMPLICIT'? (Choice | Sequence | type=mibType2);

And to reflect this on Xcore, following need to be changed:


Mib.xtext
class Definition {
 String name
 contains Import imports
 contains Identifier[] identifiers
 contains TypeDefinition[] typedef
 contains Macro[] macros
}

class TypeDefinition {
 String name
 contains mibType2 ^type
}

Setting TypeDefinition as containment for Definition allows Object Type's type to refer to this.

Mib.xtext
class ObjectType extends Identifier {
 refers Macro imp
 contains mibType2 ^type
 AccessEnum access
 StatusEnum status
 String description
 String reference
}

enum AccessEnum {
 readOnly as "read-only"
 readWrite as "read-write" = 1
 writeOnly as "write-only" = 2
 notAccessible as "not-accessible" = 3
}

enum StatusEnum {
 mandatory
 optional = 1
 obsolete = 2
 deprecated = 3
}

Now running this will give full "open declaration" for type with derived data type as well.


No comments:

Post a Comment