Repository: Unidata/MetPy

Issue:
Clean up CodeQL config
Right now it's still scanning the generated `metpy_parser.py` for some reason, which is generating a ton of issues we aren't going to fix.

Not sure why, we seem to be setting things correctly [according to the docs](https://docs.github.com/en/code-security/secure-coding/configuring-code-scanning#running-additional-queries).

Discussion:
lgtm-com[bot]: This pull request **fixes 2 alerts** when merging d6ddac6313857c14ab68a5e283b1fa9b68bd7f15 into d3f8a83d59e03b7120b84dd18def8d3915fd3a70 - [view on LGTM.com](https://lgtm.com/projects/g/Unidata/MetPy/rev/pr-f62b24cf679402b3987a5d42dda26461c64f32fa)

**fixed alerts:**

* 1 for Module is imported with &#39;import&#39; and &#39;import from&#39;
* 1 for Non\-standard exception raised in special method
lgtm-com[bot]: This pull request **fixes 2 alerts** when merging 65337071c1850f4e81afb553ba55fe5269e8e179 into d3f8a83d59e03b7120b84dd18def8d3915fd3a70 - [view on LGTM.com](https://lgtm.com/projects/g/Unidata/MetPy/rev/pr-7930c5aa94ee4e115f52b99a80a30cf43f8fedc7)

**fixed alerts:**

* 1 for Module is imported with &#39;import&#39; and &#39;import from&#39;
* 1 for Non\-standard exception raised in special method

Patch:
diff --git a/.codeclimate.yml b/.codeclimate.yml
index 0cb746cd60..680d017144 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -40,8 +40,7 @@ plugins:
 
 exclude_patterns:
 - "src/metpy/io/_nexrad_msgs/msg*.py"
-- "src/metpy/io/metar_parse.peg"
-- "src/metpy/io/metar_parser.py"
+- "src/metpy/io/_metar_parser/*"
 - "docs/**/*"
 - "staticdata/**/*"
 - "tests/*/baseline/*"
diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml
index 6e53bfa7c0..40e7750dd0 100644
--- a/.github/codeql/codeql-config.yml
+++ b/.github/codeql/codeql-config.yml
@@ -4,6 +4,6 @@ queries:
   - uses: security-and-quality
 
 paths-ignore:
-  - src/metpy/io/metar_parser.py
+  - src/metpy/io/_metar_parser
   - tutorials
   - examples
diff --git a/.github/workflows/code-analysis.yml b/.github/workflows/code-analysis.yml
index dc7f3830b7..e49992a967 100644
--- a/.github/workflows/code-analysis.yml
+++ b/.github/workflows/code-analysis.yml
@@ -6,6 +6,11 @@ on:
   pull_request:
     # The branches below must be a subset of the branches above
     branches: [main]
+    paths:
+      - '**.py'
+      - '.github/codeql/**'
+      - '.github/workflows/code-analysis.yml'
+
   schedule:
     - cron: '0 8 * * 6'
 
diff --git a/.lgtm.yml b/.lgtm.yml
index 0e1f391053..52615ab668 100644
--- a/.lgtm.yml
+++ b/.lgtm.yml
@@ -1,6 +1,6 @@
 path_classifiers:
     generated:
-        - src/metpy/io/metar_parser.py
+        - src/metpy/io/_metar_parser/metar_parser.py
     library:
         - src/metpy/deprecation.py
     test:
diff --git a/setup.cfg b/setup.cfg
index 642a869c1b..f9a4d9ff56 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -79,7 +79,7 @@ multiline-quotes = double
 rst-roles = class, data, doc, func, meth, mod
 rst-directives = plot, versionchanged
 docstring-convention = numpy
-exclude = docs build src/metpy/io/metar_parser.py
+exclude = docs build src/metpy/io/_metar_parser/metar_parser.py
 select = A B C D E F G H I J K L M N O P Q R S T U V W X Y Z B902
 ignore = F405 W503 RST902 SIM106
 per-file-ignores = examples/*.py: D MPY001 T003 T001
diff --git a/src/metpy/io/metar_parse.peg b/src/metpy/io/_metar_parser/metar_parser.peg
similarity index 100%
rename from src/metpy/io/metar_parse.peg
rename to src/metpy/io/_metar_parser/metar_parser.peg
diff --git a/src/metpy/io/metar_parser.py b/src/metpy/io/_metar_parser/metar_parser.py
similarity index 84%
rename from src/metpy/io/metar_parser.py
rename to src/metpy/io/_metar_parser/metar_parser.py
index 6a09f28762..469d4b1714 100644
--- a/src/metpy/io/metar_parser.py
+++ b/src/metpy/io/_metar_parser/metar_parser.py
@@ -1,12 +1,15 @@
+# This file was generated from metar_parser.peg
+# See http://canopy.jcoglan.com/ for documentation.
+
 from collections import defaultdict
 import re
 
 
 class TreeNode:
-    def __init__(self, text, offset, elements=None):
+    def __init__(self, text, offset, elements):
         self.text = text
         self.offset = offset
-        self.elements = elements or []
+        self.elements = elements
 
     def __iter__(self):
         yield from self.elements
@@ -71,12 +74,14 @@ class TreeNode8(TreeNode):
     def __init__(self, text, offset, elements):
         super().__init__(text, offset, elements)
         self.sep = elements[0]
+        self.wx = elements[1]
 
 
 class TreeNode9(TreeNode):
     def __init__(self, text, offset, elements):
         super().__init__(text, offset, elements)
         self.sep = elements[0]
+        self.cover = elements[1]
 
 
 class TreeNode10(TreeNode):
@@ -129,7 +134,7 @@ class Grammar:
     REGEX_32 = re.compile('^[\\d]')
     REGEX_33 = re.compile('^[\\d]')
     REGEX_34 = re.compile('^[\\d]')
-    REGEX_35 = re.compile('^["M" \\/ "P"]')
+    REGEX_35 = re.compile('^["M" / "P"]')
     REGEX_36 = re.compile('^[\\d]')
     REGEX_37 = re.compile('^[\\d]')
     REGEX_38 = re.compile('^[\\d]')
@@ -143,7 +148,7 @@ class Grammar:
     REGEX_46 = re.compile('^[M]')
     REGEX_47 = re.compile('^[\\d]')
     REGEX_48 = re.compile('^[\\d]')
-    REGEX_49 = re.compile('^["Q" \\/ "A"]')
+    REGEX_49 = re.compile('^["Q" / "A"]')
     REGEX_50 = re.compile('^[\\d]')
     REGEX_51 = re.compile('^[\\d]')
     REGEX_52 = re.compile('^[\\d]')
@@ -265,11 +270,11 @@ class Grammar:
         address1 = FAILURE
         index2 = self._offset
         index3 = self._offset
-        chunk0 = None
-        if self._offset < self._input_size:
-            chunk0 = self._input[self._offset:self._offset + 5]
+        chunk0, max0 = None, self._offset + 5
+        if max0 <= self._input_size:
+            chunk0 = self._input[self._offset:max0]
         if chunk0 == 'METAR':
-            address1 = TreeNode(self._input[self._offset:self._offset + 5], self._offset)
+            address1 = TreeNode(self._input[self._offset:self._offset + 5], self._offset, [])
             self._offset = self._offset + 5
         else:
             address1 = FAILURE
@@ -280,11 +285,11 @@ class Grammar:
                 self._expected.append('"METAR"')
         if address1 is FAILURE:
             self._offset = index3
-            chunk1 = None
-            if self._offset < self._input_size:
-                chunk1 = self._input[self._offset:self._offset + 5]
+            chunk1, max1 = None, self._offset + 5
+            if max1 <= self._input_size:
+                chunk1 = self._input[self._offset:max1]
             if chunk1 == 'SPECI':
-                address1 = TreeNode(self._input[self._offset:self._offset + 5], self._offset)
+                address1 = TreeNode(self._input[self._offset:self._offset + 5], self._offset, [])
                 self._offset = self._offset + 5
             else:
                 address1 = FAILURE
@@ -296,18 +301,18 @@ class Grammar:
             if address1 is FAILURE:
                 self._offset = index3
         if address1 is FAILURE:
-            address1 = TreeNode(self._input[index2:index2], index2)
+            address1 = TreeNode(self._input[index2:index2], index2, [])
             self._offset = index2
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
             index4 = self._offset
             index5 = self._offset
-            chunk2 = None
-            if self._offset < self._input_size:
-                chunk2 = self._input[self._offset:self._offset + 5]
+            chunk2, max2 = None, self._offset + 5
+            if max2 <= self._input_size:
+                chunk2 = self._input[self._offset:max2]
             if chunk2 == ' AUTO':
-                address2 = TreeNode(self._input[self._offset:self._offset + 5], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 5], self._offset, [])
                 self._offset = self._offset + 5
             else:
                 address2 = FAILURE
@@ -318,11 +323,11 @@ class Grammar:
                     self._expected.append('" AUTO"')
             if address2 is FAILURE:
                 self._offset = index5
-                chunk3 = None
-                if self._offset < self._input_size:
-                    chunk3 = self._input[self._offset:self._offset + 4]
+                chunk3, max3 = None, self._offset + 4
+                if max3 <= self._input_size:
+                    chunk3 = self._input[self._offset:max3]
                 if chunk3 == ' COR':
-                    address2 = TreeNode(self._input[self._offset:self._offset + 4], self._offset)
+                    address2 = TreeNode(self._input[self._offset:self._offset + 4], self._offset, [])
                     self._offset = self._offset + 4
                 else:
                     address2 = FAILURE
@@ -334,7 +339,7 @@ class Grammar:
                 if address2 is FAILURE:
                     self._offset = index5
             if address2 is FAILURE:
-                address2 = TreeNode(self._input[index4:index4], index4)
+                address2 = TreeNode(self._input[index4:index4], index4, [])
                 self._offset = index4
             if address2 is not FAILURE:
                 elements0.append(address2)
@@ -360,11 +365,11 @@ class Grammar:
             return cached[0]
         remaining0, index1, elements0, address1 = 1, self._offset, [], True
         while address1 is not FAILURE:
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 1]
+            chunk0, max0 = None, self._offset + 1
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 == ' ':
-                address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address1 = FAILURE
@@ -395,16 +400,16 @@ class Grammar:
         index2 = self._offset
         address1 = self._read_sep()
         if address1 is FAILURE:
-            address1 = TreeNode(self._input[index2:index2], index2)
+            address1 = TreeNode(self._input[index2:index2], index2, [])
             self._offset = index2
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 1]
+            chunk0, max0 = None, self._offset + 1
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 is not None and Grammar.REGEX_1.search(chunk0):
-                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address2 = FAILURE
@@ -416,11 +421,11 @@ class Grammar:
             if address2 is not FAILURE:
                 elements0.append(address2)
                 address3 = FAILURE
-                chunk1 = None
-                if self._offset < self._input_size:
-                    chunk1 = self._input[self._offset:self._offset + 1]
+                chunk1, max1 = None, self._offset + 1
+                if max1 <= self._input_size:
+                    chunk1 = self._input[self._offset:max1]
                 if chunk1 is not None and Grammar.REGEX_2.search(chunk1):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -432,11 +437,11 @@ class Grammar:
                 if address3 is not FAILURE:
                     elements0.append(address3)
                     address4 = FAILURE
-                    chunk2 = None
-                    if self._offset < self._input_size:
-                        chunk2 = self._input[self._offset:self._offset + 1]
+                    chunk2, max2 = None, self._offset + 1
+                    if max2 <= self._input_size:
+                        chunk2 = self._input[self._offset:max2]
                     if chunk2 is not None and Grammar.REGEX_3.search(chunk2):
-                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                         self._offset = self._offset + 1
                     else:
                         address4 = FAILURE
@@ -448,11 +453,11 @@ class Grammar:
                     if address4 is not FAILURE:
                         elements0.append(address4)
                         address5 = FAILURE
-                        chunk3 = None
-                        if self._offset < self._input_size:
-                            chunk3 = self._input[self._offset:self._offset + 1]
+                        chunk3, max3 = None, self._offset + 1
+                        if max3 <= self._input_size:
+                            chunk3 = self._input[self._offset:max3]
                         if chunk3 is not None and Grammar.REGEX_4.search(chunk3):
-                            address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                            address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                             self._offset = self._offset + 1
                         else:
                             address5 = FAILURE
@@ -500,11 +505,11 @@ class Grammar:
             address2 = FAILURE
             remaining0, index2, elements1, address3 = 1, self._offset, [], True
             while address3 is not FAILURE:
-                chunk0 = None
-                if self._offset < self._input_size:
-                    chunk0 = self._input[self._offset:self._offset + 1]
+                chunk0, max0 = None, self._offset + 1
+                if max0 <= self._input_size:
+                    chunk0 = self._input[self._offset:max0]
                 if chunk0 is not None and Grammar.REGEX_5.search(chunk0):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -524,11 +529,11 @@ class Grammar:
             if address2 is not FAILURE:
                 elements0.append(address2)
                 address4 = FAILURE
-                chunk1 = None
-                if self._offset < self._input_size:
-                    chunk1 = self._input[self._offset:self._offset + 1]
+                chunk1, max1 = None, self._offset + 1
+                if max1 <= self._input_size:
+                    chunk1 = self._input[self._offset:max1]
                 if chunk1 == 'Z':
-                    address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address4 = FAILURE
@@ -570,11 +575,11 @@ class Grammar:
             address2 = FAILURE
             index2 = self._offset
             index3 = self._offset
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 4]
+            chunk0, max0 = None, self._offset + 4
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 == 'AUTO':
-                address2 = TreeNode(self._input[self._offset:self._offset + 4], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 4], self._offset, [])
                 self._offset = self._offset + 4
             else:
                 address2 = FAILURE
@@ -585,11 +590,11 @@ class Grammar:
                     self._expected.append('"AUTO"')
             if address2 is FAILURE:
                 self._offset = index3
-                chunk1 = None
-                if self._offset < self._input_size:
-                    chunk1 = self._input[self._offset:self._offset + 3]
+                chunk1, max1 = None, self._offset + 3
+                if max1 <= self._input_size:
+                    chunk1 = self._input[self._offset:max1]
                 if chunk1 == 'COR':
-                    address2 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                    address2 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                     self._offset = self._offset + 3
                 else:
                     address2 = FAILURE
@@ -601,7 +606,7 @@ class Grammar:
                 if address2 is FAILURE:
                     self._offset = index3
             if address2 is FAILURE:
-                address2 = TreeNode(self._input[index2:index2], index2)
+                address2 = TreeNode(self._input[index2:index2], index2, [])
                 self._offset = index2
             if address2 is not FAILURE:
                 elements0.append(address2)
@@ -631,7 +636,7 @@ class Grammar:
         index3 = self._offset
         address1 = self._read_sep()
         if address1 is FAILURE:
-            address1 = TreeNode(self._input[index3:index3], index3)
+            address1 = TreeNode(self._input[index3:index3], index3, [])
             self._offset = index3
         if address1 is not FAILURE:
             elements0.append(address1)
@@ -647,17 +652,17 @@ class Grammar:
                     index4 = self._offset
                     address4 = self._read_gust()
                     if address4 is FAILURE:
-                        address4 = TreeNode(self._input[index4:index4], index4)
+                        address4 = TreeNode(self._input[index4:index4], index4, [])
                         self._offset = index4
                     if address4 is not FAILURE:
                         elements0.append(address4)
                         address5 = FAILURE
                         index5 = self._offset
-                        chunk0 = None
-                        if self._offset < self._input_size:
-                            chunk0 = self._input[self._offset:self._offset + 2]
+                        chunk0, max0 = None, self._offset + 2
+                        if max0 <= self._input_size:
+                            chunk0 = self._input[self._offset:max0]
                         if chunk0 == 'KT':
-                            address5 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                            address5 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                             self._offset = self._offset + 2
                         else:
                             address5 = FAILURE
@@ -668,11 +673,11 @@ class Grammar:
                                 self._expected.append('"KT"')
                         if address5 is FAILURE:
                             self._offset = index5
-                            chunk1 = None
-                            if self._offset < self._input_size:
-                                chunk1 = self._input[self._offset:self._offset + 3]
+                            chunk1, max1 = None, self._offset + 3
+                            if max1 <= self._input_size:
+                                chunk1 = self._input[self._offset:max1]
                             if chunk1 == 'MPS':
-                                address5 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                                address5 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                                 self._offset = self._offset + 3
                             else:
                                 address5 = FAILURE
@@ -689,7 +694,7 @@ class Grammar:
                             index6 = self._offset
                             address6 = self._read_varwind()
                             if address6 is FAILURE:
-                                address6 = TreeNode(self._input[index6:index6], index6)
+                                address6 = TreeNode(self._input[index6:index6], index6, [])
                                 self._offset = index6
                             if address6 is not FAILURE:
                                 elements0.append(address6)
@@ -717,7 +722,7 @@ class Grammar:
             address0 = TreeNode4(self._input[index2:self._offset], index2, elements0)
             self._offset = self._offset
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['wind'][index0] = (address0, self._offset)
         return address0
@@ -732,11 +737,11 @@ class Grammar:
         index2 = self._offset
         index3, elements0 = self._offset, []
         address1 = FAILURE
-        chunk0 = None
-        if self._offset < self._input_size:
-            chunk0 = self._input[self._offset:self._offset + 1]
+        chunk0, max0 = None, self._offset + 1
+        if max0 <= self._input_size:
+            chunk0 = self._input[self._offset:max0]
         if chunk0 is not None and Grammar.REGEX_6.search(chunk0):
-            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
             self._offset = self._offset + 1
         else:
             address1 = FAILURE
@@ -748,11 +753,11 @@ class Grammar:
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
-            chunk1 = None
-            if self._offset < self._input_size:
-                chunk1 = self._input[self._offset:self._offset + 1]
+            chunk1, max1 = None, self._offset + 1
+            if max1 <= self._input_size:
+                chunk1 = self._input[self._offset:max1]
             if chunk1 is not None and Grammar.REGEX_7.search(chunk1):
-                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address2 = FAILURE
@@ -764,11 +769,11 @@ class Grammar:
             if address2 is not FAILURE:
                 elements0.append(address2)
                 address3 = FAILURE
-                chunk2 = None
-                if self._offset < self._input_size:
-                    chunk2 = self._input[self._offset:self._offset + 1]
+                chunk2, max2 = None, self._offset + 1
+                if max2 <= self._input_size:
+                    chunk2 = self._input[self._offset:max2]
                 if chunk2 is not None and Grammar.REGEX_8.search(chunk2):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -795,11 +800,11 @@ class Grammar:
             self._offset = self._offset
         if address0 is FAILURE:
             self._offset = index2
-            chunk3 = None
-            if self._offset < self._input_size:
-                chunk3 = self._input[self._offset:self._offset + 3]
+            chunk3, max3 = None, self._offset + 3
+            if max3 <= self._input_size:
+                chunk3 = self._input[self._offset:max3]
             if chunk3 == 'VAR':
-                address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                 self._offset = self._offset + 3
             else:
                 address0 = FAILURE
@@ -810,11 +815,11 @@ class Grammar:
                     self._expected.append('\'VAR\'')
             if address0 is FAILURE:
                 self._offset = index2
-                chunk4 = None
-                if self._offset < self._input_size:
-                    chunk4 = self._input[self._offset:self._offset + 3]
+                chunk4, max4 = None, self._offset + 3
+                if max4 <= self._input_size:
+                    chunk4 = self._input[self._offset:max4]
                 if chunk4 == 'VRB':
-                    address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                    address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                     self._offset = self._offset + 3
                 else:
                     address0 = FAILURE
@@ -825,11 +830,11 @@ class Grammar:
                         self._expected.append('\'VRB\'')
                 if address0 is FAILURE:
                     self._offset = index2
-                    chunk5 = None
-                    if self._offset < self._input_size:
-                        chunk5 = self._input[self._offset:self._offset + 3]
+                    chunk5, max5 = None, self._offset + 3
+                    if max5 <= self._input_size:
+                        chunk5 = self._input[self._offset:max5]
                     if chunk5 == '///':
-                        address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                        address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                         self._offset = self._offset + 3
                     else:
                         address0 = FAILURE
@@ -841,7 +846,7 @@ class Grammar:
                     if address0 is FAILURE:
                         self._offset = index2
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['wind_dir'][index0] = (address0, self._offset)
         return address0
@@ -856,11 +861,11 @@ class Grammar:
         index2 = self._offset
         index3, elements0 = self._offset, []
         address1 = FAILURE
-        chunk0 = None
-        if self._offset < self._input_size:
-            chunk0 = self._input[self._offset:self._offset + 1]
+        chunk0, max0 = None, self._offset + 1
+        if max0 <= self._input_size:
+            chunk0 = self._input[self._offset:max0]
         if chunk0 is not None and Grammar.REGEX_9.search(chunk0):
-            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
             self._offset = self._offset + 1
         else:
             address1 = FAILURE
@@ -872,11 +877,11 @@ class Grammar:
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
-            chunk1 = None
-            if self._offset < self._input_size:
-                chunk1 = self._input[self._offset:self._offset + 1]
+            chunk1, max1 = None, self._offset + 1
+            if max1 <= self._input_size:
+                chunk1 = self._input[self._offset:max1]
             if chunk1 is not None and Grammar.REGEX_10.search(chunk1):
-                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address2 = FAILURE
@@ -889,11 +894,11 @@ class Grammar:
                 elements0.append(address2)
                 address3 = FAILURE
                 index4 = self._offset
-                chunk2 = None
-                if self._offset < self._input_size:
-                    chunk2 = self._input[self._offset:self._offset + 1]
+                chunk2, max2 = None, self._offset + 1
+                if max2 <= self._input_size:
+                    chunk2 = self._input[self._offset:max2]
                 if chunk2 is not None and Grammar.REGEX_11.search(chunk2):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -903,7 +908,7 @@ class Grammar:
                     if self._offset == self._failure:
                         self._expected.append('[\\d]')
                 if address3 is FAILURE:
-                    address3 = TreeNode(self._input[index4:index4], index4)
+                    address3 = TreeNode(self._input[index4:index4], index4, [])
                     self._offset = index4
                 if address3 is not FAILURE:
                     elements0.append(address3)
@@ -923,11 +928,11 @@ class Grammar:
             self._offset = self._offset
         if address0 is FAILURE:
             self._offset = index2
-            chunk3 = None
-            if self._offset < self._input_size:
-                chunk3 = self._input[self._offset:self._offset + 2]
+            chunk3, max3 = None, self._offset + 2
+            if max3 <= self._input_size:
+                chunk3 = self._input[self._offset:max3]
             if chunk3 == '//':
-                address0 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                address0 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                 self._offset = self._offset + 2
             else:
                 address0 = FAILURE
@@ -939,7 +944,7 @@ class Grammar:
             if address0 is FAILURE:
                 self._offset = index2
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['wind_spd'][index0] = (address0, self._offset)
         return address0
@@ -952,11 +957,11 @@ class Grammar:
             return cached[0]
         index1, elements0 = self._offset, []
         address1 = FAILURE
-        chunk0 = None
-        if self._offset < self._input_size:
-            chunk0 = self._input[self._offset:self._offset + 1]
+        chunk0, max0 = None, self._offset + 1
+        if max0 <= self._input_size:
+            chunk0 = self._input[self._offset:max0]
         if chunk0 == 'G':
-            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
             self._offset = self._offset + 1
         else:
             address1 = FAILURE
@@ -970,11 +975,11 @@ class Grammar:
             address2 = FAILURE
             remaining0, index2, elements1, address3 = 1, self._offset, [], True
             while address3 is not FAILURE:
-                chunk1 = None
-                if self._offset < self._input_size:
-                    chunk1 = self._input[self._offset:self._offset + 1]
+                chunk1, max1 = None, self._offset + 1
+                if max1 <= self._input_size:
+                    chunk1 = self._input[self._offset:max1]
                 if chunk1 is not None and Grammar.REGEX_12.search(chunk1):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -1019,11 +1024,11 @@ class Grammar:
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 1]
+            chunk0, max0 = None, self._offset + 1
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 is not None and Grammar.REGEX_13.search(chunk0):
-                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address2 = FAILURE
@@ -1035,11 +1040,11 @@ class Grammar:
             if address2 is not FAILURE:
                 elements0.append(address2)
                 address3 = FAILURE
-                chunk1 = None
-                if self._offset < self._input_size:
-                    chunk1 = self._input[self._offset:self._offset + 1]
+                chunk1, max1 = None, self._offset + 1
+                if max1 <= self._input_size:
+                    chunk1 = self._input[self._offset:max1]
                 if chunk1 is not None and Grammar.REGEX_14.search(chunk1):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -1051,11 +1056,11 @@ class Grammar:
                 if address3 is not FAILURE:
                     elements0.append(address3)
                     address4 = FAILURE
-                    chunk2 = None
-                    if self._offset < self._input_size:
-                        chunk2 = self._input[self._offset:self._offset + 1]
+                    chunk2, max2 = None, self._offset + 1
+                    if max2 <= self._input_size:
+                        chunk2 = self._input[self._offset:max2]
                     if chunk2 is not None and Grammar.REGEX_15.search(chunk2):
-                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                         self._offset = self._offset + 1
                     else:
                         address4 = FAILURE
@@ -1067,11 +1072,11 @@ class Grammar:
                     if address4 is not FAILURE:
                         elements0.append(address4)
                         address5 = FAILURE
-                        chunk3 = None
-                        if self._offset < self._input_size:
-                            chunk3 = self._input[self._offset:self._offset + 1]
+                        chunk3, max3 = None, self._offset + 1
+                        if max3 <= self._input_size:
+                            chunk3 = self._input[self._offset:max3]
                         if chunk3 == 'V':
-                            address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                            address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                             self._offset = self._offset + 1
                         else:
                             address5 = FAILURE
@@ -1083,11 +1088,11 @@ class Grammar:
                         if address5 is not FAILURE:
                             elements0.append(address5)
                             address6 = FAILURE
-                            chunk4 = None
-                            if self._offset < self._input_size:
-                                chunk4 = self._input[self._offset:self._offset + 1]
+                            chunk4, max4 = None, self._offset + 1
+                            if max4 <= self._input_size:
+                                chunk4 = self._input[self._offset:max4]
                             if chunk4 is not None and Grammar.REGEX_16.search(chunk4):
-                                address6 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                address6 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                 self._offset = self._offset + 1
                             else:
                                 address6 = FAILURE
@@ -1099,11 +1104,11 @@ class Grammar:
                             if address6 is not FAILURE:
                                 elements0.append(address6)
                                 address7 = FAILURE
-                                chunk5 = None
-                                if self._offset < self._input_size:
-                                    chunk5 = self._input[self._offset:self._offset + 1]
+                                chunk5, max5 = None, self._offset + 1
+                                if max5 <= self._input_size:
+                                    chunk5 = self._input[self._offset:max5]
                                 if chunk5 is not None and Grammar.REGEX_17.search(chunk5):
-                                    address7 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                    address7 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                     self._offset = self._offset + 1
                                 else:
                                     address7 = FAILURE
@@ -1115,11 +1120,11 @@ class Grammar:
                                 if address7 is not FAILURE:
                                     elements0.append(address7)
                                     address8 = FAILURE
-                                    chunk6 = None
-                                    if self._offset < self._input_size:
-                                        chunk6 = self._input[self._offset:self._offset + 1]
+                                    chunk6, max6 = None, self._offset + 1
+                                    if max6 <= self._input_size:
+                                        chunk6 = self._input[self._offset:max6]
                                     if chunk6 is not None and Grammar.REGEX_18.search(chunk6):
-                                        address8 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                        address8 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                         self._offset = self._offset + 1
                                     else:
                                         address8 = FAILURE
@@ -1178,11 +1183,11 @@ class Grammar:
             index3 = self._offset
             index4, elements1 = self._offset, []
             address3 = FAILURE
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 1]
+            chunk0, max0 = None, self._offset + 1
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 is not None and Grammar.REGEX_19.search(chunk0):
-                address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address3 = FAILURE
@@ -1194,11 +1199,11 @@ class Grammar:
             if address3 is not FAILURE:
                 elements1.append(address3)
                 address4 = FAILURE
-                chunk1 = None
-                if self._offset < self._input_size:
-                    chunk1 = self._input[self._offset:self._offset + 1]
+                chunk1, max1 = None, self._offset + 1
+                if max1 <= self._input_size:
+                    chunk1 = self._input[self._offset:max1]
                 if chunk1 is not None and Grammar.REGEX_20.search(chunk1):
-                    address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address4 = FAILURE
@@ -1210,11 +1215,11 @@ class Grammar:
                 if address4 is not FAILURE:
                     elements1.append(address4)
                     address5 = FAILURE
-                    chunk2 = None
-                    if self._offset < self._input_size:
-                        chunk2 = self._input[self._offset:self._offset + 1]
+                    chunk2, max2 = None, self._offset + 1
+                    if max2 <= self._input_size:
+                        chunk2 = self._input[self._offset:max2]
                     if chunk2 is not None and Grammar.REGEX_21.search(chunk2):
-                        address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                        address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                         self._offset = self._offset + 1
                     else:
                         address5 = FAILURE
@@ -1226,11 +1231,11 @@ class Grammar:
                     if address5 is not FAILURE:
                         elements1.append(address5)
                         address6 = FAILURE
-                        chunk3 = None
-                        if self._offset < self._input_size:
-                            chunk3 = self._input[self._offset:self._offset + 1]
+                        chunk3, max3 = None, self._offset + 1
+                        if max3 <= self._input_size:
+                            chunk3 = self._input[self._offset:max3]
                         if chunk3 is not None and Grammar.REGEX_22.search(chunk3):
-                            address6 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                            address6 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                             self._offset = self._offset + 1
                         else:
                             address6 = FAILURE
@@ -1243,11 +1248,11 @@ class Grammar:
                             elements1.append(address6)
                             address7 = FAILURE
                             index5 = self._offset
-                            chunk4 = None
-                            if self._offset < self._input_size:
-                                chunk4 = self._input[self._offset:self._offset + 3]
+                            chunk4, max4 = None, self._offset + 3
+                            if max4 <= self._input_size:
+                                chunk4 = self._input[self._offset:max4]
                             if chunk4 == 'NDV':
-                                address7 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                                address7 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                                 self._offset = self._offset + 3
                             else:
                                 address7 = FAILURE
@@ -1257,7 +1262,7 @@ class Grammar:
                                 if self._offset == self._failure:
                                     self._expected.append('"NDV"')
                             if address7 is FAILURE:
-                                address7 = TreeNode(self._input[index5:index5], index5)
+                                address7 = TreeNode(self._input[index5:index5], index5, [])
                                 self._offset = index5
                             if address7 is not FAILURE:
                                 elements1.append(address7)
@@ -1285,11 +1290,11 @@ class Grammar:
                 self._offset = index3
                 index6, elements2 = self._offset, []
                 address8 = FAILURE
-                chunk5 = None
-                if self._offset < self._input_size:
-                    chunk5 = self._input[self._offset:self._offset + 1]
+                chunk5, max5 = None, self._offset + 1
+                if max5 <= self._input_size:
+                    chunk5 = self._input[self._offset:max5]
                 if chunk5 is not None and Grammar.REGEX_23.search(chunk5):
-                    address8 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address8 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address8 = FAILURE
@@ -1303,11 +1308,11 @@ class Grammar:
                     address9 = FAILURE
                     index7 = self._offset
                     index8 = self._offset
-                    chunk6 = None
-                    if self._offset < self._input_size:
-                        chunk6 = self._input[self._offset:self._offset + 1]
+                    chunk6, max6 = None, self._offset + 1
+                    if max6 <= self._input_size:
+                        chunk6 = self._input[self._offset:max6]
                     if chunk6 is not None and Grammar.REGEX_24.search(chunk6):
-                        address9 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                        address9 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                         self._offset = self._offset + 1
                     else:
                         address9 = FAILURE
@@ -1323,11 +1328,11 @@ class Grammar:
                         index10 = self._offset
                         index11, elements4 = self._offset, []
                         address11 = FAILURE
-                        chunk7 = None
-                        if self._offset < self._input_size:
-                            chunk7 = self._input[self._offset:self._offset + 1]
+                        chunk7, max7 = None, self._offset + 1
+                        if max7 <= self._input_size:
+                            chunk7 = self._input[self._offset:max7]
                         if chunk7 == ' ':
-                            address11 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                            address11 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                             self._offset = self._offset + 1
                         else:
                             address11 = FAILURE
@@ -1339,11 +1344,11 @@ class Grammar:
                         if address11 is not FAILURE:
                             elements4.append(address11)
                             address12 = FAILURE
-                            chunk8 = None
-                            if self._offset < self._input_size:
-                                chunk8 = self._input[self._offset:self._offset + 1]
+                            chunk8, max8 = None, self._offset + 1
+                            if max8 <= self._input_size:
+                                chunk8 = self._input[self._offset:max8]
                             if chunk8 is not None and Grammar.REGEX_25.search(chunk8):
-                                address12 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                address12 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                 self._offset = self._offset + 1
                             else:
                                 address12 = FAILURE
@@ -1366,16 +1371,16 @@ class Grammar:
                             address10 = TreeNode(self._input[index11:self._offset], index11, elements4)
                             self._offset = self._offset
                         if address10 is FAILURE:
-                            address10 = TreeNode(self._input[index10:index10], index10)
+                            address10 = TreeNode(self._input[index10:index10], index10, [])
                             self._offset = index10
                         if address10 is not FAILURE:
                             elements3.append(address10)
                             address13 = FAILURE
-                            chunk9 = None
-                            if self._offset < self._input_size:
-                                chunk9 = self._input[self._offset:self._offset + 1]
+                            chunk9, max9 = None, self._offset + 1
+                            if max9 <= self._input_size:
+                                chunk9 = self._input[self._offset:max9]
                             if chunk9 == '/':
-                                address13 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                address13 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                 self._offset = self._offset + 1
                             else:
                                 address13 = FAILURE
@@ -1387,11 +1392,11 @@ class Grammar:
                             if address13 is not FAILURE:
                                 elements3.append(address13)
                                 address14 = FAILURE
-                                chunk10 = None
-                                if self._offset < self._input_size:
-                                    chunk10 = self._input[self._offset:self._offset + 1]
+                                chunk10, max10 = None, self._offset + 1
+                                if max10 <= self._input_size:
+                                    chunk10 = self._input[self._offset:max10]
                                 if chunk10 is not None and Grammar.REGEX_26.search(chunk10):
-                                    address14 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                    address14 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                     self._offset = self._offset + 1
                                 else:
                                     address14 = FAILURE
@@ -1419,16 +1424,16 @@ class Grammar:
                         if address9 is FAILURE:
                             self._offset = index8
                     if address9 is FAILURE:
-                        address9 = TreeNode(self._input[index7:index7], index7)
+                        address9 = TreeNode(self._input[index7:index7], index7, [])
                         self._offset = index7
                     if address9 is not FAILURE:
                         elements2.append(address9)
                         address15 = FAILURE
-                        chunk11 = None
-                        if self._offset < self._input_size:
-                            chunk11 = self._input[self._offset:self._offset + 2]
+                        chunk11, max11 = None, self._offset + 2
+                        if max11 <= self._input_size:
+                            chunk11 = self._input[self._offset:max11]
                         if chunk11 == 'SM':
-                            address15 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                            address15 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                             self._offset = self._offset + 2
                         else:
                             address15 = FAILURE
@@ -1455,11 +1460,11 @@ class Grammar:
                     self._offset = self._offset
                 if address2 is FAILURE:
                     self._offset = index3
-                    chunk12 = None
-                    if self._offset < self._input_size:
-                        chunk12 = self._input[self._offset:self._offset + 5]
+                    chunk12, max12 = None, self._offset + 5
+                    if max12 <= self._input_size:
+                        chunk12 = self._input[self._offset:max12]
                     if chunk12 == 'CAVOK':
-                        address2 = TreeNode(self._input[self._offset:self._offset + 5], self._offset)
+                        address2 = TreeNode(self._input[self._offset:self._offset + 5], self._offset, [])
                         self._offset = self._offset + 5
                     else:
                         address2 = FAILURE
@@ -1484,7 +1489,7 @@ class Grammar:
             address0 = TreeNode6(self._input[index2:self._offset], index2, elements0)
             self._offset = self._offset
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['vis'][index0] = (address0, self._offset)
         return address0
@@ -1502,11 +1507,11 @@ class Grammar:
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 1]
+            chunk0, max0 = None, self._offset + 1
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 == 'R':
-                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address2 = FAILURE
@@ -1519,11 +1524,11 @@ class Grammar:
                 elements0.append(address2)
                 address3 = FAILURE
                 index3 = self._offset
-                chunk1 = None
-                if self._offset < self._input_size:
-                    chunk1 = self._input[self._offset:self._offset + 1]
+                chunk1, max1 = None, self._offset + 1
+                if max1 <= self._input_size:
+                    chunk1 = self._input[self._offset:max1]
                 if chunk1 is not None and Grammar.REGEX_27.search(chunk1):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -1533,16 +1538,16 @@ class Grammar:
                     if self._offset == self._failure:
                         self._expected.append('[LRC]')
                 if address3 is FAILURE:
-                    address3 = TreeNode(self._input[index3:index3], index3)
+                    address3 = TreeNode(self._input[index3:index3], index3, [])
                     self._offset = index3
                 if address3 is not FAILURE:
                     elements0.append(address3)
                     address4 = FAILURE
-                    chunk2 = None
-                    if self._offset < self._input_size:
-                        chunk2 = self._input[self._offset:self._offset + 1]
+                    chunk2, max2 = None, self._offset + 1
+                    if max2 <= self._input_size:
+                        chunk2 = self._input[self._offset:max2]
                     if chunk2 is not None and Grammar.REGEX_28.search(chunk2):
-                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                         self._offset = self._offset + 1
                     else:
                         address4 = FAILURE
@@ -1554,11 +1559,11 @@ class Grammar:
                     if address4 is not FAILURE:
                         elements0.append(address4)
                         address5 = FAILURE
-                        chunk3 = None
-                        if self._offset < self._input_size:
-                            chunk3 = self._input[self._offset:self._offset + 1]
+                        chunk3, max3 = None, self._offset + 1
+                        if max3 <= self._input_size:
+                            chunk3 = self._input[self._offset:max3]
                         if chunk3 is not None and Grammar.REGEX_29.search(chunk3):
-                            address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                            address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                             self._offset = self._offset + 1
                         else:
                             address5 = FAILURE
@@ -1571,11 +1576,11 @@ class Grammar:
                             elements0.append(address5)
                             address6 = FAILURE
                             index4 = self._offset
-                            chunk4 = None
-                            if self._offset < self._input_size:
-                                chunk4 = self._input[self._offset:self._offset + 1]
+                            chunk4, max4 = None, self._offset + 1
+                            if max4 <= self._input_size:
+                                chunk4 = self._input[self._offset:max4]
                             if chunk4 is not None and Grammar.REGEX_30.search(chunk4):
-                                address6 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                address6 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                 self._offset = self._offset + 1
                             else:
                                 address6 = FAILURE
@@ -1585,16 +1590,16 @@ class Grammar:
                                 if self._offset == self._failure:
                                     self._expected.append('[LRC]')
                             if address6 is FAILURE:
-                                address6 = TreeNode(self._input[index4:index4], index4)
+                                address6 = TreeNode(self._input[index4:index4], index4, [])
                                 self._offset = index4
                             if address6 is not FAILURE:
                                 elements0.append(address6)
                                 address7 = FAILURE
-                                chunk5 = None
-                                if self._offset < self._input_size:
-                                    chunk5 = self._input[self._offset:self._offset + 1]
+                                chunk5, max5 = None, self._offset + 1
+                                if max5 <= self._input_size:
+                                    chunk5 = self._input[self._offset:max5]
                                 if chunk5 == '/':
-                                    address7 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                    address7 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                     self._offset = self._offset + 1
                                 else:
                                     address7 = FAILURE
@@ -1609,11 +1614,11 @@ class Grammar:
                                     index5 = self._offset
                                     index6, elements1 = self._offset, []
                                     address9 = FAILURE
-                                    chunk6 = None
-                                    if self._offset < self._input_size:
-                                        chunk6 = self._input[self._offset:self._offset + 1]
+                                    chunk6, max6 = None, self._offset + 1
+                                    if max6 <= self._input_size:
+                                        chunk6 = self._input[self._offset:max6]
                                     if chunk6 is not None and Grammar.REGEX_31.search(chunk6):
-                                        address9 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                        address9 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                         self._offset = self._offset + 1
                                     else:
                                         address9 = FAILURE
@@ -1625,11 +1630,11 @@ class Grammar:
                                     if address9 is not FAILURE:
                                         elements1.append(address9)
                                         address10 = FAILURE
-                                        chunk7 = None
-                                        if self._offset < self._input_size:
-                                            chunk7 = self._input[self._offset:self._offset + 1]
+                                        chunk7, max7 = None, self._offset + 1
+                                        if max7 <= self._input_size:
+                                            chunk7 = self._input[self._offset:max7]
                                         if chunk7 is not None and Grammar.REGEX_32.search(chunk7):
-                                            address10 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                            address10 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                             self._offset = self._offset + 1
                                         else:
                                             address10 = FAILURE
@@ -1641,11 +1646,11 @@ class Grammar:
                                         if address10 is not FAILURE:
                                             elements1.append(address10)
                                             address11 = FAILURE
-                                            chunk8 = None
-                                            if self._offset < self._input_size:
-                                                chunk8 = self._input[self._offset:self._offset + 1]
+                                            chunk8, max8 = None, self._offset + 1
+                                            if max8 <= self._input_size:
+                                                chunk8 = self._input[self._offset:max8]
                                             if chunk8 is not None and Grammar.REGEX_33.search(chunk8):
-                                                address11 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                                address11 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                                 self._offset = self._offset + 1
                                             else:
                                                 address11 = FAILURE
@@ -1657,11 +1662,11 @@ class Grammar:
                                             if address11 is not FAILURE:
                                                 elements1.append(address11)
                                                 address12 = FAILURE
-                                                chunk9 = None
-                                                if self._offset < self._input_size:
-                                                    chunk9 = self._input[self._offset:self._offset + 1]
+                                                chunk9, max9 = None, self._offset + 1
+                                                if max9 <= self._input_size:
+                                                    chunk9 = self._input[self._offset:max9]
                                                 if chunk9 is not None and Grammar.REGEX_34.search(chunk9):
-                                                    address12 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                                    address12 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                                     self._offset = self._offset + 1
                                                 else:
                                                     address12 = FAILURE
@@ -1673,11 +1678,11 @@ class Grammar:
                                                 if address12 is not FAILURE:
                                                     elements1.append(address12)
                                                     address13 = FAILURE
-                                                    chunk10 = None
-                                                    if self._offset < self._input_size:
-                                                        chunk10 = self._input[self._offset:self._offset + 1]
+                                                    chunk10, max10 = None, self._offset + 1
+                                                    if max10 <= self._input_size:
+                                                        chunk10 = self._input[self._offset:max10]
                                                     if chunk10 == 'V':
-                                                        address13 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                                        address13 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                                         self._offset = self._offset + 1
                                                     else:
                                                         address13 = FAILURE
@@ -1709,17 +1714,17 @@ class Grammar:
                                         address8 = TreeNode(self._input[index6:self._offset], index6, elements1)
                                         self._offset = self._offset
                                     if address8 is FAILURE:
-                                        address8 = TreeNode(self._input[index5:index5], index5)
+                                        address8 = TreeNode(self._input[index5:index5], index5, [])
                                         self._offset = index5
                                     if address8 is not FAILURE:
                                         elements0.append(address8)
                                         address14 = FAILURE
                                         index7 = self._offset
-                                        chunk11 = None
-                                        if self._offset < self._input_size:
-                                            chunk11 = self._input[self._offset:self._offset + 1]
+                                        chunk11, max11 = None, self._offset + 1
+                                        if max11 <= self._input_size:
+                                            chunk11 = self._input[self._offset:max11]
                                         if chunk11 is not None and Grammar.REGEX_35.search(chunk11):
-                                            address14 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                            address14 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                             self._offset = self._offset + 1
                                         else:
                                             address14 = FAILURE
@@ -1729,16 +1734,16 @@ class Grammar:
                                             if self._offset == self._failure:
                                                 self._expected.append('["M" / "P"]')
                                         if address14 is FAILURE:
-                                            address14 = TreeNode(self._input[index7:index7], index7)
+                                            address14 = TreeNode(self._input[index7:index7], index7, [])
                                             self._offset = index7
                                         if address14 is not FAILURE:
                                             elements0.append(address14)
                                             address15 = FAILURE
-                                            chunk12 = None
-                                            if self._offset < self._input_size:
-                                                chunk12 = self._input[self._offset:self._offset + 1]
+                                            chunk12, max12 = None, self._offset + 1
+                                            if max12 <= self._input_size:
+                                                chunk12 = self._input[self._offset:max12]
                                             if chunk12 is not None and Grammar.REGEX_36.search(chunk12):
-                                                address15 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                                address15 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                                 self._offset = self._offset + 1
                                             else:
                                                 address15 = FAILURE
@@ -1750,11 +1755,11 @@ class Grammar:
                                             if address15 is not FAILURE:
                                                 elements0.append(address15)
                                                 address16 = FAILURE
-                                                chunk13 = None
-                                                if self._offset < self._input_size:
-                                                    chunk13 = self._input[self._offset:self._offset + 1]
+                                                chunk13, max13 = None, self._offset + 1
+                                                if max13 <= self._input_size:
+                                                    chunk13 = self._input[self._offset:max13]
                                                 if chunk13 is not None and Grammar.REGEX_37.search(chunk13):
-                                                    address16 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                                    address16 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                                     self._offset = self._offset + 1
                                                 else:
                                                     address16 = FAILURE
@@ -1766,11 +1771,11 @@ class Grammar:
                                                 if address16 is not FAILURE:
                                                     elements0.append(address16)
                                                     address17 = FAILURE
-                                                    chunk14 = None
-                                                    if self._offset < self._input_size:
-                                                        chunk14 = self._input[self._offset:self._offset + 1]
+                                                    chunk14, max14 = None, self._offset + 1
+                                                    if max14 <= self._input_size:
+                                                        chunk14 = self._input[self._offset:max14]
                                                     if chunk14 is not None and Grammar.REGEX_38.search(chunk14):
-                                                        address17 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                                        address17 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                                         self._offset = self._offset + 1
                                                     else:
                                                         address17 = FAILURE
@@ -1782,11 +1787,11 @@ class Grammar:
                                                     if address17 is not FAILURE:
                                                         elements0.append(address17)
                                                         address18 = FAILURE
-                                                        chunk15 = None
-                                                        if self._offset < self._input_size:
-                                                            chunk15 = self._input[self._offset:self._offset + 1]
+                                                        chunk15, max15 = None, self._offset + 1
+                                                        if max15 <= self._input_size:
+                                                            chunk15 = self._input[self._offset:max15]
                                                         if chunk15 is not None and Grammar.REGEX_39.search(chunk15):
-                                                            address18 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                                            address18 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                                             self._offset = self._offset + 1
                                                         else:
                                                             address18 = FAILURE
@@ -1798,11 +1803,11 @@ class Grammar:
                                                         if address18 is not FAILURE:
                                                             elements0.append(address18)
                                                             address19 = FAILURE
-                                                            chunk16 = None
-                                                            if self._offset < self._input_size:
-                                                                chunk16 = self._input[self._offset:self._offset + 2]
+                                                            chunk16, max16 = None, self._offset + 2
+                                                            if max16 <= self._input_size:
+                                                                chunk16 = self._input[self._offset:max16]
                                                             if chunk16 == 'FT':
-                                                                address19 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                                address19 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                                 self._offset = self._offset + 2
                                                             else:
                                                                 address19 = FAILURE
@@ -1861,7 +1866,7 @@ class Grammar:
             address0 = TreeNode7(self._input[index2:self._offset], index2, elements0)
             self._offset = self._offset
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['run'][index0] = (address0, self._offset)
         return address0
@@ -1904,7 +1909,7 @@ class Grammar:
         else:
             address0 = FAILURE
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['curwx'][index0] = (address0, self._offset)
         return address0
@@ -1919,11 +1924,11 @@ class Grammar:
         address1 = FAILURE
         index2 = self._offset
         index3 = self._offset
-        chunk0 = None
-        if self._offset < self._input_size:
-            chunk0 = self._input[self._offset:self._offset + 1]
+        chunk0, max0 = None, self._offset + 1
+        if max0 <= self._input_size:
+            chunk0 = self._input[self._offset:max0]
         if chunk0 is not None and Grammar.REGEX_40.search(chunk0):
-            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
             self._offset = self._offset + 1
         else:
             address1 = FAILURE
@@ -1934,11 +1939,11 @@ class Grammar:
                 self._expected.append('[-+]')
         if address1 is FAILURE:
             self._offset = index3
-            chunk1 = None
-            if self._offset < self._input_size:
-                chunk1 = self._input[self._offset:self._offset + 2]
+            chunk1, max1 = None, self._offset + 2
+            if max1 <= self._input_size:
+                chunk1 = self._input[self._offset:max1]
             if chunk1 == 'VC':
-                address1 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                address1 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                 self._offset = self._offset + 2
             else:
                 address1 = FAILURE
@@ -1950,17 +1955,17 @@ class Grammar:
             if address1 is FAILURE:
                 self._offset = index3
         if address1 is FAILURE:
-            address1 = TreeNode(self._input[index2:index2], index2)
+            address1 = TreeNode(self._input[index2:index2], index2, [])
             self._offset = index2
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
             index4 = self._offset
-            chunk2 = None
-            if self._offset < self._input_size:
-                chunk2 = self._input[self._offset:self._offset + 2]
+            chunk2, max2 = None, self._offset + 2
+            if max2 <= self._input_size:
+                chunk2 = self._input[self._offset:max2]
             if chunk2 == 'MI':
-                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                 self._offset = self._offset + 2
             else:
                 address2 = FAILURE
@@ -1971,11 +1976,11 @@ class Grammar:
                     self._expected.append('"MI"')
             if address2 is FAILURE:
                 self._offset = index4
-                chunk3 = None
-                if self._offset < self._input_size:
-                    chunk3 = self._input[self._offset:self._offset + 2]
+                chunk3, max3 = None, self._offset + 2
+                if max3 <= self._input_size:
+                    chunk3 = self._input[self._offset:max3]
                 if chunk3 == 'PR':
-                    address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                    address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                     self._offset = self._offset + 2
                 else:
                     address2 = FAILURE
@@ -1986,11 +1991,11 @@ class Grammar:
                         self._expected.append('"PR"')
                 if address2 is FAILURE:
                     self._offset = index4
-                    chunk4 = None
-                    if self._offset < self._input_size:
-                        chunk4 = self._input[self._offset:self._offset + 2]
+                    chunk4, max4 = None, self._offset + 2
+                    if max4 <= self._input_size:
+                        chunk4 = self._input[self._offset:max4]
                     if chunk4 == 'DR':
-                        address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                        address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                         self._offset = self._offset + 2
                     else:
                         address2 = FAILURE
@@ -2001,11 +2006,11 @@ class Grammar:
                             self._expected.append('"DR"')
                     if address2 is FAILURE:
                         self._offset = index4
-                        chunk5 = None
-                        if self._offset < self._input_size:
-                            chunk5 = self._input[self._offset:self._offset + 2]
+                        chunk5, max5 = None, self._offset + 2
+                        if max5 <= self._input_size:
+                            chunk5 = self._input[self._offset:max5]
                         if chunk5 == 'BL':
-                            address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                            address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                             self._offset = self._offset + 2
                         else:
                             address2 = FAILURE
@@ -2016,11 +2021,11 @@ class Grammar:
                                 self._expected.append('"BL"')
                         if address2 is FAILURE:
                             self._offset = index4
-                            chunk6 = None
-                            if self._offset < self._input_size:
-                                chunk6 = self._input[self._offset:self._offset + 2]
+                            chunk6, max6 = None, self._offset + 2
+                            if max6 <= self._input_size:
+                                chunk6 = self._input[self._offset:max6]
                             if chunk6 == 'SH':
-                                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                 self._offset = self._offset + 2
                             else:
                                 address2 = FAILURE
@@ -2031,11 +2036,11 @@ class Grammar:
                                     self._expected.append('"SH"')
                             if address2 is FAILURE:
                                 self._offset = index4
-                                chunk7 = None
-                                if self._offset < self._input_size:
-                                    chunk7 = self._input[self._offset:self._offset + 2]
+                                chunk7, max7 = None, self._offset + 2
+                                if max7 <= self._input_size:
+                                    chunk7 = self._input[self._offset:max7]
                                 if chunk7 == 'TS':
-                                    address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                    address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                     self._offset = self._offset + 2
                                 else:
                                     address2 = FAILURE
@@ -2046,11 +2051,11 @@ class Grammar:
                                         self._expected.append('"TS"')
                                 if address2 is FAILURE:
                                     self._offset = index4
-                                    chunk8 = None
-                                    if self._offset < self._input_size:
-                                        chunk8 = self._input[self._offset:self._offset + 2]
+                                    chunk8, max8 = None, self._offset + 2
+                                    if max8 <= self._input_size:
+                                        chunk8 = self._input[self._offset:max8]
                                     if chunk8 == 'FG':
-                                        address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                        address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                         self._offset = self._offset + 2
                                     else:
                                         address2 = FAILURE
@@ -2061,11 +2066,11 @@ class Grammar:
                                             self._expected.append('"FG"')
                                     if address2 is FAILURE:
                                         self._offset = index4
-                                        chunk9 = None
-                                        if self._offset < self._input_size:
-                                            chunk9 = self._input[self._offset:self._offset + 2]
+                                        chunk9, max9 = None, self._offset + 2
+                                        if max9 <= self._input_size:
+                                            chunk9 = self._input[self._offset:max9]
                                         if chunk9 == 'TS':
-                                            address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                            address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                             self._offset = self._offset + 2
                                         else:
                                             address2 = FAILURE
@@ -2076,11 +2081,11 @@ class Grammar:
                                                 self._expected.append('"TS"')
                                         if address2 is FAILURE:
                                             self._offset = index4
-                                            chunk10 = None
-                                            if self._offset < self._input_size:
-                                                chunk10 = self._input[self._offset:self._offset + 2]
+                                            chunk10, max10 = None, self._offset + 2
+                                            if max10 <= self._input_size:
+                                                chunk10 = self._input[self._offset:max10]
                                             if chunk10 == 'FZ':
-                                                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                 self._offset = self._offset + 2
                                             else:
                                                 address2 = FAILURE
@@ -2091,11 +2096,11 @@ class Grammar:
                                                     self._expected.append('"FZ"')
                                             if address2 is FAILURE:
                                                 self._offset = index4
-                                                chunk11 = None
-                                                if self._offset < self._input_size:
-                                                    chunk11 = self._input[self._offset:self._offset + 2]
+                                                chunk11, max11 = None, self._offset + 2
+                                                if max11 <= self._input_size:
+                                                    chunk11 = self._input[self._offset:max11]
                                                 if chunk11 == 'RA':
-                                                    address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                    address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                     self._offset = self._offset + 2
                                                 else:
                                                     address2 = FAILURE
@@ -2106,11 +2111,11 @@ class Grammar:
                                                         self._expected.append('"RA"')
                                                 if address2 is FAILURE:
                                                     self._offset = index4
-                                                    chunk12 = None
-                                                    if self._offset < self._input_size:
-                                                        chunk12 = self._input[self._offset:self._offset + 2]
+                                                    chunk12, max12 = None, self._offset + 2
+                                                    if max12 <= self._input_size:
+                                                        chunk12 = self._input[self._offset:max12]
                                                     if chunk12 == 'BR':
-                                                        address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                        address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                         self._offset = self._offset + 2
                                                     else:
                                                         address2 = FAILURE
@@ -2121,11 +2126,11 @@ class Grammar:
                                                             self._expected.append('"BR"')
                                                     if address2 is FAILURE:
                                                         self._offset = index4
-                                                        chunk13 = None
-                                                        if self._offset < self._input_size:
-                                                            chunk13 = self._input[self._offset:self._offset + 2]
+                                                        chunk13, max13 = None, self._offset + 2
+                                                        if max13 <= self._input_size:
+                                                            chunk13 = self._input[self._offset:max13]
                                                         if chunk13 == 'HZ':
-                                                            address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                            address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                             self._offset = self._offset + 2
                                                         else:
                                                             address2 = FAILURE
@@ -2136,11 +2141,11 @@ class Grammar:
                                                                 self._expected.append('"HZ"')
                                                         if address2 is FAILURE:
                                                             self._offset = index4
-                                                            chunk14 = None
-                                                            if self._offset < self._input_size:
-                                                                chunk14 = self._input[self._offset:self._offset + 2]
+                                                            chunk14, max14 = None, self._offset + 2
+                                                            if max14 <= self._input_size:
+                                                                chunk14 = self._input[self._offset:max14]
                                                             if chunk14 == 'SN':
-                                                                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                                 self._offset = self._offset + 2
                                                             else:
                                                                 address2 = FAILURE
@@ -2155,11 +2160,11 @@ class Grammar:
                 elements0.append(address2)
                 address3 = FAILURE
                 index5 = self._offset
-                chunk15 = None
-                if self._offset < self._input_size:
-                    chunk15 = self._input[self._offset:self._offset + 1]
+                chunk15, max15 = None, self._offset + 1
+                if max15 <= self._input_size:
+                    chunk15 = self._input[self._offset:max15]
                 if chunk15 is not None and Grammar.REGEX_41.search(chunk15):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -2169,18 +2174,18 @@ class Grammar:
                     if self._offset == self._failure:
                         self._expected.append('[-+]')
                 if address3 is FAILURE:
-                    address3 = TreeNode(self._input[index5:index5], index5)
+                    address3 = TreeNode(self._input[index5:index5], index5, [])
                     self._offset = index5
                 if address3 is not FAILURE:
                     elements0.append(address3)
                     address4 = FAILURE
                     index6 = self._offset
                     index7 = self._offset
-                    chunk16 = None
-                    if self._offset < self._input_size:
-                        chunk16 = self._input[self._offset:self._offset + 2]
+                    chunk16, max16 = None, self._offset + 2
+                    if max16 <= self._input_size:
+                        chunk16 = self._input[self._offset:max16]
                     if chunk16 == 'RA':
-                        address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                        address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                         self._offset = self._offset + 2
                     else:
                         address4 = FAILURE
@@ -2191,11 +2196,11 @@ class Grammar:
                             self._expected.append('"RA"')
                     if address4 is FAILURE:
                         self._offset = index7
-                        chunk17 = None
-                        if self._offset < self._input_size:
-                            chunk17 = self._input[self._offset:self._offset + 2]
+                        chunk17, max17 = None, self._offset + 2
+                        if max17 <= self._input_size:
+                            chunk17 = self._input[self._offset:max17]
                         if chunk17 == 'BR':
-                            address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                            address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                             self._offset = self._offset + 2
                         else:
                             address4 = FAILURE
@@ -2206,11 +2211,11 @@ class Grammar:
                                 self._expected.append('"BR"')
                         if address4 is FAILURE:
                             self._offset = index7
-                            chunk18 = None
-                            if self._offset < self._input_size:
-                                chunk18 = self._input[self._offset:self._offset + 2]
+                            chunk18, max18 = None, self._offset + 2
+                            if max18 <= self._input_size:
+                                chunk18 = self._input[self._offset:max18]
                             if chunk18 == 'DZ':
-                                address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                 self._offset = self._offset + 2
                             else:
                                 address4 = FAILURE
@@ -2221,11 +2226,11 @@ class Grammar:
                                     self._expected.append('"DZ"')
                             if address4 is FAILURE:
                                 self._offset = index7
-                                chunk19 = None
-                                if self._offset < self._input_size:
-                                    chunk19 = self._input[self._offset:self._offset + 2]
+                                chunk19, max19 = None, self._offset + 2
+                                if max19 <= self._input_size:
+                                    chunk19 = self._input[self._offset:max19]
                                 if chunk19 == 'FG':
-                                    address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                    address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                     self._offset = self._offset + 2
                                 else:
                                     address4 = FAILURE
@@ -2236,11 +2241,11 @@ class Grammar:
                                         self._expected.append('"FG"')
                                 if address4 is FAILURE:
                                     self._offset = index7
-                                    chunk20 = None
-                                    if self._offset < self._input_size:
-                                        chunk20 = self._input[self._offset:self._offset + 2]
+                                    chunk20, max20 = None, self._offset + 2
+                                    if max20 <= self._input_size:
+                                        chunk20 = self._input[self._offset:max20]
                                     if chunk20 == 'FU':
-                                        address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                        address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                         self._offset = self._offset + 2
                                     else:
                                         address4 = FAILURE
@@ -2251,11 +2256,11 @@ class Grammar:
                                             self._expected.append('"FU"')
                                     if address4 is FAILURE:
                                         self._offset = index7
-                                        chunk21 = None
-                                        if self._offset < self._input_size:
-                                            chunk21 = self._input[self._offset:self._offset + 2]
+                                        chunk21, max21 = None, self._offset + 2
+                                        if max21 <= self._input_size:
+                                            chunk21 = self._input[self._offset:max21]
                                         if chunk21 == 'VA':
-                                            address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                            address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                             self._offset = self._offset + 2
                                         else:
                                             address4 = FAILURE
@@ -2266,11 +2271,11 @@ class Grammar:
                                                 self._expected.append('"VA"')
                                         if address4 is FAILURE:
                                             self._offset = index7
-                                            chunk22 = None
-                                            if self._offset < self._input_size:
-                                                chunk22 = self._input[self._offset:self._offset + 2]
+                                            chunk22, max22 = None, self._offset + 2
+                                            if max22 <= self._input_size:
+                                                chunk22 = self._input[self._offset:max22]
                                             if chunk22 == 'DU':
-                                                address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                 self._offset = self._offset + 2
                                             else:
                                                 address4 = FAILURE
@@ -2281,11 +2286,11 @@ class Grammar:
                                                     self._expected.append('"DU"')
                                             if address4 is FAILURE:
                                                 self._offset = index7
-                                                chunk23 = None
-                                                if self._offset < self._input_size:
-                                                    chunk23 = self._input[self._offset:self._offset + 2]
+                                                chunk23, max23 = None, self._offset + 2
+                                                if max23 <= self._input_size:
+                                                    chunk23 = self._input[self._offset:max23]
                                                 if chunk23 == 'SA':
-                                                    address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                    address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                     self._offset = self._offset + 2
                                                 else:
                                                     address4 = FAILURE
@@ -2296,11 +2301,11 @@ class Grammar:
                                                         self._expected.append('"SA"')
                                                 if address4 is FAILURE:
                                                     self._offset = index7
-                                                    chunk24 = None
-                                                    if self._offset < self._input_size:
-                                                        chunk24 = self._input[self._offset:self._offset + 2]
+                                                    chunk24, max24 = None, self._offset + 2
+                                                    if max24 <= self._input_size:
+                                                        chunk24 = self._input[self._offset:max24]
                                                     if chunk24 == 'SA':
-                                                        address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                        address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                         self._offset = self._offset + 2
                                                     else:
                                                         address4 = FAILURE
@@ -2311,11 +2316,11 @@ class Grammar:
                                                             self._expected.append('"SA"')
                                                     if address4 is FAILURE:
                                                         self._offset = index7
-                                                        chunk25 = None
-                                                        if self._offset < self._input_size:
-                                                            chunk25 = self._input[self._offset:self._offset + 2]
+                                                        chunk25, max25 = None, self._offset + 2
+                                                        if max25 <= self._input_size:
+                                                            chunk25 = self._input[self._offset:max25]
                                                         if chunk25 == 'HZ':
-                                                            address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                            address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                             self._offset = self._offset + 2
                                                         else:
                                                             address4 = FAILURE
@@ -2326,11 +2331,11 @@ class Grammar:
                                                                 self._expected.append('"HZ"')
                                                         if address4 is FAILURE:
                                                             self._offset = index7
-                                                            chunk26 = None
-                                                            if self._offset < self._input_size:
-                                                                chunk26 = self._input[self._offset:self._offset + 2]
+                                                            chunk26, max26 = None, self._offset + 2
+                                                            if max26 <= self._input_size:
+                                                                chunk26 = self._input[self._offset:max26]
                                                             if chunk26 == 'PY':
-                                                                address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                                                address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                                                 self._offset = self._offset + 2
                                                             else:
                                                                 address4 = FAILURE
@@ -2342,7 +2347,7 @@ class Grammar:
                                                             if address4 is FAILURE:
                                                                 self._offset = index7
                     if address4 is FAILURE:
-                        address4 = TreeNode(self._input[index6:index6], index6)
+                        address4 = TreeNode(self._input[index6:index6], index6, [])
                         self._offset = index6
                     if address4 is not FAILURE:
                         elements0.append(address4)
@@ -2404,7 +2409,7 @@ class Grammar:
         else:
             address0 = FAILURE
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['skyc'][index0] = (address0, self._offset)
         return address0
@@ -2419,11 +2424,11 @@ class Grammar:
         index2, elements0 = self._offset, []
         address1 = FAILURE
         index3 = self._offset
-        chunk0 = None
-        if self._offset < self._input_size:
-            chunk0 = self._input[self._offset:self._offset + 3]
+        chunk0, max0 = None, self._offset + 3
+        if max0 <= self._input_size:
+            chunk0 = self._input[self._offset:max0]
         if chunk0 == 'FEW':
-            address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+            address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
             self._offset = self._offset + 3
         else:
             address1 = FAILURE
@@ -2434,11 +2439,11 @@ class Grammar:
                 self._expected.append('"FEW"')
         if address1 is FAILURE:
             self._offset = index3
-            chunk1 = None
-            if self._offset < self._input_size:
-                chunk1 = self._input[self._offset:self._offset + 3]
+            chunk1, max1 = None, self._offset + 3
+            if max1 <= self._input_size:
+                chunk1 = self._input[self._offset:max1]
             if chunk1 == 'SCT':
-                address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                 self._offset = self._offset + 3
             else:
                 address1 = FAILURE
@@ -2449,11 +2454,11 @@ class Grammar:
                     self._expected.append('"SCT"')
             if address1 is FAILURE:
                 self._offset = index3
-                chunk2 = None
-                if self._offset < self._input_size:
-                    chunk2 = self._input[self._offset:self._offset + 3]
+                chunk2, max2 = None, self._offset + 3
+                if max2 <= self._input_size:
+                    chunk2 = self._input[self._offset:max2]
                 if chunk2 == 'BKN':
-                    address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                    address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                     self._offset = self._offset + 3
                 else:
                     address1 = FAILURE
@@ -2464,11 +2469,11 @@ class Grammar:
                         self._expected.append('"BKN"')
                 if address1 is FAILURE:
                     self._offset = index3
-                    chunk3 = None
-                    if self._offset < self._input_size:
-                        chunk3 = self._input[self._offset:self._offset + 3]
+                    chunk3, max3 = None, self._offset + 3
+                    if max3 <= self._input_size:
+                        chunk3 = self._input[self._offset:max3]
                     if chunk3 == 'OVC':
-                        address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                        address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                         self._offset = self._offset + 3
                     else:
                         address1 = FAILURE
@@ -2479,11 +2484,11 @@ class Grammar:
                             self._expected.append('"OVC"')
                     if address1 is FAILURE:
                         self._offset = index3
-                        chunk4 = None
-                        if self._offset < self._input_size:
-                            chunk4 = self._input[self._offset:self._offset + 2]
+                        chunk4, max4 = None, self._offset + 2
+                        if max4 <= self._input_size:
+                            chunk4 = self._input[self._offset:max4]
                         if chunk4 == 'VV':
-                            address1 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                            address1 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                             self._offset = self._offset + 2
                         else:
                             address1 = FAILURE
@@ -2494,11 +2499,11 @@ class Grammar:
                                 self._expected.append('"VV"')
                         if address1 is FAILURE:
                             self._offset = index3
-                            chunk5 = None
-                            if self._offset < self._input_size:
-                                chunk5 = self._input[self._offset:self._offset + 3]
+                            chunk5, max5 = None, self._offset + 3
+                            if max5 <= self._input_size:
+                                chunk5 = self._input[self._offset:max5]
                             if chunk5 == '///':
-                                address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                                address1 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                                 self._offset = self._offset + 3
                             else:
                                 address1 = FAILURE
@@ -2515,11 +2520,11 @@ class Grammar:
             index4 = self._offset
             remaining0, index5, elements1, address3 = 0, self._offset, [], True
             while address3 is not FAILURE:
-                chunk6 = None
-                if self._offset < self._input_size:
-                    chunk6 = self._input[self._offset:self._offset + 1]
+                chunk6, max6 = None, self._offset + 1
+                if max6 <= self._input_size:
+                    chunk6 = self._input[self._offset:max6]
                 if chunk6 is not None and Grammar.REGEX_42.search(chunk6):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -2537,18 +2542,18 @@ class Grammar:
             else:
                 address2 = FAILURE
             if address2 is FAILURE:
-                address2 = TreeNode(self._input[index4:index4], index4)
+                address2 = TreeNode(self._input[index4:index4], index4, [])
                 self._offset = index4
             if address2 is not FAILURE:
                 elements0.append(address2)
                 address4 = FAILURE
                 index6 = self._offset
                 index7 = self._offset
-                chunk7 = None
-                if self._offset < self._input_size:
-                    chunk7 = self._input[self._offset:self._offset + 3]
+                chunk7, max7 = None, self._offset + 3
+                if max7 <= self._input_size:
+                    chunk7 = self._input[self._offset:max7]
                 if chunk7 == 'TCU':
-                    address4 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                    address4 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                     self._offset = self._offset + 3
                 else:
                     address4 = FAILURE
@@ -2559,11 +2564,11 @@ class Grammar:
                         self._expected.append('"TCU"')
                 if address4 is FAILURE:
                     self._offset = index7
-                    chunk8 = None
-                    if self._offset < self._input_size:
-                        chunk8 = self._input[self._offset:self._offset + 2]
+                    chunk8, max8 = None, self._offset + 2
+                    if max8 <= self._input_size:
+                        chunk8 = self._input[self._offset:max8]
                     if chunk8 == 'CB':
-                        address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                        address4 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                         self._offset = self._offset + 2
                     else:
                         address4 = FAILURE
@@ -2574,11 +2579,11 @@ class Grammar:
                             self._expected.append('"CB"')
                     if address4 is FAILURE:
                         self._offset = index7
-                        chunk9 = None
-                        if self._offset < self._input_size:
-                            chunk9 = self._input[self._offset:self._offset + 3]
+                        chunk9, max9 = None, self._offset + 3
+                        if max9 <= self._input_size:
+                            chunk9 = self._input[self._offset:max9]
                         if chunk9 == '///':
-                            address4 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                            address4 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                             self._offset = self._offset + 3
                         else:
                             address4 = FAILURE
@@ -2590,7 +2595,7 @@ class Grammar:
                         if address4 is FAILURE:
                             self._offset = index7
                 if address4 is FAILURE:
-                    address4 = TreeNode(self._input[index6:index6], index6)
+                    address4 = TreeNode(self._input[index6:index6], index6, [])
                     self._offset = index6
                 if address4 is not FAILURE:
                     elements0.append(address4)
@@ -2611,11 +2616,11 @@ class Grammar:
         if address0 is FAILURE:
             self._offset = index1
             index8 = self._offset
-            chunk10 = None
-            if self._offset < self._input_size:
-                chunk10 = self._input[self._offset:self._offset + 3]
+            chunk10, max10 = None, self._offset + 3
+            if max10 <= self._input_size:
+                chunk10 = self._input[self._offset:max10]
             if chunk10 == 'CLR':
-                address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                 self._offset = self._offset + 3
             else:
                 address0 = FAILURE
@@ -2626,11 +2631,11 @@ class Grammar:
                     self._expected.append('"CLR"')
             if address0 is FAILURE:
                 self._offset = index8
-                chunk11 = None
-                if self._offset < self._input_size:
-                    chunk11 = self._input[self._offset:self._offset + 3]
+                chunk11, max11 = None, self._offset + 3
+                if max11 <= self._input_size:
+                    chunk11 = self._input[self._offset:max11]
                 if chunk11 == 'SKC':
-                    address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                    address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                     self._offset = self._offset + 3
                 else:
                     address0 = FAILURE
@@ -2641,11 +2646,11 @@ class Grammar:
                         self._expected.append('"SKC"')
                 if address0 is FAILURE:
                     self._offset = index8
-                    chunk12 = None
-                    if self._offset < self._input_size:
-                        chunk12 = self._input[self._offset:self._offset + 3]
+                    chunk12, max12 = None, self._offset + 3
+                    if max12 <= self._input_size:
+                        chunk12 = self._input[self._offset:max12]
                     if chunk12 == 'NSC':
-                        address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                        address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                         self._offset = self._offset + 3
                     else:
                         address0 = FAILURE
@@ -2656,11 +2661,11 @@ class Grammar:
                             self._expected.append('"NSC"')
                     if address0 is FAILURE:
                         self._offset = index8
-                        chunk13 = None
-                        if self._offset < self._input_size:
-                            chunk13 = self._input[self._offset:self._offset + 3]
+                        chunk13, max13 = None, self._offset + 3
+                        if max13 <= self._input_size:
+                            chunk13 = self._input[self._offset:max13]
                         if chunk13 == 'NCD':
-                            address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                            address0 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                             self._offset = self._offset + 3
                         else:
                             address0 = FAILURE
@@ -2676,11 +2681,11 @@ class Grammar:
                 address0 = self._read_wx()
                 if address0 is FAILURE:
                     self._offset = index1
-                    chunk14 = None
-                    if self._offset < self._input_size:
-                        chunk14 = self._input[self._offset:self._offset + 2]
+                    chunk14, max14 = None, self._offset + 2
+                    if max14 <= self._input_size:
+                        chunk14 = self._input[self._offset:max14]
                     if chunk14 == '//':
-                        address0 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                        address0 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                         self._offset = self._offset + 2
                     else:
                         address0 = FAILURE
@@ -2708,11 +2713,11 @@ class Grammar:
             elements0.append(address1)
             address2 = FAILURE
             index3 = self._offset
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 2]
+            chunk0, max0 = None, self._offset + 2
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 == '//':
-                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                 self._offset = self._offset + 2
             else:
                 address2 = FAILURE
@@ -2722,7 +2727,7 @@ class Grammar:
                 if self._offset == self._failure:
                     self._expected.append('"//"')
             if address2 is FAILURE:
-                address2 = TreeNode(self._input[index3:index3], index3)
+                address2 = TreeNode(self._input[index3:index3], index3, [])
                 self._offset = index3
             if address2 is not FAILURE:
                 elements0.append(address2)
@@ -2731,11 +2736,11 @@ class Grammar:
                 if address3 is not FAILURE:
                     elements0.append(address3)
                     address4 = FAILURE
-                    chunk1 = None
-                    if self._offset < self._input_size:
-                        chunk1 = self._input[self._offset:self._offset + 1]
+                    chunk1, max1 = None, self._offset + 1
+                    if max1 <= self._input_size:
+                        chunk1 = self._input[self._offset:max1]
                     if chunk1 == '/':
-                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                         self._offset = self._offset + 1
                     else:
                         address4 = FAILURE
@@ -2752,11 +2757,11 @@ class Grammar:
                             elements0.append(address5)
                             address6 = FAILURE
                             index4 = self._offset
-                            chunk2 = None
-                            if self._offset < self._input_size:
-                                chunk2 = self._input[self._offset:self._offset + 2]
+                            chunk2, max2 = None, self._offset + 2
+                            if max2 <= self._input_size:
+                                chunk2 = self._input[self._offset:max2]
                             if chunk2 == '//':
-                                address6 = TreeNode(self._input[self._offset:self._offset + 2], self._offset)
+                                address6 = TreeNode(self._input[self._offset:self._offset + 2], self._offset, [])
                                 self._offset = self._offset + 2
                             else:
                                 address6 = FAILURE
@@ -2766,7 +2771,7 @@ class Grammar:
                                 if self._offset == self._failure:
                                     self._expected.append('"//"')
                             if address6 is FAILURE:
-                                address6 = TreeNode(self._input[index4:index4], index4)
+                                address6 = TreeNode(self._input[index4:index4], index4, [])
                                 self._offset = index4
                             if address6 is not FAILURE:
                                 elements0.append(address6)
@@ -2794,7 +2799,7 @@ class Grammar:
             address0 = TreeNode10(self._input[index2:self._offset], index2, elements0)
             self._offset = self._offset
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['temp_dewp'][index0] = (address0, self._offset)
         return address0
@@ -2808,11 +2813,11 @@ class Grammar:
         index1, elements0 = self._offset, []
         address1 = FAILURE
         index2 = self._offset
-        chunk0 = None
-        if self._offset < self._input_size:
-            chunk0 = self._input[self._offset:self._offset + 1]
+        chunk0, max0 = None, self._offset + 1
+        if max0 <= self._input_size:
+            chunk0 = self._input[self._offset:max0]
         if chunk0 is not None and Grammar.REGEX_43.search(chunk0):
-            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
             self._offset = self._offset + 1
         else:
             address1 = FAILURE
@@ -2822,17 +2827,17 @@ class Grammar:
             if self._offset == self._failure:
                 self._expected.append('[M]')
         if address1 is FAILURE:
-            address1 = TreeNode(self._input[index2:index2], index2)
+            address1 = TreeNode(self._input[index2:index2], index2, [])
             self._offset = index2
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
             index3 = self._offset
-            chunk1 = None
-            if self._offset < self._input_size:
-                chunk1 = self._input[self._offset:self._offset + 1]
+            chunk1, max1 = None, self._offset + 1
+            if max1 <= self._input_size:
+                chunk1 = self._input[self._offset:max1]
             if chunk1 is not None and Grammar.REGEX_44.search(chunk1):
-                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address2 = FAILURE
@@ -2842,17 +2847,17 @@ class Grammar:
                 if self._offset == self._failure:
                     self._expected.append('[\\d]')
             if address2 is FAILURE:
-                address2 = TreeNode(self._input[index3:index3], index3)
+                address2 = TreeNode(self._input[index3:index3], index3, [])
                 self._offset = index3
             if address2 is not FAILURE:
                 elements0.append(address2)
                 address3 = FAILURE
                 index4 = self._offset
-                chunk2 = None
-                if self._offset < self._input_size:
-                    chunk2 = self._input[self._offset:self._offset + 1]
+                chunk2, max2 = None, self._offset + 1
+                if max2 <= self._input_size:
+                    chunk2 = self._input[self._offset:max2]
                 if chunk2 is not None and Grammar.REGEX_45.search(chunk2):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -2862,7 +2867,7 @@ class Grammar:
                     if self._offset == self._failure:
                         self._expected.append('[\\d]')
                 if address3 is FAILURE:
-                    address3 = TreeNode(self._input[index4:index4], index4)
+                    address3 = TreeNode(self._input[index4:index4], index4, [])
                     self._offset = index4
                 if address3 is not FAILURE:
                     elements0.append(address3)
@@ -2892,11 +2897,11 @@ class Grammar:
         index1, elements0 = self._offset, []
         address1 = FAILURE
         index2 = self._offset
-        chunk0 = None
-        if self._offset < self._input_size:
-            chunk0 = self._input[self._offset:self._offset + 1]
+        chunk0, max0 = None, self._offset + 1
+        if max0 <= self._input_size:
+            chunk0 = self._input[self._offset:max0]
         if chunk0 is not None and Grammar.REGEX_46.search(chunk0):
-            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+            address1 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
             self._offset = self._offset + 1
         else:
             address1 = FAILURE
@@ -2906,17 +2911,17 @@ class Grammar:
             if self._offset == self._failure:
                 self._expected.append('[M]')
         if address1 is FAILURE:
-            address1 = TreeNode(self._input[index2:index2], index2)
+            address1 = TreeNode(self._input[index2:index2], index2, [])
             self._offset = index2
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
             index3 = self._offset
-            chunk1 = None
-            if self._offset < self._input_size:
-                chunk1 = self._input[self._offset:self._offset + 1]
+            chunk1, max1 = None, self._offset + 1
+            if max1 <= self._input_size:
+                chunk1 = self._input[self._offset:max1]
             if chunk1 is not None and Grammar.REGEX_47.search(chunk1):
-                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address2 = FAILURE
@@ -2926,17 +2931,17 @@ class Grammar:
                 if self._offset == self._failure:
                     self._expected.append('[\\d]')
             if address2 is FAILURE:
-                address2 = TreeNode(self._input[index3:index3], index3)
+                address2 = TreeNode(self._input[index3:index3], index3, [])
                 self._offset = index3
             if address2 is not FAILURE:
                 elements0.append(address2)
                 address3 = FAILURE
                 index4 = self._offset
-                chunk2 = None
-                if self._offset < self._input_size:
-                    chunk2 = self._input[self._offset:self._offset + 1]
+                chunk2, max2 = None, self._offset + 1
+                if max2 <= self._input_size:
+                    chunk2 = self._input[self._offset:max2]
                 if chunk2 is not None and Grammar.REGEX_48.search(chunk2):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -2946,7 +2951,7 @@ class Grammar:
                     if self._offset == self._failure:
                         self._expected.append('[\\d]')
                 if address3 is FAILURE:
-                    address3 = TreeNode(self._input[index4:index4], index4)
+                    address3 = TreeNode(self._input[index4:index4], index4, [])
                     self._offset = index4
                 if address3 is not FAILURE:
                     elements0.append(address3)
@@ -2979,16 +2984,16 @@ class Grammar:
         index3 = self._offset
         address1 = self._read_sep()
         if address1 is FAILURE:
-            address1 = TreeNode(self._input[index3:index3], index3)
+            address1 = TreeNode(self._input[index3:index3], index3, [])
             self._offset = index3
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 1]
+            chunk0, max0 = None, self._offset + 1
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 is not None and Grammar.REGEX_49.search(chunk0):
-                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address2 = FAILURE
@@ -3000,11 +3005,11 @@ class Grammar:
             if address2 is not FAILURE:
                 elements0.append(address2)
                 address3 = FAILURE
-                chunk1 = None
-                if self._offset < self._input_size:
-                    chunk1 = self._input[self._offset:self._offset + 1]
+                chunk1, max1 = None, self._offset + 1
+                if max1 <= self._input_size:
+                    chunk1 = self._input[self._offset:max1]
                 if chunk1 is not None and Grammar.REGEX_50.search(chunk1):
-                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                    address3 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                     self._offset = self._offset + 1
                 else:
                     address3 = FAILURE
@@ -3016,11 +3021,11 @@ class Grammar:
                 if address3 is not FAILURE:
                     elements0.append(address3)
                     address4 = FAILURE
-                    chunk2 = None
-                    if self._offset < self._input_size:
-                        chunk2 = self._input[self._offset:self._offset + 1]
+                    chunk2, max2 = None, self._offset + 1
+                    if max2 <= self._input_size:
+                        chunk2 = self._input[self._offset:max2]
                     if chunk2 is not None and Grammar.REGEX_51.search(chunk2):
-                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                        address4 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                         self._offset = self._offset + 1
                     else:
                         address4 = FAILURE
@@ -3032,11 +3037,11 @@ class Grammar:
                     if address4 is not FAILURE:
                         elements0.append(address4)
                         address5 = FAILURE
-                        chunk3 = None
-                        if self._offset < self._input_size:
-                            chunk3 = self._input[self._offset:self._offset + 1]
+                        chunk3, max3 = None, self._offset + 1
+                        if max3 <= self._input_size:
+                            chunk3 = self._input[self._offset:max3]
                         if chunk3 is not None and Grammar.REGEX_52.search(chunk3):
-                            address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                            address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                             self._offset = self._offset + 1
                         else:
                             address5 = FAILURE
@@ -3048,11 +3053,11 @@ class Grammar:
                         if address5 is not FAILURE:
                             elements0.append(address5)
                             address6 = FAILURE
-                            chunk4 = None
-                            if self._offset < self._input_size:
-                                chunk4 = self._input[self._offset:self._offset + 1]
+                            chunk4, max4 = None, self._offset + 1
+                            if max4 <= self._input_size:
+                                chunk4 = self._input[self._offset:max4]
                             if chunk4 is not None and Grammar.REGEX_53.search(chunk4):
-                                address6 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                address6 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                 self._offset = self._offset + 1
                             else:
                                 address6 = FAILURE
@@ -3065,11 +3070,11 @@ class Grammar:
                                 elements0.append(address6)
                                 address7 = FAILURE
                                 index4 = self._offset
-                                chunk5 = None
-                                if self._offset < self._input_size:
-                                    chunk5 = self._input[self._offset:self._offset + 1]
+                                chunk5, max5 = None, self._offset + 1
+                                if max5 <= self._input_size:
+                                    chunk5 = self._input[self._offset:max5]
                                 if chunk5 == '=':
-                                    address7 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                                    address7 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                                     self._offset = self._offset + 1
                                 else:
                                     address7 = FAILURE
@@ -3079,7 +3084,7 @@ class Grammar:
                                     if self._offset == self._failure:
                                         self._expected.append('"="')
                                 if address7 is FAILURE:
-                                    address7 = TreeNode(self._input[index4:index4], index4)
+                                    address7 = TreeNode(self._input[index4:index4], index4, [])
                                     self._offset = index4
                                 if address7 is not FAILURE:
                                     elements0.append(address7)
@@ -3110,7 +3115,7 @@ class Grammar:
             address0 = TreeNode(self._input[index2:self._offset], index2, elements0)
             self._offset = self._offset
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['altim'][index0] = (address0, self._offset)
         return address0
@@ -3127,17 +3132,17 @@ class Grammar:
         index3 = self._offset
         address1 = self._read_sep()
         if address1 is FAILURE:
-            address1 = TreeNode(self._input[index3:index3], index3)
+            address1 = TreeNode(self._input[index3:index3], index3, [])
             self._offset = index3
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
             index4 = self._offset
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 3]
+            chunk0, max0 = None, self._offset + 3
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 == 'RMK':
-                address2 = TreeNode(self._input[self._offset:self._offset + 3], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 3], self._offset, [])
                 self._offset = self._offset + 3
             else:
                 address2 = FAILURE
@@ -3150,11 +3155,11 @@ class Grammar:
                 self._offset = index4
                 remaining0, index5, elements1, address3 = 0, self._offset, [], True
                 while address3 is not FAILURE:
-                    chunk1 = None
-                    if self._offset < self._input_size:
-                        chunk1 = self._input[self._offset:self._offset + 5]
+                    chunk1, max1 = None, self._offset + 5
+                    if max1 <= self._input_size:
+                        chunk1 = self._input[self._offset:max1]
                     if chunk1 == 'NOSIG':
-                        address3 = TreeNode(self._input[self._offset:self._offset + 5], self._offset)
+                        address3 = TreeNode(self._input[self._offset:self._offset + 5], self._offset, [])
                         self._offset = self._offset + 5
                     else:
                         address3 = FAILURE
@@ -3179,7 +3184,7 @@ class Grammar:
                 remaining1, index6, elements2, address5 = 0, self._offset, [], True
                 while address5 is not FAILURE:
                     if self._offset < self._input_size:
-                        address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                        address5 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                         self._offset = self._offset + 1
                     else:
                         address5 = FAILURE
@@ -3213,7 +3218,7 @@ class Grammar:
             address0 = TreeNode(self._input[index2:self._offset], index2, elements0)
             self._offset = self._offset
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['remarks'][index0] = (address0, self._offset)
         return address0
@@ -3230,16 +3235,16 @@ class Grammar:
         index3 = self._offset
         address1 = self._read_sep()
         if address1 is FAILURE:
-            address1 = TreeNode(self._input[index3:index3], index3)
+            address1 = TreeNode(self._input[index3:index3], index3, [])
             self._offset = index3
         if address1 is not FAILURE:
             elements0.append(address1)
             address2 = FAILURE
-            chunk0 = None
-            if self._offset < self._input_size:
-                chunk0 = self._input[self._offset:self._offset + 1]
+            chunk0, max0 = None, self._offset + 1
+            if max0 <= self._input_size:
+                chunk0 = self._input[self._offset:max0]
             if chunk0 == '=':
-                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset)
+                address2 = TreeNode(self._input[self._offset:self._offset + 1], self._offset, [])
                 self._offset = self._offset + 1
             else:
                 address2 = FAILURE
@@ -3262,7 +3267,7 @@ class Grammar:
             address0 = TreeNode(self._input[index2:self._offset], index2, elements0)
             self._offset = self._offset
         if address0 is FAILURE:
-            address0 = TreeNode(self._input[index1:index1], index1)
+            address0 = TreeNode(self._input[index1:index1], index1, [])
             self._offset = index1
         self._cache['end'][index0] = (address0, self._offset)
         return address0
diff --git a/src/metpy/io/metar.py b/src/metpy/io/metar.py
index 83deaa53d7..8ab8bb1c50 100644
--- a/src/metpy/io/metar.py
+++ b/src/metpy/io/metar.py
@@ -10,8 +10,8 @@ import warnings
 import numpy as np
 import pandas as pd
 
+from ._metar_parser.metar_parser import parse, ParseError
 from ._tools import open_as_needed
-from .metar_parser import parse, ParseError
 from .station_data import station_info
 from ..package_tools import Exporter
 from ..units import units
diff --git a/src/metpy/io/nexrad.py b/src/metpy/io/nexrad.py
index 35f678a38d..d016b7040d 100644
--- a/src/metpy/io/nexrad.py
+++ b/src/metpy/io/nexrad.py
@@ -11,7 +11,6 @@ import logging
 import pathlib
 import re
 import struct
-from struct import Struct
 from xdrlib import Unpacker
 
 import numpy as np
@@ -451,7 +450,7 @@ class Level2File:
     def _decode_msg13(self, msg_hdr):
         data = self._buffer_segment(msg_hdr)
         if data:
-            data = Struct(f'>{len(data) // 2:d}h').unpack(data)
+            data = struct.Struct(f'>{len(data) // 2:d}h').unpack(data)
             # Legacy format doesn't have date/time and has fewer azimuths
             if data[0] <= 5:
                 num_el = data[0]
@@ -494,7 +493,7 @@ class Level2File:
         # will be returned concatenated when this is the case
         data = self._buffer_segment(msg_hdr)
         if data:
-            date, time, num_el, *data = Struct(f'>{len(data) // 2:d}h').unpack(data)
+            date, time, num_el, *data = struct.Struct(f'>{len(data) // 2:d}h').unpack(data)
             if num_el == 0:
                 log.info('Message 15 num_el is 0--likely legacy clutter filter notch width. '
                          'Skipping...')
@@ -665,6 +664,8 @@ class Level2File:
         if msg_hdr.num_segments == len(bufs):
             self._msg_buf.pop(msg_hdr.msg_type)
             return b''.join(bytes(item[1]) for item in sorted(bufs.items()))
+        else:
+            return None
 
     def _add_sweep(self, hdr):
         if not self.sweeps and not hdr.rad_status & START_VOLUME:
@@ -1754,6 +1755,7 @@ class Level3File:
                 self._buffer.splice(comp_start, decomp_data)
                 assert self._buffer.check_remains(self.metadata['uncompressed_size'])
             except OSError:
+                # Compression didn't work, so we just assume it wasn't actually compressed.
                 pass
 
         # Unpack the various blocks, if present. The factor of 2 converts from
diff --git a/src/metpy/pandas.py b/src/metpy/pandas.py
index b32bd31ec1..5fe4811bea 100644
--- a/src/metpy/pandas.py
+++ b/src/metpy/pandas.py
@@ -3,12 +3,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 """Provide accessors to enhance interoperability between Pandas and MetPy."""
 import functools
-import logging
 
 import pandas as pd
 
 __all__ = []
-log = logging.getLogger(__name__)
 
 
 def preprocess_pandas(func):
diff --git a/src/metpy/plots/cartopy_utils.py b/src/metpy/plots/cartopy_utils.py
index 55101052c5..56bf4ab608 100644
--- a/src/metpy/plots/cartopy_utils.py
+++ b/src/metpy/plots/cartopy_utils.py
@@ -75,6 +75,6 @@ def import_cartopy():
 class CartopyStub:
     """Fail if a CartoPy attribute is accessed."""
 
-    def __getattr__(self, item):
+    def __getattr__(self, name):
         """Raise an error on any attribute access."""
-        raise RuntimeError(f'CartoPy is required to use this feature ({item}).')
+        raise AttributeError(f'Cannot use {name} without Cartopy installed.')
diff --git a/src/metpy/plots/wx_symbols.py b/src/metpy/plots/wx_symbols.py
index c91a621309..909f75f1be 100644
--- a/src/metpy/plots/wx_symbols.py
+++ b/src/metpy/plots/wx_symbols.py
@@ -63,6 +63,7 @@ def wx_code_to_numeric(codes):
                     wx_sym_list.append(wx_code_map[wxcode[opt]])
                     break
                 except KeyError:
+                    # That option didn't work--move on.
                     pass
             else:
                 wx_sym_list.append(0)


Test patch:
diff --git a/tests/calc/test_basic.py b/tests/calc/test_basic.py
index 7a4e915ae0..77aa5f8426 100644
--- a/tests/calc/test_basic.py
+++ b/tests/calc/test_basic.py
@@ -317,41 +317,6 @@ def test_geopotential_to_height_32bit():
     assert_almost_equal(geopotential_to_height(geopot), truth, 2)
 
 
-# class TestIrrad(object):
-#    def test_basic(self):
-#        'Test the basic solar irradiance calculation.'
-#        from datetime import date
-
-#        d = date(2008, 9, 28)
-#        lat = 35.25
-#        hours = np.linspace(6,18,10)
-
-#        s = solar_irradiance(lat, d, hours)
-#        values = np.array([0., 344.1, 682.6, 933.9, 1067.6, 1067.6, 933.9,
-#            682.6, 344.1, 0.])
-#        assert_array_almost_equal(s, values, 1)
-
-#    def test_scalar(self):
-#        from datetime import date
-#        d = date(2008, 9, 28)
-#        lat = 35.25
-#        hour = 9.5
-#        s = solar_irradiance(lat, d, hour)
-#        assert_almost_equal(s, 852.1, 1)
-
-#    def test_invalid(self):
-#        'Test for values that should be masked.'
-#        from datetime import date
-#        d = date(2008, 9, 28)
-#        lat = 35.25
-#        hours = np.linspace(0,22,12)
-#        s = solar_irradiance(lat, d, hours)
-
-#        mask = np.array([ True,  True,  True,  True, False, False, False,
-#            False, False, True,  True,  True])
-#        assert_array_equal(s.mask, mask)
-
-
 def test_pressure_to_heights_basic():
     """Test basic pressure to height calculation for standard atmosphere."""
     pressures = np.array([975.2, 987.5, 956., 943.]) * units.mbar
diff --git a/tests/plots/test_cartopy_utils.py b/tests/plots/test_cartopy_utils.py
index e2ed5122f8..aa96604c5f 100644
--- a/tests/plots/test_cartopy_utils.py
+++ b/tests/plots/test_cartopy_utils.py
@@ -80,7 +80,7 @@ def test_cartopy_stub(monkeypatch):
     monkeypatch.setitem(sys.modules, 'cartopy.crs', None)
 
     ccrs = cartopy_utils.import_cartopy()
-    with pytest.raises(RuntimeError, match='CartoPy is required'):
+    with pytest.raises(AttributeError, match='without Cartopy'):
         ccrs.PlateCarree()
 
 
diff --git a/tests/test_xarray.py b/tests/test_xarray.py
index 9dd4ed8b3b..dc5012858d 100644
--- a/tests/test_xarray.py
+++ b/tests/test_xarray.py
@@ -1069,8 +1069,8 @@ def test_update_attribute_dictionary(test_ds_generic):
 def test_update_attribute_callable(test_ds_generic):
     """Test update_attribute using callable."""
     def even_ascii(varname, **kwargs):
-        if ord(varname[0]) % 2 == 0:
-            return 'yes'
+        return 'yes' if ord(varname[0]) % 2 == 0 else None
+
     result = test_ds_generic.metpy.update_attribute('even', even_ascii)
 
     # Test attribute updates