Repository: lark-parser/lark

Issue:
exception str() failed in `UnexpectedCharacters` because of 'PatternRE' has no attribute 'raw'
**Describe the bug**

Lark v1.1.2

The standalone parser generated with `python -m lark.tools.standalone` appears to have an issue with the `PatternRE`/`PatternStr` subclasses because when I get an `UnexpectedCharacters` error, it's exception formatting fails because of 

```
kraken.lang._generated_parser.UnexpectedCharactersTraceback (most recent call last):
  File ".venvs/3.9/lib/python3.9/site-packages/kraken/lang/_generated_parser.py", line 206, in __str__
    message += self._format_expected(self.allowed)
  File ".venvs/3.9/lib/python3.9/site-packages/kraken/lang/_generated_parser.py", line 143, in _format_expected
    expected = [d[t_name].user_repr() if t_name in d else t_name for t_name in expected]
  File ".venvs/3.9/lib/python3.9/site-packages/kraken/lang/_generated_parser.py", line 143, in <listcomp>
    expected = [d[t_name].user_repr() if t_name in d else t_name for t_name in expected]
  File ".venvs/3.9/lib/python3.9/site-packages/kraken/lang/_generated_parser.py", line 1187, in user_repr
    return self.pattern.raw or self.name
AttributeError: 'PatternRE' object has no attribute 'raw'
```

**To Reproduce**

* Take some Lark grammar
* Generate a standalone parser
* Feed it some input that results in an `UnexpectedCharacters` error

If it helps, I attached the standalone parser that was generated on my side:

[_generated_parser.py.zip](https://github.com/lark-parser/lark/files/8782534/_generated_parser.zip)



Discussion:

Patch:
diff --git a/lark/lexer.py b/lark/lexer.py
index 1f1bb75..4291f2d 100644
--- a/lark/lexer.py
+++ b/lark/lexer.py
@@ -63,7 +63,7 @@ class Pattern(Serialize, ABC):
 
 
 class PatternStr(Pattern):
-    __serialize_fields__ = 'value', 'flags'
+    __serialize_fields__ = 'value', 'flags', 'raw'
 
     type: ClassVar[str] = "str"
 
@@ -80,7 +80,7 @@ class PatternStr(Pattern):
 
 
 class PatternRE(Pattern):
-    __serialize_fields__ = 'value', 'flags', '_width'
+    __serialize_fields__ = 'value', 'flags', 'raw', '_width'
 
     type: ClassVar[str] = "re"
 


Test patch:
diff --git a/tests/test_cache.py b/tests/test_cache.py
index fd653bf..24e05bb 100644
--- a/tests/test_cache.py
+++ b/tests/test_cache.py
@@ -3,7 +3,7 @@ from __future__ import absolute_import
 import logging
 from unittest import TestCase, main, skipIf
 
-from lark import Lark, Tree, Transformer
+from lark import Lark, Tree, Transformer, UnexpectedInput
 from lark.lexer import Lexer, Token
 import lark.lark as lark_module
 
@@ -168,7 +168,26 @@ class TestCache(TestCase):
         self.assertCountEqual(cm.output, ["ERROR:lark:dummy message"])
 
 
+    def test_error_message(self):
+        # Checks that error message generation works
+        # This is especially important since sometimes the `str` method fails with
+        # the mysterious "<unprintable UnexpectedCharacters object>" or similar
+        g = r"""
+        start: add+
+        add: /\d+/ "+" /\d+/
+        %ignore " "
+        """
+        texts = ("1+", "+1", "", "1 1+1")
 
+        parser1 = Lark(g, parser='lalr', cache=True)
+        parser2 = Lark(g, parser='lalr', cache=True)
+        assert len(self.mock_fs.files) == 1
+        for text in texts:
+            with self.assertRaises((UnexpectedInput)) as cm1:
+                parser1.parse(text)
+            with self.assertRaises((UnexpectedInput)) as cm2:
+                parser2.parse(text)
+            self.assertEqual(str(cm1.exception), str(cm2.exception))
 
 if __name__ == '__main__':
     main()
diff --git a/tests/test_nearley/nearley b/tests/test_nearley/nearley
index 3268316..a46b374 160000
--- a/tests/test_nearley/nearley
+++ b/tests/test_nearley/nearley
@@ -1,1 +1,1 @@
-Subproject commit 326831689826cb1b9a4d21d1ce0d5db9278e9636
+Subproject commit a46b37471db486db0f6e1ce6a2934fb238346b44