Repository: zalmane/copybook (language: python)

Issue:
Accept + editing sign control symbol for signed data items
copybook accepts the minus ("-") editing sign control symbol to indicate a signed data item, but it doesn't accept the plus ("+") editing sign control symbol.

For example, this PICTURE clause:

           01  WORK-BOOK.
             10  AMOUNT2       PIC +9(4).99.

fails with this exception:

    pyparsing.exceptions.ParseException: Expected end of text, found '10'  (at char 32), (line:3, col:10)

[See **Table 1. PICTURE clause symbol meanings** in the IBM Enterprise COBOL z/OS documentation](https://www.ibm.com/docs/en/cobol-zos/4.2?topic=clause-symbols-used-in-picture)


Discussion / hints:
I will submit a pull request.
interesting. What does the + represent in the PICTURE? The same as '-'? just representing a signed number?
Yes, but I think + means the value will always include a sign (even if it is positive), while - means the value will only include a sign if it is negative.
I'm very new to COBOL, but my assertion is based on [**External floating-point items** in the Enterprise COBOL for z/OS documentation](https://www.ibm.com/docs/en/cobol-zos/4.2?topic=clause-data-categories-picture-rules)

> \+ or -
>
> A + sign indicates that a positive sign will be used in the output to represent positive values and that a negative sign will represent negative values.
>
> A - sign indicates that a blank will be used in the output to represent positive values and that a negative sign will represent negative values.

Fix patch:
diff --git a/copybook/parser.py b/copybook/parser.py
index 948a271..aa50338 100644
--- a/copybook/parser.py
+++ b/copybook/parser.py
@@ -19,7 +19,7 @@
 numeric_pic = Group(
     Optional(
         Suppress("S")("signed")
-        | ("-"+FollowedBy("9"))("signed")
+        | (one_of("+ -")+FollowedBy("9"))("signed")
     )
     + Optional(
         # bracket notation, e.g. 9(13)


Test patch:
diff --git a/tests/test_parse_string.py b/tests/test_parse_string.py
index 7f76c8f..ef327f5 100644
--- a/tests/test_parse_string.py
+++ b/tests/test_parse_string.py
@@ -146,3 +146,23 @@ def test_extended_char_pic():
     assert len(result)==4
     assert result[2].datatype=="str"
     assert result[2].get_total_length()==2
+
+def test_plus_sign_control_symbol():
+    test_str = """
+       01  WORK-BOOK.
+         10  AMOUNT2       PIC +9(4).99.
+    """
+    result = copybook.parse_string(test_str).flatten()
+    assert len(result)==2
+    assert result[1].datatype=="decimal"
+    assert result[1].get_total_length()==7
+
+def test_minus_sign_control_symbol():
+    test_str = """
+       01  WORK-BOOK.
+         10  AMOUNT2       PIC -9(4).99.
+    """
+    result = copybook.parse_string(test_str).flatten()
+    assert len(result)==2
+    assert result[1].datatype=="decimal"
+    assert result[1].get_total_length()==7
\ No newline at end of file