diff options
author | ptmcg <ptmcg@austin.rr.com> | 2022-12-11 10:56:32 -0600 |
---|---|---|
committer | ptmcg <ptmcg@austin.rr.com> | 2022-12-11 10:56:32 -0600 |
commit | bcaeea1fa924a66a5b13c67cd830621e4eff4214 (patch) | |
tree | 405ee5a30ffb7ec292242e3828957dfbca430aec /pyparsing/core.py | |
parent | 8c72861e1ca49507f5cc201295c061d0e49e1bfa (diff) | |
download | pyparsing-git-bcaeea1fa924a66a5b13c67cd830621e4eff4214.tar.gz |
Added DelimitedList class, for better handling of naming and diagramming (replaces delimited_list function)
Diffstat (limited to 'pyparsing/core.py')
-rw-r--r-- | pyparsing/core.py | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/pyparsing/core.py b/pyparsing/core.py index 320d882..5c845ae 100644 --- a/pyparsing/core.py +++ b/pyparsing/core.py @@ -5049,6 +5049,71 @@ class ZeroOrMore(_MultipleMatch): return "[" + str(self.expr) + "]..." +class DelimitedList(ParseElementEnhance): + def __init__( + self, + expr: Union[str, ParserElement], + delim: Union[str, ParserElement] = ",", + combine: bool = False, + min: typing.Optional[int] = None, + max: typing.Optional[int] = None, + *, + allow_trailing_delim: bool = False, + ): + """Helper to define a delimited list of expressions - the delimiter + defaults to ','. By default, the list elements and delimiters can + have intervening whitespace, and comments, but this can be + overridden by passing ``combine=True`` in the constructor. If + ``combine`` is set to ``True``, the matching tokens are + returned as a single token string, with the delimiters included; + otherwise, the matching tokens are returned as a list of tokens, + with the delimiters suppressed. + + If ``allow_trailing_delim`` is set to True, then the list may end with + a delimiter. + + Example:: + + DelimitedList(Word(alphas)).parse_string("aa,bb,cc") # -> ['aa', 'bb', 'cc'] + DelimitedList(Word(hexnums), delim=':', combine=True).parse_string("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] + """ + if isinstance(expr, str_type): + expr = ParserElement._literalStringClass(expr) + expr = typing.cast(ParserElement, expr) + + if min is not None: + if min < 1: + raise ValueError("min must be greater than 0") + if max is not None: + if min is not None and max < min: + raise ValueError("max must be greater than, or equal to min") + + self.content = expr + self.raw_delim = str(delim) + self.delim = delim + self.combine = combine + if not combine: + self.delim = Suppress(delim) + self.min = min or 1 + self.max = max + self.allow_trailing_delim = allow_trailing_delim + + delim_list_expr = self.content + (self.delim + self.content) * ( + self.min - 1, + None if self.max is None else self.max - 1, + ) + if self.allow_trailing_delim: + delim_list_expr += Opt(self.delim) + + if self.combine: + delim_list_expr = Combine(delim_list_expr) + + super().__init__(delim_list_expr, savelist=True) + + def _generateDefaultName(self) -> str: + return "{0} [{1} {0}]...".format(self.content.streamline(), self.raw_delim) + + class _NullToken: def __bool__(self): return False |