Repository: lark-parser/lark

Issue:
Caching does not work with recursive pattern
**Describe the bug**

I tried to leverage caching to speed up the loading time of my grammar, but it didn't work, so I started to dig into the code and found that it can't load the pickled file

```shell
Traceback (most recent call last):
  ...
  File ".../lark/lark.py", line 326, in __init__
    raise e
  File ".../lark/lark.py", line 321, in __init__
    cached_parser_data = pickle.load(f)
TypeError: __new__() missing 1 required positional argument: 'name'
```

I could trace it down to an issue with `MAXREPEAT` and it happens, when a recursive pattern is used.

**To Reproduce**

```python
from lark import Lark


def main():
    json_grammar = r"""
    start: element*
    
    element: value
    
    ?value: "null"                      -> null
          | QUOTED_INTERPOLATION        -> string
    
    QUOTED_INTERPOLATION: /'(?R)'/
    
    %import common.NEWLINE
    %import common.WS_INLINE
    
    %ignore NEWLINE
    %ignore WS_INLINE
    """

    json_parser = Lark(json_grammar, start="start", parser="lalr", regex=True, cache=True)

    tree = json_parser.parse(
        """
        null
        """
    )
    print(tree.pretty())


if __name__ == "__main__":
    main()
```


Discussion:

Patch:
diff --git a/lark/utils.py b/lark/utils.py
index 77252b6..d7bab6f 100644
--- a/lark/utils.py
+++ b/lark/utils.py
@@ -137,9 +137,10 @@ def get_regexp_width(expr):
             # we manually test for the most important info (whether the empty string is matched)
             c = regex.compile(regexp_final)
             if c.match('') is None:
-                return 1, sre_constants.MAXREPEAT
+                # MAXREPEAT is a none pickable subclass of int, therefore needs to be converted to enable caching
+                return 1, int(sre_constants.MAXREPEAT)
             else:
-                return 0, sre_constants.MAXREPEAT
+                return 0, int(sre_constants.MAXREPEAT)
 
 ###}
 


Test patch:
diff --git a/tests/test_cache.py b/tests/test_cache.py
index dd67435..16a35bd 100644
--- a/tests/test_cache.py
+++ b/tests/test_cache.py
@@ -1,5 +1,6 @@
 from __future__ import absolute_import
 
+import logging
 from unittest import TestCase, main
 
 from lark import Lark, Tree, Transformer
@@ -140,6 +141,24 @@ class TestCache(TestCase):
         res = parser.parse("ab")
         self.assertEqual(res, Tree('startab', [Tree('expr', ['a', 'b'])]))
 
+    def test_recursive_pattern(self):
+        g = """
+        start: recursive+
+        recursive: /\w{3}\d{3}(?R)?/
+        """
+
+        assert len(self.mock_fs.files) == 0
+        Lark(g, parser="lalr", regex=True, cache=True)
+        assert len(self.mock_fs.files) == 1
+
+        with self.assertLogs("lark", level="ERROR") as cm:
+            Lark(g, parser='lalr', regex=True, cache=True)
+            assert len(self.mock_fs.files) == 1
+            # need to add an error log, because 'self.assertNoLogs' was added in Python 3.10
+            logging.getLogger('lark').error("dummy message")
+        # should only have the dummy log
+        self.assertCountEqual(cm.output, ["ERROR:lark:dummy message"])
+