Repository: idaholab/MontePy

Issue:
Parsing of transformations on FILL keywords appears to be failing
**Describe the bug**
Hello again, thanks for the the support you have been giving us lately. I'm back with another issue.
Montepy appears to fail parsing a cell that has a FILL card modified by a full transformation (see example).

**To Reproduce**

``` python
import montepy

# Read the file
problem = montepy.read_input("extracted_cell.i")
```
```python
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\mcnp_object.py:50, in MCNP_Object.__init__(self, input, parser)
     [49](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:49)     pass
---> [50](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:50) self._tree = parser.parse(input.tokenize(), input)
     [51](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:51) self._input = input

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\input_parser\parser_base.py:156, in MCNP_Parser.parse(self, token_generator, input)
    [155](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:155) # change to using `gen_wrapper()` to debug
--> [156](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:156) tree = super().parse(token_generator)
    [157](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:157) # treat any previous errors as being fatal even if it recovered.

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\sly\yacc.py:2138, in Parser.parse(self, tokens)
   [2137](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/sly/yacc.py:2137) try:       
-> [2138](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/sly/yacc.py:2138)     value = p.func(self, pslice)
   [2139](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/sly/yacc.py:2139) except AttributeError as e:

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\input_parser\parser_base.py:182, in MCNP_Parser.identifier_phrase(self, p)
    [176](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:176) """
    [177](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:177) A non-zero number with or without padding converted to int.
    [178](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:178) 
    [179](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:179) :returns: an int ValueNode
    [180](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:180) :rtype: ValueNode
    [181](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:181) """
--> [182](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:182) return self._flush_phrase(p, int)

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\input_parser\parser_base.py:302, in MCNP_Parser._flush_phrase(self, p, token_type)
    [301](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:301)     padding = None
--> [302](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/parser_base.py:302) return syntax_node.ValueNode(p[0], token_type, padding)

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\input_parser\syntax_node.py:652, in ValueNode.__init__(self, token, token_type, padding, never_pad)
    [651](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/syntax_node.py:651) elif token_type == int:
--> [652](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/syntax_node.py:652)     self._value = int(token)
    [653](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/syntax_node.py:653) else:

ValueError: invalid literal for int() with base 10: '30.000'

During handling of the above exception, another exception occurred:

MalformedInputError                       Traceback (most recent call last)
Cell In[10], [line 4](vscode-notebook-cell:?execution_count=10&line=4)
      [1](vscode-notebook-cell:?execution_count=10&line=1) import montepy
      [3](vscode-notebook-cell:?execution_count=10&line=3) # Read the file
----> [4](vscode-notebook-cell:?execution_count=10&line=4) problem = montepy.read_input("extracted_cell.i")

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\input_parser\input_reader.py:29, in read_input(input_file, mcnp_version, replace)
     [27](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/input_reader.py:27) problem = mcnp_problem.MCNP_Problem(input_file)
     [28](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/input_reader.py:28) problem.mcnp_version = mcnp_version
---> [29](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/input_reader.py:29) problem.parse_input(replace=replace)
     [30](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/input_parser/input_reader.py:30) return problem

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\mcnp_problem.py:286, in MCNP_Problem.parse_input(self, check_input, replace)
    [284](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:284)         continue
    [285](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:285)     else:
--> [286](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:286)         raise e
    [287](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:287) if isinstance(obj, Material):
    [288](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:288)     self._materials.append(obj)

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\mcnp_problem.py:271, in MCNP_Problem.parse_input(self, check_input, replace)
    [269](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:269) if len(input.input_lines) > 0:
    [270](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:270)     try:
--> [271](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:271)         obj = obj_parser(input)
    [272](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:272)         obj.link_to_problem(self)
    [273](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_problem.py:273)         obj_container.append(obj)

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\cell.py:88, in Cell.__init__(self, input)
     [86](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/cell.py:86) self._complements = Cells()
     [87](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/cell.py:87) self._number = self._generate_default_node(int, -1)
---> [88](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/cell.py:88) super().__init__(input, self._parser)
     [89](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/cell.py:89) if not input:
     [90](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/cell.py:90)     self._generate_default_tree()

File c:\ProgramData\Anaconda3\envs\montepy\lib\site-packages\montepy\mcnp_object.py:53, in MCNP_Object.__init__(self, input, parser)
     [51](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:51)     self._input = input
     [52](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:52) except ValueError as e:
---> [53](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:53)     raise MalformedInputError(
     [54](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:54)         input, f"Error parsing object of type: {type(self)}: {e.args[0]}"
     [55](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:55)     )
     [56](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:56) if self._tree is None:
     [57](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:57)     raise ParsingError(
     [58](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:58)         input,
     [59](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:59)         "",
     [60](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:60)         parser.log.clear_queue(),
     [61](file:///C:/ProgramData/Anaconda3/envs/montepy/lib/site-packages/montepy/mcnp_object.py:61)     )

MalformedInputError: 
: extracted_cell.i, line 2
Error parsing object of type: <class 'montepy.cell.Cell'>: invalid literal for int() with base 10: '30.000'

the full input:
1    0  3 -2
         IMP:N=1.000000  IMP:P=1.000000
         *FILL=1  ( 0.000        0.000  0.000
                    30.000      120.000 90.000
                    60.000       30.000 90.000
                    90.000       90.000  0.000)
```

**MCNP input file snippet**

```
A TITLE
1    0  3 -2 
         IMP:N=1.000000  IMP:P=1.000000
         *FILL=1  ( 0.000        0.000  0.000
                    30.000      120.000 90.000
                    60.000       30.000 90.000
                    90.000       90.000  0.000)
2    0   1  U=1
          IMP:N=1.000000  IMP:P=1.000000

1 PZ 0
2 PZ 4
3 PZ -4 

MODE N
NPS 1
```

**Version**

 - Version 0.3.3.dev11+g55d0c4d




Discussion:

Patch:
diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst
index d6467cb1..6d6a29d8 100644
--- a/doc/source/changelog.rst
+++ b/doc/source/changelog.rst
@@ -9,6 +9,7 @@ MontePy Changelog
 * Fixed bug with material compositions not being updated when written to file (:issue:`470`).
 * Fixed bug with appending and renumbering numbered objects from other MCNP problems (:issue:`466`).
 * Fixed bug with dynamic typing and the parsers that only appear in edge cases (:issue:`461`).
+* Fixed parser bug with having spaces in the start of the transform input for the fill of a cell (:pull:`479`).
 * Fixed bug with trying to get trailing comments from non-existant parts of the syntax tree (:pull:`480`).
 
 **Code Quality**
diff --git a/montepy/input_parser/cell_parser.py b/montepy/input_parser/cell_parser.py
index a519fe60..d1d6bf5c 100644
--- a/montepy/input_parser/cell_parser.py
+++ b/montepy/input_parser/cell_parser.py
@@ -181,11 +181,15 @@ class CellParser(MCNP_Parser):
     # support for fill card weirdness
     @_(
         'number_sequence "(" number_sequence ")"',
+        'number_sequence "(" padding number_sequence ")"',
         'number_sequence "(" number_sequence ")" padding',
+        'number_sequence "(" padding number_sequence ")" padding',
         'number_sequence ":" numerical_phrase',
+        'number_sequence ":" padding numerical_phrase',
         # support for TRCL syntax
         '"(" number_sequence ")"',
         '"(" number_sequence ")" padding',
+        '"(" padding number_sequence ")" padding',
     )
     def number_sequence(self, p):
         if isinstance(p[0], str):
diff --git a/montepy/input_parser/parser_base.py b/montepy/input_parser/parser_base.py
index 75846269..25413f55 100644
--- a/montepy/input_parser/parser_base.py
+++ b/montepy/input_parser/parser_base.py
@@ -548,8 +548,9 @@ class MCNP_Parser(Parser, metaclass=MetaBuilder):
 
         debugfile = 'parser.out'
         """
-        print("********* New Parsing Error ************ ")
+        print(f"********* New Parsing Error from: {type(self)} ************ ")
         print(f"Token: {token}")
         print(f"State: {self.state}, statestack: {self.statestack}")
         print(f"Symstack: {self.symstack}")
+        print(f"Log length: {len(self.log)}")
         print()


Test patch:
diff --git a/tests/test_edge_cases.py b/tests/test_edge_cases.py
index 2cb9d4fe..b92ee3d5 100644
--- a/tests/test_edge_cases.py
+++ b/tests/test_edge_cases.py
@@ -171,6 +171,14 @@ class EdgeCaseTests(TestCase):
             "      )",
             "      IMP:N=1.000000 IMP:P=1.000000",
         ],
+        [
+            "1    0  3 -2",
+            "    IMP:N=1.000000  IMP:P=1.000000",
+            "    *FILL=1  ( 0.000        0.000  0.000",
+            "           30.000      120.000 90.000",
+            "           60.000       30.000 90.000",
+            "           90.000       90.000  0.000)",
+        ],
     ],
 )
 def test_complex_cell_parsing(lines):