public BinaryFileSchema GetBFSTree(PegNode rootnode)
{
//First pass below root. Expecting datablocks and byteOrder fields.
PegNode node = rootnode.child_;
do
{
PegNode field = node;
EBinaryFileSchemaParser field_id = GetNodeId(field);
bool isformat = false;
BfsSourceRange formatrange = GetSourceRange(field);
BfsSourceRange blocktyperange;
//BYTEORDER
if (GetNodeId(field) == EBinaryFileSchemaParser.byteorder)
{
BfsByteOrder byteorder = new BfsByteOrder();
StoreSourceRange(field, byteorder);
if ( GetNodeId(field.child_) == EBinaryFileSchemaParser.littleendian)
byteorder.ByteOrder = BfsByteOrderEnum.LittleEndian;
else if (GetNodeId(field.child_) == EBinaryFileSchemaParser.bigendian)
byteorder.ByteOrder = BfsByteOrderEnum.BigEndian;
else
byteorder.ByteOrder = BfsByteOrderEnum.LanguageDefault;
schema.ByteOrder = byteorder;
}
else
{
PegNode block_content = field.child_;
//If the first node is a 'format' flag, go to next sibling
if (GetNodeId(block_content) == EBinaryFileSchemaParser.formatspecifier)
{
isformat = true;
formatrange = GetSourceRange(block_content);
block_content = block_content.next_;
}
blocktyperange = GetSourceRange(block_content);
block_content = block_content.next_;
IBfsDataBlock block;
switch (field_id)
{
//STRUCT
case EBinaryFileSchemaParser.p_struct:
block = new BfsStruct();
StoreSourceRange(node, block);
block.IsFormat = isformat;
ConvertStructType(block_content, block as IBfsStructType);
schema.DatablockList.Add(block);
break;
//ABS_OFFSET
case EBinaryFileSchemaParser.abs_offset:
block = new BfsAbsOffset();
StoreSourceRange(node, block);
block.IsFormat = isformat;
ConvertStructType(block_content, block as IBfsStructType);
schema.DatablockList.Add(block);
break;
//REL_OFFSET
case EBinaryFileSchemaParser.rel_offset:
block = new BfsRelOffset();
StoreSourceRange(node, block);
block.IsFormat = isformat;
ConvertStructType(block_content, block as IBfsStructType);
schema.DatablockList.Add(block);
break;
//ENUM
case EBinaryFileSchemaParser.p_enum:
block = new BfsEnum();
StoreSourceRange(node, block);
block.IsFormat = isformat;
ConvertEnumType(block_content, block as BfsEnum);
schema.DatablockList.Add(block);
break;
//BITFIELD
case EBinaryFileSchemaParser.bitfield:
block = new BfsBitfield();
StoreSourceRange(node, block);
block.BlockTypeSourceRange = GetSourceRange(field);
block.IsFormat = isformat;
ConvertBitfieldType(block_content, block as BfsBitfield);
schema.DatablockList.Add(block);
break;
default:
throw new AstConvertException("Not a data-block: " + GetNodeId(block_content));
}
block.BlockTypeSourceRange = blocktyperange;
if (isformat)
block.FormatSourceRange = formatrange;
}
}
while ((node = node.next_) != null);
return schema;
}