# -*- coding: utf-8 -*-
#
# parselglossy -- Generic input parsing library, speaking in tongues
# Copyright (C) 2020 Roberto Di Remigio, Radovan Bast, and contributors.
#
# This file is part of parselglossy.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# For information on the complete list of contributors to the
# parselglossy library, see: <http://parselglossy.readthedocs.io/>
#
"""Getkw grammar generation."""
from typing import Any
from .atoms import (
bool_t,
complex_t,
data_t,
float_t,
fortranStyleComment,
int_t,
make_list_t,
quoted_str_t,
unquoted_str_t,
)
try:
import pyparsing as pp
except ImportError:
# Import local copy
from . import pyparsing as pp # type: ignore
[docs]def grammar(*, has_complex: bool = False) -> Any:
"""The Getkw recursive grammar.
Parameters
----------
has_complex: bool
Whether to include complex numbers. Defaults to `False`.
Returns
-------
A parsing grammar.
"""
EQ, COMMA = map(pp.Suppress, "=,")
LBRACE, RBRACE = map(pp.Suppress, "{}")
# Define key
key = pp.Word(pp.alphas + "_<>", pp.alphanums + "_<>")
# A scalar value (bool, int, float, str)
if has_complex:
scalar = quoted_str_t ^ complex_t ^ float_t ^ int_t ^ bool_t ^ unquoted_str_t
else:
scalar = quoted_str_t ^ float_t ^ int_t ^ bool_t ^ unquoted_str_t
# Coerce lists to be lists
list_t = make_list_t(scalar)
list_t.setParseAction(lambda t: [t])
# Define key-value pairs, i.e. our keywords
pair = pp.Group(key + EQ + list_t) | pp.Group(key + EQ + scalar)
# Define values and section recursively
section = pp.Forward()
values = pp.Forward()
section << pp.Group(key + LBRACE + values + RBRACE)
values << pp.Dict(pp.OneOrMore(section | data_t | pair))
# Define input
retval = pp.Dict(pp.OneOrMore(section) | pp.OneOrMore(values))
# Ignore Python (#), C/C++ (/* */ and //), and Fortran (!) style comments
comment = pp.cppStyleComment | pp.pythonStyleComment | fortranStyleComment
retval.ignore(comment)
return retval