Skip to content

Latest commit

 

History

History
 
 

yanlr

  • infos = Information about the yanlr plugin is in keys below
  • infos/author = René Schwaiger sanssecours@me.com
  • infos/licence = BSD
  • infos/needs = directoryvalue yamlsmith
  • infos/provides = storage/yaml
  • infos/recommends =
  • infos/placements = getstorage
  • infos/status = maintained unittest preview experimental unfinished nodoc concept discouraged
  • infos/metadata =
  • infos/description = This storage plugin use a parser generated by ANTLR to read YAML files

Yan LR

Introduction

This plugin uses ANTLR to generate a parser for the YAML serialization format. Apart from the hand written lexer, all other parts of the plugin use standard ANTLR tools, such as

.

Dependencies

The plugin requires

If packages for those libraries are not available for your system, you can install them manually. For more information about that please take a look at ANTLR’s homepage and at the ReadMe of the ANTLR C++ runtime.

Please note that we only tested the plugin with ANTLR 4.7.1 (and later versions of ANTLR).

Arch Linux

In Arch Linux the required packages are called antlr4 and antlr4-runtime.

pacman -Sy --noconfirm antlr4 antlr4-runtime

Debian Linux

In Debian Linux you need the packages antlr4 and libantlr4-runtime-dev.

apt-get -y install antlr4 libantlr4-runtime-dev

macOS

To install the dependencies of the plugin using Homebrew, please use the command below.

brew install antlr antlr4-cpp-runtime

Examples

Mappings

# Mount plugin to `user/tests/yanlr`
sudo kdb mount config.yaml user/tests/yanlr yanlr

# Manually add some mappings to the configuration file
printf 'all : circles presuppose\n' >  `kdb file user/tests/yanlr`
printf 'hello : world\n'            >> `kdb file user/tests/yanlr`

kdb ls /tests/yanlr
#> user/tests/yanlr/all
#> user/tests/yanlr/hello

kdb get user/tests/yanlr/all
#> circles presuppose

# Store value at root of mountpoint
kdb set user/tests/yanlr 'Mount Eerie'
kdb get user/tests/yanlr
#> Mount Eerie

# Add new key-value pairs
# Yan LR actually uses the YAML Smith plugin to write data
kdb set user/tests/yanlr/brand new
kdb set user/tests/yanlr/brand/new eyes
kdb set user/tests/yanlr/dance/gavin 'Dance!'

kdb ls /tests/yanlr
#> user/tests/yanlr
#> user/tests/yanlr/all
#> user/tests/yanlr/brand
#> user/tests/yanlr/brand/new
#> user/tests/yanlr/dance/gavin
#> user/tests/yanlr/hello

kdb get /tests/yanlr/hello
#> world
kdb get user/tests/yanlr/brand
#> new
kdb get /tests/yanlr/dance/gavin
#> Dance!

# Undo modifications to the key database
kdb rm -r user/tests/yanlr
sudo kdb umount user/tests/yanlr

Arrays

# Mount plugin to `/tests/yanlr`
sudo kdb mount config.yaml user/tests/yanlr yanlr

# Manually add a sequences to the configuration file
printf 'primes:\n'   >  `kdb file user/tests/yanlr`
printf '  - two\n'   >> `kdb file user/tests/yanlr`
printf '  - three\n' >> `kdb file user/tests/yanlr`
printf '  - five\n'  >> `kdb file user/tests/yanlr`

kdb ls user/tests/yanlr
#> user/tests/yanlr/primes
#> user/tests/yanlr/primes/#0
#> user/tests/yanlr/primes/#1
#> user/tests/yanlr/primes/#2

kdb set user/tests/yanlr/primes/#3 seven

# Retrieve index of last array element
kdb meta-get user/tests/yanlr/primes array
#> #3

# Undo modifications to the key database
kdb rm -r user/tests/yanlr
sudo kdb umount user/tests/yanlr

Boolean Values

# Mount plugin to `/tests/yanlr`
sudo kdb mount config.yaml user/tests/yanlr yanlr

# Manually add a boolean value to the database
printf 'boolean: true' > `kdb file user/tests/yanlr`

# Elektra stores boolean values as `0` and `1`
kdb get user/tests/yanlr/boolean
#> 1

# Undo modifications to the key database
kdb rm -r user/tests/yanlr
sudo kdb umount user/tests/yanlr

Null Values

# Mount plugin to `/tests/yanlr`
sudo kdb mount config.yaml user/tests/yanlr yanlr

# Manually add a null value to the database
printf '"null":' > `kdb file user/tests/yanlr`

# Elektra adds the metakey `binary` for empty keys
kdb meta-ls user/tests/yanlr/null
#> binary

# Undo modifications to the key database
kdb rm -r user/tests/yanlr
sudo kdb umount user/tests/yanlr

Error Messages

# Mount plugin
sudo kdb mount config.yaml user/tests/yanlr yanlr

# Manually add syntactically incorrect data
printf -- 'key: - element 1\n'                   >  `kdb file user/tests/yanlr`
printf -- '- element 2 # Incorrect Indentation!' >> `kdb file user/tests/yanlr`

# The plugin reports the location of the error
kdb ls user/tests/yanlr
# RET: 5
# STDERR: .*/config.yaml:2:1: mismatched input '- ' expecting end of map.*

# Let us look at the error message more closely.
# Since the location of `config.yaml` depends on the current user and OS,
# we store the text before `config.yaml` as `user/tests/error/prefix`.
kdb set user/tests/error "$(2>&1 kdb ls user/tests/yanlr)"
kdb set user/tests/error/prefix "$(kdb get user/tests/error | grep 'config.yaml' | head -1 | sed -E 's/(.*)config.yaml.*/\1/')"
# We also store the length of the prefix, so we can remove it from every
# line of the error message.
kdb set user/tests/error/prefix/length "$(kdb get user/tests/error/prefix | wc -c | sed 's/[ ]*//g')"

# Since we only want to look at the “reason” of the error, we
# remove the other part of the error message with `head` and `tail`.
kdb get user/tests/error | tail -n6 | cut -c"$(kdb get user/tests/error/prefix/length | tr -d '\n')"-
#> config.yaml:2:1: mismatched input '- ' expecting end of map
#>                  - element 2 # Incorrect Indentation!
#>                  ^^
#> config.yaml:2:37: extraneous input 'end of map' expecting end of document
#>                   - element 2 # Incorrect Indentation!
#>                                                       ^

# Fix syntax error
printf -- 'key: - element 1\n'        >  `kdb file user/tests/yanlr`
printf -- '     - element 2 # Fixed!' >> `kdb file user/tests/yanlr`

kdb ls user/tests/yanlr
#> user/tests/yanlr/key
#> user/tests/yanlr/key/#0
#> user/tests/yanlr/key/#1

# Undo modifications
kdb rm -r user/tests/error
kdb rm -r user/tests/yanlr
sudo kdb umount user/tests/yanlr

Limitations

  • The plugin does not support

    • plain scalars that span multiple lines,
    • special characters inside double quoted scalars,
    • other line endings than \n (Unix line endings),
    • block scalars,
    • flow collections,
    • tags,
    • anchors & aliases,
    • multiple documents, and
    • document start and end markers

    .

  • Yan LR does not provide write support for data. Please use the YAML Smith plugin for that purpose.

Input Restrictions

The plugin should, but does not, limit the amount

  • of nesting levels,
  • the length of numbers, and
  • the length of scalars

. These restrictions would make it less easy to crash the parser, by feeding it unrestricted data.

Duplicate Keys

Currently the plugin parses the input

duplicate: one
duplicate: two

storing the value two. According to the YAML specification the parser should not allow duplicated keys, and instead fail with an error, for the input above.

Comments

The lexer does currently tokenize comments. Consequently the plugin grammar of the plugin does also match comments. However, the listener does currently ignore comments.

Indentation

The lexer does not check for incorrect indentation. Consequently the following YAML data:

	value

will produce a plain scalar containing a tab character followed by the text value. The correct behavior would be to report an error, since YAML does not allow tab characters in indentation.

Error Messages

Visualized error messages (containing ^ markers) might not point to the correct error location, if the input contains tabs or unicode characters with a length other than 1.