How to parse an .eds file in C++?

  antlr, boost, c++, parsing

I need to parse this:

$ EZ-EDS Version 3.25.1.20181218 Generated Electronic Data Sheet

[File]
        DescText = "EtherNet/IP EDS for ANT lite+ PLC";
        CreateDate = 02-16-2018;
        CreateTime = 14:13:46;
        ModDate = 10-11-2019;
        ModTime = 11:05:09;
        Revision = 1.2;
        HomeURL = "www.bluebotics.com";
        1_IOC_Details_License = 0x7B457ED4;

[Device]
        VendCode = 1504;
        VendName = "BlueBotics SA";
        ProdType = 43;
        ProdTypeStr = "Generic Device";
        ProdCode = 1;
        MajRev = 1;
        MinRev = 2;
        ProdName = "ANT lite+ PLC";
        Icon = "ANT.ico";
        IconContents =
                "AAABAAEAICAAAAEAGACoDAAAFgAAACgAAAAgAAAAQAAAAAEAGAAAAAAAAAAA"
                "AAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////"
                "////////////////////////////////////////////////////////////"
                "////////////////////////////////////////////////////////////"
                "////////////////////////////////////////////////////////////"
                "///////////////3///3+//n497Guq2lcVKcUSmlQRCtTSGtWSmtYTmtZTmt"
                "XTmtWTGlTRicQQicTSGldVK1ppTO087e4+/39///////////////////////"
                "////////////////+//////v9/fOw72taUqlRRClTSG9hmPetq3v29b37+/3"
                "+/f/+///9//37/fv397evq3GimulUSmcOAitbUq1qpzW497v8/f/+///////"
                "///////////////////////////38+/GnoScSSGlVSG9jmvn297/9///////"
                "///////////////////////////////////37+fWrpSURRicSRCtinvO09bv"
                "8+/////////////////3///////////v7+/GhmuUOAi1dVrOurW1loy9tqXG"
                "x73e5+/38/f/9/f/+//////////////3////////////////////7+e9hmuU"
                "OAitcVLOz87v8+/////////////////////3+/+1loScOBC1hmP///+1fWOl"
                "VSmlYTmtZULGvr3OsqXn5+f////3+///+///////////////////////////"
                "///////OlnOUOAitfVrW39738//////////////////GqpScNAi9gmv/////"
                "//+lWTG1lnvGopSlYTnGnoycRRjW19bn4+fe29b38/f/////////////////"
                "///////////3///////OnoycPAi1inve3+f3+//////////e6++tUSmtXTH3"
                "7+/////////GhmucTRilYTm1aULGqpScVSnO197OopSlcULn7/f3+//v9///"
                "+/////////////////////////////+tbUqcSRjGur3v9//////////GnoSc"
                "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";

[Device Classification]
        Class1 = EtherNetIP;

$ ... more sections ...

[Connection Manager]
        Object_Name = "Connection Manager Object";
        Object_Class_Code = 0x06;
        Connection1 =
                0x04010002,             $ 0-15    = supported transport classes
                                        $ 16      = trigger: cyclic
                                        $ 17      = trigger: change of state
                                        $ 18      = trigger: application
                                        $ 19-23   = trigger: reserved
                                        $ 24      = application type: listen-only
                                        $ 25      = application type: input-only
                                        $ 26      = application type: exclusive-owner
                                        $ 27      = application type: redundant-owner
                                        $ 28-30   = reserved
                                        $ 31      = Direction: Client = 0 / Server = 1
                0x44440005,             $ 0       = O->T fixed size supported
                                        $ 1       = O->T variable size supported
                                        $ 2       = T->O fixed size supported
                                        $ 3       = T->O variable size supported
                                        $ 4-5     = O->T number of bytes per slot (obsolete)
                                        $ 6-7     = T->O number of bytes per slot (obsolete)
                                        $ 8-10    = O->T Real time transfer format
                                        $ 11      = reserved
                                        $ 12-14   = T->O Real time transfer format
                                        $ 15      = reserved
                                        $ 16      = O->T connection type: NULL
                                        $ 17      = O->T connection type: MULTICAST
                                        $ 18      = O->T connection type: POINT2POINT
                                        $ 19      = O->T connection type: reserved
                                        $ 20      = T->O connection type: NULL
                                        $ 21      = T->O connection type: MULTICAST
                                        $ 22      = T->O connection type: POINT2POINT
                                        $ 23      = T->O connection type: reserved
                                        $ 24      = O->T priority: LOW
                                        $ 25      = O->T priority: HIGH
                                        $ 26      = O->T priority: SCHEDULED
                                        $ 27      = O->T priority: reserved
                                        $ 28      = T->O priority: LOW
                                        $ 29      = T->O priority: HIGH
                                        $ 30      = T->O priority: SCHEDULED
                                        $ 31      = T->O priority: reserved
                100000,,Assem2,         $ O->T RPI, size, format
                100000,,Assem1,         $ T->O RPI, size, format
                ,,                      $ proxy config size, format
                ,,                      $ target config size, format
                "Data",                 $ Connection Name
                "Data blocks exchange", $ help string
                "20 04 24 03 2C 68 2C 67";    $ Path
        Connection2 =
                0x04010002,             $ 0-15    = supported transport classes
                                        $ 16      = trigger: cyclic
                                        $ 17      = trigger: change of state
                                        $ 18      = trigger: application
                                        $ 19-23   = trigger: reserved
                                        $ 24      = application type: listen-only
                                        $ 25      = application type: input-only
                                        $ 26      = application type: exclusive-owner
                                        $ 27      = application type: redundant-owner
                                        $ 28-30   = reserved
                                        $ 31      = Direction: Client = 0 / Server = 1
                0x22440005,             $ 0       = O->T fixed size supported
                                        $ 1       = O->T variable size supported
                                        $ 2       = T->O fixed size supported
                                        $ 3       = T->O variable size supported
                                        $ 4-5     = O->T number of bytes per slot (obsolete)
                                        $ 6-7     = T->O number of bytes per slot (obsolete)
                                        $ 8-10    = O->T Real time transfer format
                                        $ 11      = reserved
                                        $ 12-14   = T->O Real time transfer format
                                        $ 15      = reserved
                                        $ 16      = O->T connection type: NULL
                                        $ 17      = O->T connection type: MULTICAST
                                        $ 18      = O->T connection type: POINT2POINT
                                        $ 19      = O->T connection type: reserved
                                        $ 20      = T->O connection type: NULL
                                        $ 21      = T->O connection type: MULTICAST
                                        $ 22      = T->O connection type: POINT2POINT
                                        $ 23      = T->O connection type: reserved
                                        $ 24      = O->T priority: LOW
                                        $ 25      = O->T priority: HIGH
                                        $ 26      = O->T priority: SCHEDULED
                                        $ 27      = O->T priority: reserved
                                        $ 28      = T->O priority: LOW
                                        $ 29      = T->O priority: HIGH
                                        $ 30      = T->O priority: SCHEDULED
                                        $ 31      = T->O priority: reserved
                10000,,Assem4,          $ O->T RPI, size, format
                10000,,Assem3,          $ T->O RPI, size, format
                ,,                      $ proxy config size, format
                ,,                      $ target config size, format
                "Motion",               $ Connection Name
                "Control of differential or tricycle motors",    $ help string
                "20 04 24 03 2C 69 2C 70";    $ Path
        Connection3 =
                0x04010002,             $ 0-15    = supported transport classes
                                        $ 16      = trigger: cyclic
                                        $ 17      = trigger: change of state
                                        $ 18      = trigger: application
                                        $ 19-23   = trigger: reserved
                                        $ 24      = application type: listen-only
                                        $ 25      = application type: input-only
                                        $ 26      = application type: exclusive-owner
                                        $ 27      = application type: redundant-owner
                                        $ 28-30   = reserved
                                        $ 31      = Direction: Client = 0 / Server = 1
                0x22440005,             $ 0       = O->T fixed size supported
                                        $ 1       = O->T variable size supported
                                        $ 2       = T->O fixed size supported
                                        $ 3       = T->O variable size supported
                                        $ 4-5     = O->T number of bytes per slot (obsolete)
                                        $ 6-7     = T->O number of bytes per slot (obsolete)
                                        $ 8-10    = O->T Real time transfer format
                                        $ 11      = reserved
                                        $ 12-14   = T->O Real time transfer format
                                        $ 15      = reserved
                                        $ 16      = O->T connection type: NULL
                                        $ 17      = O->T connection type: MULTICAST
                                        $ 18      = O->T connection type: POINT2POINT
                                        $ 19      = O->T connection type: reserved
                                        $ 20      = T->O connection type: NULL
                                        $ 21      = T->O connection type: MULTICAST
                                        $ 22      = T->O connection type: POINT2POINT
                                        $ 23      = T->O connection type: reserved
                                        $ 24      = O->T priority: LOW
                                        $ 25      = O->T priority: HIGH
                                        $ 26      = O->T priority: SCHEDULED
                                        $ 27      = O->T priority: reserved
                                        $ 28      = T->O priority: LOW
                                        $ 29      = T->O priority: HIGH
                                        $ 30      = T->O priority: SCHEDULED
                                        $ 31      = T->O priority: reserved
                10000,,Assem6,          $ O->T RPI, size, format
                10000,,Assem5,          $ T->O RPI, size, format
                ,,                      $ proxy config size, format
                ,,                      $ target config size, format
                "MotionTurret",         $ Connection Name
                "Control of turret motors",    $ help string
                "20 04 24 03 2C 71 2C 72";    $ Path
        Connection4 =
                0x04010002,             $ 0-15    = supported transport classes
                                        $ 16      = trigger: cyclic
                                        $ 17      = trigger: change of state
                                        $ 18      = trigger: application
                                        $ 19-23   = trigger: reserved
                                        $ 24      = application type: listen-only
                                        $ 25      = application type: input-only
                                        $ 26      = application type: exclusive-owner
                                        $ 27      = application type: redundant-owner
                                        $ 28-30   = reserved
                                        $ 31      = Direction: Client = 0 / Server = 1
                0x22440005,             $ 0       = O->T fixed size supported
                                        $ 1       = O->T variable size supported
                                        $ 2       = T->O fixed size supported
                                        $ 3       = T->O variable size supported
                                        $ 4-5     = O->T number of bytes per slot (obsolete)
                                        $ 6-7     = T->O number of bytes per slot (obsolete)
                                        $ 8-10    = O->T Real time transfer format
                                        $ 11      = reserved
                                        $ 12-14   = T->O Real time transfer format
                                        $ 15      = reserved
                                        $ 16      = O->T connection type: NULL
                                        $ 17      = O->T connection type: MULTICAST
                                        $ 18      = O->T connection type: POINT2POINT
                                        $ 19      = O->T connection type: reserved
                                        $ 20      = T->O connection type: NULL
                                        $ 21      = T->O connection type: MULTICAST
                                        $ 22      = T->O connection type: POINT2POINT
                                        $ 23      = T->O connection type: reserved
                                        $ 24      = O->T priority: LOW
                                        $ 25      = O->T priority: HIGH
                                        $ 26      = O->T priority: SCHEDULED
                                        $ 27      = O->T priority: reserved
                                        $ 28      = T->O priority: LOW
                                        $ 29      = T->O priority: HIGH
                                        $ 30      = T->O priority: SCHEDULED
                                        $ 31      = T->O priority: reserved
                10000,,Assem8,          $ O->T RPI, size, format
                10000,,Assem7,          $ T->O RPI, size, format
                ,,                      $ proxy config size, format
                ,,                      $ target config size, format
                "MotionActiveCasters",  $ Connection Name
                "Control of active casters",    $ help string
                "20 04 24 03 2C 73 2C 74";    $ Path
        Connection5 =
                0x04010002,             $ 0-15    = supported transport classes
                                        $ 16      = trigger: cyclic
                                        $ 17      = trigger: change of state
                                        $ 18      = trigger: application
                                        $ 19-23   = trigger: reserved
                                        $ 24      = application type: listen-only
                                        $ 25      = application type: input-only
                                        $ 26      = application type: exclusive-owner
                                        $ 27      = application type: redundant-owner
                                        $ 28-30   = reserved
                                        $ 31      = Direction: Client = 0 / Server = 1
                0x22440005,             $ 0       = O->T fixed size supported
                                        $ 1       = O->T variable size supported
                                        $ 2       = T->O fixed size supported
                                        $ 3       = T->O variable size supported
                                        $ 4-5     = O->T number of bytes per slot (obsolete)
                                        $ 6-7     = T->O number of bytes per slot (obsolete)
                                        $ 8-10    = O->T Real time transfer format
                                        $ 11      = reserved
                                        $ 12-14   = T->O Real time transfer format
                                        $ 15      = reserved
                                        $ 16      = O->T connection type: NULL
                                        $ 17      = O->T connection type: MULTICAST
                                        $ 18      = O->T connection type: POINT2POINT
                                        $ 19      = O->T connection type: reserved
                                        $ 20      = T->O connection type: NULL
                                        $ 21      = T->O connection type: MULTICAST
                                        $ 22      = T->O connection type: POINT2POINT
                                        $ 23      = T->O connection type: reserved
                                        $ 24      = O->T priority: LOW
                                        $ 25      = O->T priority: HIGH
                                        $ 26      = O->T priority: SCHEDULED
                                        $ 27      = O->T priority: reserved
                                        $ 28      = T->O priority: LOW
                                        $ 29      = T->O priority: HIGH
                                        $ 30      = T->O priority: SCHEDULED
                                        $ 31      = T->O priority: reserved
                10000,,Assem10,         $ O->T RPI, size, format
                10000,,Assem9,          $ T->O RPI, size, format
                ,,                      $ proxy config size, format
                ,,                      $ target config size, format
                "MotionSpeedVector",    $ Connection Name
                "Control of generic platform",    $ help string
                "20 04 24 03 2C 75 2C 76";    $ Path


I thought the best way to do this would be to write a context free gramar with something like antlr4. And I started using that, but I realized it needs the antlr runtime, and it just feels a little heavy weight for parsing a config file. Then I looked at boost ptree. And this format is extremely similar to .ini, but it supports multi line values with lists and strings. It also supports end of line comments. Is there an easy C++ library that I can just hand a CFG and get a map back with the config data?

I have an antlr cfg like this:

grammar eds;

eds                 :   section+;

section             :   header body;

header              :   '[' header_name ']';

body                :   field+;

field               :   name '=' value STMTEND;

header_name         :   Identifier+;

name                :   Identifier;

raw_value           :   string
                    |   integer
                    |   hex
                    |   version
                    |   date
                    |   time
                    |   raw_text;

value               :   raw_value
                    |   list;

list                :   raw_value list_value+;

list_value          :   ',' raw_value
                    |   ',';

raw_text            :   Identifier;

string              :   String_standard
                    |   string_list;

string_list         :   String_standard string_list
                    |   String_standard String_standard;

integer             :   Integer;
version             :   Version;
date                :   Date;
time                :   Time;
hex                 :   Hex;

String_standard     :   '"' ( Escape | ~(''' | '' | 'n' | 'r') | '.' | '+' + '/' | ' ')* '"';
 
Escape              :   '' ( ''' | '' );

Integer             :   NUMBER+;

Hex                 :   '0' 'x' HEX_DIGIT+;

Version             :   NUMBER+ '.' NUMBER+
                    |   NUMBER+ '.' NUMBER+ '.' NUMBER+
                    |   NUMBER+ '.' NUMBER+ '.' NUMBER+ '.' NUMBER+;

Date                :   NUMBER NUMBER '-' NUMBER NUMBER '-' NUMBER NUMBER NUMBER NUMBER;

Time                :   NUMBER NUMBER ':' NUMBER NUMBER ':' NUMBER NUMBER;

Identifier          :   Identifier_Char+;

fragment 
Identifier_Char     :   LETTER
                    |   NUMBER
                    |   '_';


fragment LETTER              :   [a-zA-Z];

fragment HEX_DIGIT           :   [a-fA-F0-9];

fragment NUMBER              :   [0-9];

STMTEND             :   SEMICOLON;

fragment SEMICOLON : ';';
fragment NEWLINE   : 'r' 'n' | 'n' | 'r';

WS:                 [ trnu000C]+ -> channel(HIDDEN);
LINE_COMMENT:       '$' ~[rn]*    -> channel(HIDDEN);

Source: Windows Questions C++

LEAVE A COMMENT