0

I need to write reader class for a program config file, and I'm trying to determine the best way to approach this.

I have some experience with boost::spirit (actually, just enough to know that I am terrible at writing grammars), and a good bit of experience with regular-expressions.

Other than that, I can't think of much. So my options seem to be:

  1. boost::spirit
  2. std or boost regex
  3. ol' fashion string parsing

I am looking for suggestions or advice on how to proceed - or even pseudo-code should anyone feel inclined.

I realize this is a bit of an opinion-based question, but I'm really struggling with writers-block here. I'm worried I'll start down a path, and waste a lot of time before realizing it was a poor choice.

The config file format is already defined, and looks like this:

Group1 {
    Scalar1 = 500
    Scalar2 = 45.5
    Scalar3 = My Value
    List1 {
        LS1 = 123
        LS2 = hello world
    }
    List2 {
        LS1 = 456
        LS2 = goodbye world
    }
    Array1 [
        300
        200
        25
    ]
    Array2 [
        true
        false
        true
        false
    ]
};
  • The config will always have at least one Group.
  • A Group will contain 0..n Scalar, List, and/or Array entries
  • A scalar is: label = value
  • A List is a labeled container of Scalars
  • An Array is a labeled container of values

The labels shown (eg. Scalar1, Scalar2, ...) are just examples. They can be called anything: maxrate = 500, avg_val = 45.5, would have been just as valid.

Blair Fonville
  • 908
  • 1
  • 11
  • 23
  • quick question: why do you want to define your own config format when there are already quite a few config formats out there? – DZDomi Jun 22 '18 at 00:15
  • @DZDomi Thanks for the comment. The config format is already defined. I need to write a lib to conform to the format that is already in use. I didn't make that clear. If you have a suggestion, though, I could propose changing the format as a possible path. – Blair Fonville Jun 22 '18 at 00:17
  • 1
    The language looks small. IMHO, unless you have extensive experience with Boost::Spirit, Flex or Bison, write your own. I could write this up faster than I could get the above tools working. I recommend in any case, draw a parsing diagram and maybe also BNF format. – Thomas Matthews Jun 22 '18 at 00:20
  • @ThomasMatthews beat me to it. Only thing I'd add is I don't think Regex is a good fit for this one. – user4581301 Jun 22 '18 at 00:21
  • 2
    Look up recursive descent parsing, this would be very easy and clean done that way. Unless you have a grammar for numeric literals I'd just define them as "whatever strtod and strtol parse" – gct Jun 22 '18 at 00:23
  • @ThomasMatthews I was thinking the same. My biggest concern though, are the scalar values, which can be strings. And the strings could contain []{} characters. This would complicate things a little as I'd have to be careful to match openings and closings. I didn't know if a grammar would be better suited for that reason. – Blair Fonville Jun 22 '18 at 00:26
  • @SeanMcAllister Not sure how I missed that. It's perfect for recursive descent - and I already have some code I can reuse. Thanks – Blair Fonville Jun 22 '18 at 00:31
  • 1
    @BlairFonville Glad to hear it. For strings and such, I'd write a regexp to try to suck them out. – gct Jun 22 '18 at 00:32
  • I never said to not develop a grammar. Some grammars are not worth the hassle of the big tools. – Thomas Matthews Jun 22 '18 at 02:05
  • @ThomasMatthews No, you’re right. In fact you specifically said that I should. I misspoke - I meant to write “I didn’t know if a grammar library would better suited”. If I could trust that there would be no human error, the parsing would be trivial. My primary goal is robust error detection and handling. That’s where it gets most complicated. I probably should have stated that in the question. – Blair Fonville Jun 22 '18 at 02:24
  • See my article on how to write a recursive descent parser. This is actually pretty easy. https://stackoverflow.com/questions/2245962/is-there-an-alternative-for-flex-bison-that-is-usable-on-8-bit-embedded-systems/2336769#2336769 – Ira Baxter Jun 22 '18 at 09:11

1 Answers1

1

Copy the file to tmp, replacing every instance of = with :, then read it as json with boost::ptree.

Red.Wave
  • 2,790
  • 11
  • 17
  • While this doesn't work "out of the box", I can definitely work with this, and it's probably the quickest path to take. It's just what I was looking for. Thanks. – Blair Fonville Jun 25 '18 at 19:06
  • you're wellcome. The config syntax was really similar to json. Actually if the assignment were replaced with colon, it'd be json. – Red.Wave Jun 25 '18 at 20:08
  • I also had to add commas after each entry, and wrap entry names and string values (where values included spaces) in quotes. But it was a quick fix, and gave me the error detection that I needed. – Blair Fonville Jun 25 '18 at 20:16