# A YAML parser for Fortran: fortran-yaml-cpp

**URL:** <https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022>\
**Category:** Announcements\
**Created:** [October 8, 2021, 8:07am UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022 "2021-10-08T08:07:25Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![nicholaswogan](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@nicholaswogan](https://fortran-lang.discourse.group/u/nicholaswogan)\
**Post date:** [October 8, 2021, 8:07am UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/1 "2021-10-08T08:07:25Z")

</div>

I put together a YAML parser for Fortran: [GitHub - Nicholaswogan/fortran-yaml-cpp: Fortran wrapper to the yaml-cpp parser](https://github.com/Nicholaswogan/fortran-yaml-cpp) . Currently at version 0.0.1

It is an interface to the C++ package [yaml-cpp](https://github.com/jbeder/yaml-cpp). I use yaml-cpp to parse a yaml document, then I load the data into Fortran derived types created by [fortran-yaml](https://github.com/BoldingBruggeman/fortran-yaml). So it’s just knitting two packages together. The API is nearly identical to `fortran-yaml`.

The reason I did this was because `fortran-yaml` isn’t a full yaml parser. It can’t deal with flow style, or multiline strings, and a bunch of other stuff. Initially, I tried improving the parser in `fortran-yaml` so that it could parse more yaml syntax, but this turned out to be really hard. Knitting together `yaml-cpp` and `fortran-yaml` was much easier.

I would appreciate any feedback/issues/suggestions! This is the most involved merger of Fortran and C++ I’ve tried, so I probably made mistakes that need catching.

---

<div class="post-metadata">

**Author:** ![epagone](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/epagone/32/252_2.png) [@epagone](https://fortran-lang.discourse.group/u/epagone)\
**Post date:** [October 8, 2021, 10:51am UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/2 "2021-10-08T10:51:22Z")

</div>

Many thanks for doing this @nicholaswogan. I am really excited by this news and I can’t wait to test it (although I might not have time for this in the near future ☹ ).

Although it is probably not the sort of feedback that you are expecting, I’d ask if you can package the library with fpm. For my use case, it would be a big improvement.

Also, have you compared the features of your parser with the young but excellent [yaFyaml](https://github.com/Goddard-Fortran-Ecosystem/yaFyaml)?

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [October 8, 2021, 2:31pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/3 "2021-10-08T14:31:19Z")

</div>

@nicholaswogan thanks for doing that. As @epagone asked, if you wouldn’t mind adding `fpm` build system that would make it much easier for others to try.

---

<div class="post-metadata">

**Author:** ![nicholaswogan](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@nicholaswogan](https://fortran-lang.discourse.group/u/nicholaswogan)\
**Post date:** [October 8, 2021, 4:52pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/4 "2021-10-08T16:52:25Z")

</div>

`yaFyaml` does looks excellent!! I think I like the API more than fortran-yaml. But I can’t figure out how to build yaFyaml. It has some dependencies which are not included in the github repo (GFTL).

@certik @epagone I will package fortran-yaml-cpp with fpm, but I have to work out how to do this when CMake is involved. CMake has to be involved because it needs to build the C++ package yaml-cpp.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [October 8, 2021, 5:01pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/5 "2021-10-08T17:01:54Z")

</div>

I think there are three ways:

- You can just call `cmake` to build the C++ package in a build script that `fpm` just calls
- You can assume it is already installed, so you just tell `fpm` the correct compiler flags to link with it
- You provide an `fpm` build system for the C++ package and just depend on it

@awvwgk, what is the best way forward in this case?

---

<div class="post-metadata">

**Author:** ![awvwgk](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/awvwgk/32/154_2.png) [@awvwgk](https://fortran-lang.discourse.group/u/awvwgk)\
**Post date:** [October 8, 2021, 6:34pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/6 "2021-10-08T18:34:30Z")

</div>

> [@certik](#):
>
> You can assume it is already installed, so you just tell `fpm` the correct compiler flags to link with it

Linking against a system library seems like the most feasible approach IMO.

---

<div class="post-metadata">

**Author:** ![nicholaswogan](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@nicholaswogan](https://fortran-lang.discourse.group/u/nicholaswogan)\
**Post date:** [October 8, 2021, 9:22pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/7 "2021-10-08T21:22:11Z")

</div>

@awvwgk I just tried this approach, and its not working out. fpm doesn’t seem to be executing my build-script.

> [@certik](#):
>
> You can just call `cmake` to build the C++ package in a build script that `fpm` just calls

Is this implemented in the latest release? I am using `Version: 0.4.0, alpha`

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [October 8, 2021, 10:49pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/8 "2021-10-08T22:49:30Z")

</div>

Can you provide steps for us to reproduce the error you are getting?

---

<div class="post-metadata">

**Author:** ![nicholaswogan](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@nicholaswogan](https://fortran-lang.discourse.group/u/nicholaswogan)\
**Post date:** [October 8, 2021, 11:42pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/9 "2021-10-08T23:42:40Z")

</div>

Here is my directory structure:

```auto
.
├── CMakeLists.txt
├── LICENSE.txt
├── README.md
├── fpm.toml
├── my_build_script.sh
├── src
│ ├── CMakeLists.txt
│ ├── yaml-cpp
│ ├── yaml.cpp
│ ├── yaml.f90
│ └── yaml_types.f90
├── test.yaml
└── tests
    ├── example.f90
    └── test.f90

```

My `fpm.toml`:

```auto
name = "fortran-yaml-cpp"
version = "0.0.1"
license = "MIT"
author = "Nick Wogan"
maintainer = "nicholaswogan@gmail.com"
copyright = "2021 Nick Wogan"

[library]
source-dir="src"
build-script="my_build_script.sh"

[[executable]]
name="runTests"
source-dir="tests"
main="test.f90"

```

and `my_build_script.sh`:

```bash
mkdir cmake_build_dir
cmake -B cmake_build_dir -S . -DFPM_BUILD=ON
cmake --build cmake_build_dir -j

```

The idea is to do all the right things in `CMakeLists.txt` for fpm work when `FPM_BUILD=ON`.

When I run `fpm build`, I get the following

```auto
 + mkdir -p build/dependencies
 + mkdir -p build/gfortran_2A42023B310FA28D/fortran-yaml-cpp
 + gfortran -c ././src/yaml_types.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/fortran-yaml-cpp -I build/gfortran_2A42023B310FA28D/fortran-yaml-cpp -o build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/src_yaml_types.f90.o
././src/yaml_types.f90:192:40:

  192 | subroutine null_dump(self,unit,indent)
      | 1
Warning: Unused dummy argument 'indent' at (1) [-Wunused-dummy-argument]
././src/yaml_types.f90:192:28:

  192 | subroutine null_dump(self,unit,indent)
      | 1
Warning: Unused dummy argument 'self' at (1) [-Wunused-dummy-argument]
././src/yaml_types.f90:186:41:

  186 | subroutine value_dump(self,unit,indent)
      | 1
Warning: Unused dummy argument 'indent' at (1) [-Wunused-dummy-argument]
././src/yaml_types.f90:107:42:

  107 | recursive subroutine node_finalize(self)
      | 1
Warning: Unused dummy argument 'self' at (1) [-Wunused-dummy-argument]
 + gfortran -c ././src/yaml.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/fortran-yaml-cpp -I build/gfortran_2A42023B310FA28D/fortran-yaml-cpp -o build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/src_yaml.f90.o
././src/yaml.f90:55:37:

   55 | filename_copy = filename//char(0)
      | ^
Warning: '.filename_copy' may be used uninitialized [-Wmaybe-uninitialized]
 + ar -rs build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/libfortran-yaml-cpp.a build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/src_yaml_types.f90.o build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/src_yaml.f90.o
ar: creating archive build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/libfortran-yaml-cpp.a
 + gfortran -c tests/test.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/fortran-yaml-cpp -I build/gfortran_2A42023B310FA28D/fortran-yaml-cpp -o build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/tests_test.f90.o
 + gfortran -c tests/example.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/fortran-yaml-cpp -I build/gfortran_2A42023B310FA28D/fortran-yaml-cpp -o build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/tests_example.f90.o
tests/example.f90:41:61:

   41 | string = trim(dict%get_string("equation",error = io_err))
      | ^
Warning: '.string' may be used uninitialized [-Wmaybe-uninitialized]
 + mkdir -p build/gfortran_2A42023B310FA28D/app/
 + gfortran -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/fortran-yaml-cpp -I build/gfortran_2A42023B310FA28D/fortran-yaml-cpp build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/tests_test.f90.o build/gfortran_2A42023B310FA28D/fortran-yaml-cpp/libfortran-yaml-cpp.a -o build/gfortran_2A42023B310FA28D/app/runTests
Undefined symbols for architecture x86_64:
  "_DestroyNode", referenced from:
      ___yaml_MOD_parse in libfortran-yaml-cpp.a(src_yaml.f90.o)
  "_LoadFile_c", referenced from:
      ___yaml_MOD_loadfile in libfortran-yaml-cpp.a(src_yaml.f90.o)
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
<ERROR> Compilation failed for object " runTests "
<ERROR>stopping due to failed compilation
STOP 1

```

`my_build_script.sh` is never executed. Instead, fpm compiles `src/yaml.f90` and `src/yaml_types.f90` and does not compile `src/yaml.cpp`, and makes `libfortran-yaml-cpp.a`. Then fpm tries to build and link the executable `runTests`, but fails because symbols from `src/yaml.cpp` are not contained in `libfortran-yaml-cpp.a`.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [October 9, 2021, 12:09am UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/10 "2021-10-09T00:09:09Z")

</div>

Thank you for this. @awvwgk do you know where the problem could be?

---

<div class="post-metadata">

**Author:** ![awvwgk](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/awvwgk/32/154_2.png) [@awvwgk](https://fortran-lang.discourse.group/u/awvwgk)\
**Post date:** [October 9, 2021, 12:24am UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/11 "2021-10-09T00:24:39Z")

</div>

> [@certik](#):
>
> do you know where the problem could be?

We currently don’t support build scripts in Fortran fpm. The key in library is still leftover from the Haskell implementation, but we didn’t get around to actually implement a build script hook yet in the Fortran version. So this is an open issue at the moment.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [October 9, 2021, 10:43am UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/12 "2021-10-09T10:43:58Z")

</div>

I don’t think fpm’s support for C++ files is there yet either. It might work in some cases just because the gcc or icc compiler commands by default enable both C and C++. I think there can be some issues with choosing the right linker.

The related issue for fpm is here:

> <https://github.com/fortran-lang/fpm/issues/353>
>
> Fpm already has a preliminary support for C and C++ source files. But there are …still some issues to iron out. Here are a few that I am aware of, we should create individual issues out of these and link them here. 
> 
> \* \[\] One issue is that you currently have to manually \[specify\](https://fortran-lang.discourse.group/t/fortran-and-c/685) \`stdc++\` in \`fpm.toml\`. It should work automatically.
> 
> \* \[\] I think we need to add tests for this and test it at our CI.
> 
> \* \[\] Document this feature in our documentation
> 
> \* \[\] Ensure this works with MPI. Fpm does not support MPI yet, so we should add support first (#354). I remember there being issues regarding whether the main program has to be linked as a C++ or Fortran project.

To work with fpm currently, you’ll have to install your C++ dependency first as a system library, and then add something like:

```auto
link = ["yaml-cpp", "stdc++"]

```

into your TOML file.

Improved C++ support in fpm is something that should definitely be pursued.

---

<div class="post-metadata">

**Author:** ![nicholaswogan](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@nicholaswogan](https://fortran-lang.discourse.group/u/nicholaswogan)\
**Post date:** [October 13, 2021, 4:10pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/13 "2021-10-13T16:10:45Z")

</div>

The way I’ve laid out the package currently, I think this method won’t quite work because `fortran-yaml-cpp` has a little bit of C++ code in it, which needs compiling.

So I think I would need to fork `yaml-cpp`, add my C++ code to `libyaml-cpp`, and make this modified version of yaml-cpp a dependency.

But there would still be the issue of the linker. I think fpm would need to use a C++ linker to make an executable.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [October 13, 2021, 4:58pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/14 "2021-10-13T16:58:29Z")

</div>

If you have time to help us improve `fpm` to work well with C++, please do. It’s a must have feature as far as I am concerned.

---

<div class="post-metadata">

**Author:** ![tom\_clune](https://avatars.discourse-cdn.com/v4/letter/t/94ad74/32.png) [@tom\_clune](https://fortran-lang.discourse.group/u/tom_clune)\
**Post date:** [May 19, 2022, 5:29pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/15 "2022-05-19T17:29:13Z")

</div>

I’m the primary developer of yaFyaml - and only incidentally stumbled into this thread just now.

I recently released yaFyaml v1.0 which changes some of the interfaces. I’d be happy to help anyone that is having difficulty with installation - it does indeed depend on 2 other packages: gFTL and gFTL-shared. gFTL is a utility that generates templates for software containers with similar interfaces to C++ STL containers. gFTL-shared is a library that instantiates those containers for common cases of intrinsic types. And gFTL-shared includes gFTL as a submodule, so you really only need to install it - installs in a canonical CMake manner.

Happy to help out anyone interested. Contact me on GitHub or email: [Thomas.L.Clune@nasa.gov](mailto:Thomas.L.Clune@nasa.gov)

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [May 22, 2022, 11:54pm UTC](https://fortran-lang.discourse.group/t/a-yaml-parser-for-fortran-fortran-yaml-cpp/2022/16 "2022-05-22T23:54:11Z")

</div>

Thanks @tom_clune for posting and welcome to the forum!
