changeset 52:bc662ab63361 draft

Introduce new guarantee (None leaves state untouched) and remove many holds
author Lewin Bormann <lbo@spheniscida.de>
date Fri, 24 May 2019 00:07:15 +0200
parents f5cfdd80cfe7
children 2202ec2712c8
files pcombinators/combinators.py
diffstat 1 files changed, 5 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/pcombinators/combinators.py	Thu May 23 22:56:33 2019 +0200
+++ b/pcombinators/combinators.py	Fri May 24 00:07:15 2019 +0200
@@ -15,6 +15,8 @@
     def parse(self, st):
         """Call parse() on any class inheriting from this one. It will consume
         the ParseState st and return the parse result (depending on the parsers used).
+
+        None indicates a failed parse. In this case, st must be returned with unmodified position.
         """
         return (None, st)
 
@@ -64,17 +66,13 @@
         self._transform = tf
 
     def parse(self, st):
-        hold = st.hold()
         r, st2 = self._inner.parse(st)
         if r is None:
-            st.reset(hold)
             return None, st
         try:
             r2 = self._transform(r)
-            st2.release(hold)
             return r2, st2
         except Exception as e:
-            st.reset(hold)
             raise Exception('{} (at {} (col {}))'.format(e, st, st.index()))
 
 class _Sequence(Parser):
@@ -99,12 +97,10 @@
 
     def parse(self, st):
         results = []
-        hold = st.hold()
+        hold = st.hold() if self._atomic else None
         for p in self._parsers:
-            before = st.hold()
             result, st2 = p.parse(st)
             if result is None:
-                st.reset(before)
                 if self._atomic:
                     st.reset(hold)
                     return None, st
@@ -112,8 +108,8 @@
             if result is not SKIP_MARKER:
                 results.append(result)
             st = st2
-            st.release(before)
-        st.release(hold)
+        if self._atomic:
+            st.release(hold)
         return results, st2