fortranfortran-namelist

Nested namelists in fortran


namelist is a useful fortran construct to quickly initialize variables from a file. A namelist has a name and contains a set of variables with a known type. This makes it similar to the type construct.

It happens often that the parameters given to a program or subroutine are best organized not as lists, but rather as hierarchical structures, like the menu interface. Extended type like type, extends(simple) :: advanced seems to be a good representation of this hierarchical structure.

However, reading this data representation with the namelist construct seems to be awkward because one might end up with very long namelists of the kind

&options
 very_long_option_X   =  1,
 very_long_option_Y   =  2,
 long_option_B%long_descriptive_name_a = 10,
 long_option_B%long_descriptive_name_b = 20,
 long_option_D%long_suboption_DD%long_descriptive_name_a = 300,
 long_option_D%long_suboption_DD%long_descriptive_name_b = 400,
 long_option_D%long_suboption_DD%long_descriptive_name_c = 500,
/

Many people would say it is not ideal and they would rather prefer

&options
   very_long_option_X   =  1,
   very_long_option_Y   =  2,
   &long_option_B
      long_descriptive_name_a = 10,
      long_descriptive_name_b = 20
   /
   &long_option_D
      &long_suboption_DD
         long_descriptive_name_a = 300,
         long_descriptive_name_b = 400,
         long_descriptive_name_c = 500
      /
   /
/

Therefore, I would like to ask what is a good approach to read such data structures. How do you deal with this kind of situations?


Solution

  • Configuration files are really an area where custom languages or at least custom grammar parsers are often implemented. Not just by Fortran programmers, but also (or mainly) by programmers of many other languages.

    Basically, one sketches a grammar which the configuration files should obey and then writes a parser for such a grammar either by hand, typically either as a recursive descent parser made of recursive functions consuming various elements of the grammar or as a state machine and defined transitions between the states. If one wants to avoid the manual route, one uses a parser generator (such as ANTLR) or parser combinators. These tools typically do not target Fortran. However, a search on github.com will reveal some recent parser generators for Fortran!

    Several years ago, when I needed a configuration file parser in Fortran, I went the manual recursive descent way. My humble attempt can be found in the ParseTrees module in https://bitbucket.org/LadaF/elmm/src/master/src/strings.f90 but it is far from perfect. I only show it for illustration. It reads config files like https://bitbucket.org/LadaF/elmm/src/master/examples/DIPLOS/area_sources.conf.

    Libraries for universal formats like JSON can certainly be used (and there are Fortran implementations, such as https://github.com/jacobwilliams/json-fortran), but you have to follow their format specification. For example, JSON does not allow comments and that is a no-no for me.

    Any advanced way you choose, you will be responsible for translating the data from the parsed syntax tree into your data structures. No tool can do it for you, AFAIAA. That is the aspect, in which the standard namelists really shine.