From: Philippe Proulx Date: Mon, 2 Oct 2023 16:02:02 +0000 (-0400) Subject: Add the directive form of a group (`!group`) X-Git-Tag: v0.10.0 X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=261c5ecfc67f0cb56a39f27a6d70542ac2d6a2cf;p=normand.git Add the directive form of a group (`!group`) This is to add some consistency regarding items which may contain other items: I want all of them to have an available `!xyz` form. Normand already has `!if` and `!repeat`, not it has `!group` (and the alias `!g`). The following two groups are equivalent: ( aa bb cc ) * 5 !group aa bb cc !end * 5 Change-Id: I00b2789c078c9b9216ab9b732bc3adeff39b0642 Signed-off-by: Philippe Proulx --- diff --git a/README.adoc b/README.adoc index fe99d82..c865f0f 100644 --- a/README.adoc +++ b/README.adoc @@ -29,7 +29,7 @@ _**Normand**_ is a text-to-binary processor with its own language. This package offers both a portable {py3} module and a command-line tool. -WARNING: This version of Normand is 0.9, meaning both the Normand +WARNING: This version of Normand is 0.10, meaning both the Normand language and the module/CLI interface aren't stable. ifdef::env-github[] @@ -411,10 +411,10 @@ A Normand comment may exist: * Between the last item and the ``pass:[*]`` character of a post-item repetition, and between that ``pass:[*]`` character and the following number or expression. -* Between the ``!repeat``/``!r`` prefix and the following constant - integer, name, or expression of a repetition block. -* Between the ``!if`` prefix and the following name or expression of a - conditional block. +* Between the ``!repeat``/``!r`` block opening and the following + constant integer, name, or expression of a repetition block. +* Between the ``!if`` block opening and the following name or expression + of a conditional block. A comment is anything between two ``pass:[#]`` characters on the same line, or from ``pass:[#]`` until the end of the line. Whitespaces and @@ -998,11 +998,20 @@ than a single item and to isolate labels. A group is: -. The `(` prefix. +. The `(`, `!group`, or `!g` opening. . Zero or more items. -. The `)` suffix. +. Depending on the group opening: ++ +-- +`(`:: + The `)` closing. + +`!group`:: +`!g`:: + The `!end` closing. +-- ==== Input: @@ -1022,7 +1031,9 @@ aa bb cc dd ee 6c 65 63 6c 65 72 63 ┆ •••••leclerc Input: ---- -((aa bb cc) * 3 dd ee) * 5 +!group + (aa bb cc) * 3 dd ee +!end * 5 ---- Output: @@ -1067,7 +1078,7 @@ if some expression is true, or no bytes at all if it's false. A conditional block is: -. The `!if` prefix. +. The `!if` opening. . One of: @@ -1097,7 +1108,7 @@ For the name `__NAME__`, this is equivalent to the . Zero or more items. -. The `!end` suffix. +. The `!end` closing. ==== Input: @@ -1157,7 +1168,7 @@ a given number of times. A repetition block is: -. The `!repeat` or `!r` prefix. +. The `!repeat` or `!r` opening. . One of: @@ -1190,7 +1201,7 @@ For the name `__NAME__`, this is equivalent to the . Zero or more items. -. The `!end` suffix. +. The `!end` closing. You may also use a <> after some items. The form ``!repeat{nbsp}__X__{nbsp}__ITEMS__{nbsp}!end`` diff --git a/normand/normand.py b/normand/normand.py index b2f3069..e2dbe0f 100644 --- a/normand/normand.py +++ b/normand/normand.py @@ -30,7 +30,7 @@ # Upstream repository: . __author__ = "Philippe Proulx" -__version__ = "0.9.0" +__version__ = "0.10.0" __all__ = [ "ByteOrder", "parse", @@ -665,15 +665,17 @@ class _Parser: return _Str(data, begin_text_loc) # Patterns for _try_parse_group() - _group_prefix_pat = re.compile(r"\(") - _group_suffix_pat = re.compile(r"\)") + _group_prefix_pat = re.compile(r"\(|!g(roup)?\b") + _group_suffix_paren_pat = re.compile(r"\)") # Tries to parse a group, returning a group item on success. def _try_parse_group(self): begin_text_loc = self._text_loc # Match prefix - if self._try_parse_pat(self._group_prefix_pat) is None: + m_open = self._try_parse_pat(self._group_prefix_pat) + + if m_open is None: # No match return @@ -682,9 +684,15 @@ class _Parser: # Expect end of group self._skip_ws_and_comments() - self._expect_pat( - self._group_suffix_pat, "Expecting an item or `)` (end of group)" - ) + + if m_open.group(0) == "(": + pat = self._group_suffix_paren_pat + exp = ")" + else: + pat = self._block_end_pat + exp = "!end" + + self._expect_pat(pat, "Expecting an item or `{}` (end of group)".format(exp)) # Return item return _Group(items, begin_text_loc) diff --git a/pyproject.toml b/pyproject.toml index 2d8f3c3..737d511 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ [tool.poetry] name = 'normand' -version = '0.9.0' +version = '0.10.0' description = 'Text-to-binary processor with its own language' license = 'MIT' authors = ['Philippe Proulx '] diff --git a/tests/fail-group-blk-missing-end.nt b/tests/fail-group-blk-missing-end.nt new file mode 100644 index 0000000..3bdc2f8 --- /dev/null +++ b/tests/fail-group-blk-missing-end.nt @@ -0,0 +1,3 @@ +!group aa bb cc "yeah" +--- +2:1 - Expecting an item or `!end` (end of group) diff --git a/tests/fail-group-blk-wrong-end.nt b/tests/fail-group-blk-wrong-end.nt new file mode 100644 index 0000000..c12360a --- /dev/null +++ b/tests/fail-group-blk-wrong-end.nt @@ -0,0 +1,3 @@ +!group aa bb cc ) +--- +1:17 - Expecting an item or `!end` (end of group) diff --git a/tests/fail-group-missing-suffix.nt b/tests/fail-group-missing-suffix.nt deleted file mode 100644 index e2eae33..0000000 --- a/tests/fail-group-missing-suffix.nt +++ /dev/null @@ -1,3 +0,0 @@ -( aa bb cc "yeah" ---- -2:1 - Expecting an item or `)` (end of group) diff --git a/tests/fail-group-paren-missing-end.nt b/tests/fail-group-paren-missing-end.nt new file mode 100644 index 0000000..e2eae33 --- /dev/null +++ b/tests/fail-group-paren-missing-end.nt @@ -0,0 +1,3 @@ +( aa bb cc "yeah" +--- +2:1 - Expecting an item or `)` (end of group) diff --git a/tests/fail-group-paren-wrong-end.nt b/tests/fail-group-paren-wrong-end.nt new file mode 100644 index 0000000..bd49980 --- /dev/null +++ b/tests/fail-group-paren-wrong-end.nt @@ -0,0 +1,3 @@ +( aa bb cc !end +--- +1:12 - Expecting an item or `)` (end of group) diff --git a/tests/pass-group-blk-g.nt b/tests/pass-group-blk-g.nt new file mode 100644 index 0000000..37fad30 --- /dev/null +++ b/tests/pass-group-blk-g.nt @@ -0,0 +1,4 @@ +!g $1 $2 $3 !end * 2 +--- +01 02 03 +01 02 03 diff --git a/tests/pass-group-blk-label-1.nt b/tests/pass-group-blk-label-1.nt new file mode 100644 index 0000000..1d83d60 --- /dev/null +++ b/tests/pass-group-blk-label-1.nt @@ -0,0 +1,6 @@ +00 !group 11 22 {mix-meow:8} 33 44 !end * 2 55 +--- +00 +11 22 03 33 44 +11 22 03 33 44 +55 diff --git a/tests/pass-group-blk-label-2.nt b/tests/pass-group-blk-label-2.nt new file mode 100644 index 0000000..2285e9d --- /dev/null +++ b/tests/pass-group-blk-label-2.nt @@ -0,0 +1,25 @@ +00 +!group + 11 {mix:8} 22 + !group + {meow + mix : 8} + !end * 3 + 33 +!end * 2 +44 +--- +00 + +11 04 22 + 08 + 09 + 0a +33 + +11 0b 22 + 16 + 17 + 18 +33 + +44 diff --git a/tests/pass-group-blk-label-3.nt b/tests/pass-group-blk-label-3.nt new file mode 100644 index 0000000..1f8b421 --- /dev/null +++ b/tests/pass-group-blk-label-3.nt @@ -0,0 +1,11 @@ +00 +!group + 11 22 {outer:8} {inner:8} {end:8} +!end * 3 + ff +--- +00 + 11 22 01 02 10 + 11 22 01 07 10 + 11 22 01 0c 10 +ff diff --git a/tests/pass-group-blk-no-rep.nt b/tests/pass-group-blk-no-rep.nt new file mode 100644 index 0000000..82881f9 --- /dev/null +++ b/tests/pass-group-blk-no-rep.nt @@ -0,0 +1,10 @@ +00 +!group + 11 22 33 + !group + aa bb cc + !end +!end +dd +--- +00 11 22 33 aa bb cc dd diff --git a/tests/pass-group-label-1.nt b/tests/pass-group-label-1.nt deleted file mode 100644 index dbfa2d8..0000000 --- a/tests/pass-group-label-1.nt +++ /dev/null @@ -1,6 +0,0 @@ -00 (11 22 {mix-meow:8} 33 44) * 2 55 ---- -00 -11 22 03 33 44 -11 22 03 33 44 -55 diff --git a/tests/pass-group-label-2.nt b/tests/pass-group-label-2.nt deleted file mode 100644 index 7eff18e..0000000 --- a/tests/pass-group-label-2.nt +++ /dev/null @@ -1,17 +0,0 @@ -00 (11 {mix:8} 22 ( {meow + mix : 8}) * 3 33) * 2 44 ---- -00 - -11 04 22 - 08 - 09 - 0a -33 - -11 0b 22 - 16 - 17 - 18 -33 - -44 diff --git a/tests/pass-group-label-3.nt b/tests/pass-group-label-3.nt deleted file mode 100644 index 57928b1..0000000 --- a/tests/pass-group-label-3.nt +++ /dev/null @@ -1,7 +0,0 @@ -00 (11 22 {outer:8} {inner:8} {end:8}) * 3 ff ---- -00 - 11 22 01 02 10 - 11 22 01 07 10 - 11 22 01 0c 10 -ff diff --git a/tests/pass-group-no-rep.nt b/tests/pass-group-no-rep.nt deleted file mode 100644 index 1afdc87..0000000 --- a/tests/pass-group-no-rep.nt +++ /dev/null @@ -1,3 +0,0 @@ -00 (11 22 33 (aa bb cc)) dd ---- -00 11 22 33 aa bb cc dd diff --git a/tests/pass-group-paren-label-1.nt b/tests/pass-group-paren-label-1.nt new file mode 100644 index 0000000..dbfa2d8 --- /dev/null +++ b/tests/pass-group-paren-label-1.nt @@ -0,0 +1,6 @@ +00 (11 22 {mix-meow:8} 33 44) * 2 55 +--- +00 +11 22 03 33 44 +11 22 03 33 44 +55 diff --git a/tests/pass-group-paren-label-2.nt b/tests/pass-group-paren-label-2.nt new file mode 100644 index 0000000..7eff18e --- /dev/null +++ b/tests/pass-group-paren-label-2.nt @@ -0,0 +1,17 @@ +00 (11 {mix:8} 22 ( {meow + mix : 8}) * 3 33) * 2 44 +--- +00 + +11 04 22 + 08 + 09 + 0a +33 + +11 0b 22 + 16 + 17 + 18 +33 + +44 diff --git a/tests/pass-group-paren-label-3.nt b/tests/pass-group-paren-label-3.nt new file mode 100644 index 0000000..57928b1 --- /dev/null +++ b/tests/pass-group-paren-label-3.nt @@ -0,0 +1,7 @@ +00 (11 22 {outer:8} {inner:8} {end:8}) * 3 ff +--- +00 + 11 22 01 02 10 + 11 22 01 07 10 + 11 22 01 0c 10 +ff diff --git a/tests/pass-group-paren-no-rep.nt b/tests/pass-group-paren-no-rep.nt new file mode 100644 index 0000000..1afdc87 --- /dev/null +++ b/tests/pass-group-paren-no-rep.nt @@ -0,0 +1,3 @@ +00 (11 22 33 (aa bb cc)) dd +--- +00 11 22 33 aa bb cc dd diff --git a/tests/pass-readme-learn-group-2.nt b/tests/pass-readme-learn-group-2.nt index 2e37b36..cb93612 100644 --- a/tests/pass-readme-learn-group-2.nt +++ b/tests/pass-readme-learn-group-2.nt @@ -1,4 +1,6 @@ -((aa bb cc) * 3 dd ee) * 5 +!group + (aa bb cc) * 3 dd ee +!end * 5 --- aa bb cc aa bb cc aa bb cc dd ee aa bb cc aa bb cc aa bb cc dd ee aa bb cc aa bb cc aa bb cc dd