[pypy-svn] r44374 - in pypy/dist/pypy/rlib/parsing: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Jun 19 15:50:36 CEST 2007


Author: cfbolz
Date: Tue Jun 19 15:50:36 2007
New Revision: 44374

Modified:
   pypy/dist/pypy/rlib/parsing/regex.py
   pypy/dist/pypy/rlib/parsing/test/test_regex.py
Log:
add negation of regular expressions


Modified: pypy/dist/pypy/rlib/parsing/regex.py
==============================================================================
--- pypy/dist/pypy/rlib/parsing/regex.py	(original)
+++ pypy/dist/pypy/rlib/parsing/regex.py	Tue Jun 19 15:50:36 2007
@@ -1,3 +1,4 @@
+import string
 from pypy.rlib.parsing.deterministic import NFA
 
 class RegularExpression(object):
@@ -16,6 +17,9 @@
     def __pos__(self):
         return AddExpression(self, self.kleene())
 
+    def __invert__(self):
+        return NotExpression(self)
+
     def kleene(self):
         return KleeneClosure(self)
 
@@ -153,6 +157,26 @@
     def __repr__(self):
         return "OrExpression(%r, %r)" % (self.rega, self.regb)
 
+class NotExpression(RegularExpression):
+    def __init__(self, reg):
+        self.reg = reg
+
+    def make_automaton(self):
+        nfa = self.reg.make_automaton()
+        # add error state
+        error = nfa.add_state("error")
+        for state in range(nfa.num_states):
+            occurring = set(nfa.transitions.get(state, {}).keys())
+            toerror = set([chr(i) for i in range(256)]) - occurring
+            for input in toerror:
+                nfa.add_transition(state, error, input)
+        nfa.final_states = set(range(nfa.num_states)) - nfa.final_states
+        return nfa
+
+    def __invert__(self):
+        return self.reg
+
+
 class LexingOrExpression(RegularExpression):
     def __init__(self, regs, names):
         self.regs = regs
@@ -188,3 +212,5 @@
 
     def __repr__(self):
         return "LexingOrExpression(%r, %r)" % (self.regs, self.names)
+
+

Modified: pypy/dist/pypy/rlib/parsing/test/test_regex.py
==============================================================================
--- pypy/dist/pypy/rlib/parsing/test/test_regex.py	(original)
+++ pypy/dist/pypy/rlib/parsing/test/test_regex.py	Tue Jun 19 15:50:36 2007
@@ -137,6 +137,17 @@
     assert fn("a")
     assert fn("aaaaaAAAAaAAzAzaslwer")
 
+def test_not():
+    r = NotExpression(StringExpression("a"))
+    nda = r.make_automaton()
+    fda = nda.make_deterministic()
+    fda.view()
+    r = fda.get_runner()
+    assert not r.recognize("a")
+    assert r.recognize("b")
+    assert r.recognize("bbbbbbbb")
+    assert r.recognize("arstiow2ie34nvarstbbbbbbbb")
+
 def test_empty():
     a = StringExpression("a")
     empty = StringExpression("")



More information about the Pypy-commit mailing list