[pypy-svn] r33962 - in pypy/dist/pypy: jit/timeshifter/test lang/automata lang/automata/test
rxe at codespeak.net
rxe at codespeak.net
Tue Oct 31 16:05:20 CET 2006
Author: rxe
Date: Tue Oct 31 16:05:15 2006
New Revision: 33962
Added:
pypy/dist/pypy/lang/automata/ (props changed)
pypy/dist/pypy/lang/automata/__init__.py (contents, props changed)
pypy/dist/pypy/lang/automata/dfa.py (contents, props changed)
pypy/dist/pypy/lang/automata/test/ (props changed)
pypy/dist/pypy/lang/automata/test/test_dfa.py (contents, props changed)
Modified:
pypy/dist/pypy/jit/timeshifter/test/test_portal.py
Log:
add a first and extremely hackish attempt at a dfa engine, with a failing test to jit/.../test_portal.py - (arigo, rxe)
Modified: pypy/dist/pypy/jit/timeshifter/test/test_portal.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_portal.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_portal.py Tue Oct 31 16:05:15 2006
@@ -9,6 +9,7 @@
from pypy.rpython.objectmodel import hint
+import py.test
class TestPortal(object):
from pypy.jit.codegen.llgraph.rgenop import RGenOp
@@ -115,3 +116,15 @@
policy=P_NOVIRTUAL)
assert res == 68
self.check_insns(int_floordiv=1, int_mul=0)
+
+ def test_dfa_compile(self):
+ py.test.skip("fails with debug_fatalerror() for some unknown reason")
+ from pypy.lang.automata.dfa import getautomaton, convertdfa, recognizetable
+ def main(gets):
+ a = getautomaton()
+ dfatable = convertdfa(a)
+ s = ["aaaaaaaaaab", "aaaa"][gets]
+ return recognizetable(dfatable, s)
+
+ res = self.timeshift_from_portal(main, recognizetable, [0], policy=P_NOVIRTUAL)
+ assert res >= 0
Added: pypy/dist/pypy/lang/automata/__init__.py
==============================================================================
Added: pypy/dist/pypy/lang/automata/dfa.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lang/automata/dfa.py Tue Oct 31 16:05:15 2006
@@ -0,0 +1,143 @@
+" a very stripped down versio of cfbolz's algorithm/automaton module "
+
+from pypy.rpython.objectmodel import hint
+from pypy.rpython.lltypesystem.lltype import GcArray, Signed, malloc
+
+class LexerError(Exception):
+ def __init__(self, input, state, index):
+ self.input = input
+ self.state = state
+ self.index = index
+ self.args = (input, state, index)
+
+class DFA(object):
+ def __init__(self, num_states=0, transitions=None, final_states=None,
+ names=None):
+ self.num_states = 0
+ if transitions is None:
+ transitions = {}
+ if final_states is None:
+ final_states = {}
+ if names is None:
+ names = []
+ self.transitions = transitions
+ self.final_states = final_states
+ self.names = names
+
+ def __repr__(self):
+ from pprint import pformat
+ return "DFA%s" % (pformat((
+ self.num_states, self.transitions, self.final_states,
+ self.names)), )
+
+ def add_state(self, name=None, final=False):
+ state = self.num_states
+ self.num_states += 1
+ if final:
+ self.final_states[state] = None
+ if name is None:
+ name = str(state)
+ self.names.append(name)
+ return self.num_states - 1
+
+ def add_transition(self, state, input, next_state):
+ self.transitions[state, input] = next_state
+
+ def get_transition(self, state, input):
+ return self.transitions[state, input]
+
+ def contains(self, (state, input)):
+ return (state, input) in self.transitions
+
+ def get_all_chars(self):
+ all_chars = {}
+ for state, input in self.transitions:
+ all_chars.add(input)
+ return all_chars
+
+ def get_runner(self):
+ return DFARunner(self)
+
+def getautomaton():
+ # simple example of handcrafted dfa
+ a = DFA()
+ s0 = a.add_state("start")
+ s1 = a.add_state()
+ s2 = a.add_state(final=True)
+ a.add_transition(s0, "a", s0)
+ a.add_transition(s0, "c", s1)
+ a.add_transition(s0, "b", s2)
+ a.add_transition(s1, "b", s2)
+ return a
+
+def recognize(automaton, s):
+ state = 0
+ try:
+ for char in s:
+ state = automaton.get_transition(state, char)
+ except KeyError:
+ return False
+
+ return state in automaton.final_states
+
+#________________________________________________________________________________
+
+# lower level version - more amenable to JIT
+
+# an earlier version to keep around, based of GcArray
+
+# A = GcArray(Signed, hints={'immutable': True})
+# def convertdfa(automaton):
+# automaton.transitions
+# size = automaton.num_states * 256
+# dfatable = malloc(A, size)
+# for ii in range(size):
+# dfatable[ii] = -1
+# for (s, c), r in automaton.transitions.items():
+# dfatable[s * 256 + ord(c)] = r
+# return dfatable
+
+# def recognizetable(dfatable, s):
+# state = 0
+# indx = 0
+# while True:
+# hint(None, global_merge_point=True)
+# if indx >= len(s):
+# break
+# c = s[indx]
+# c = hint(c, promote=True)
+# state = dfatable[state * 256 + ord(c)]
+# hint(state, concrete=True)
+# if state < 0:
+# break
+# indx += 1
+# return hint(state, variable=True)
+
+#________________________________________________________________________________
+
+# another lower level version - more amenable to JIT, this time converts
+# nice automata class to a table, represented as a big string
+
+def convertdfa(automaton):
+ automaton.transitions
+ size = automaton.num_states * 256
+ dfatable = [chr(255)] * size
+ for (s, c), r in automaton.transitions.items():
+ dfatable[s * 256 + ord(c)] = chr(r)
+ return "".join(dfatable)
+
+def recognizetable(dfatable, s):
+ state = 0
+ indx = 0
+ while True:
+ hint(None, global_merge_point=True)
+ if indx >= len(s):
+ break
+ c = s[indx]
+ c = hint(c, promote=True)
+ state = ord(dfatable[state * 256 + ord(c)])
+ hint(state, concrete=True)
+ if state == 255:
+ break
+ indx += 1
+ return hint(state, variable=True)
Added: pypy/dist/pypy/lang/automata/test/test_dfa.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lang/automata/test/test_dfa.py Tue Oct 31 16:05:15 2006
@@ -0,0 +1,93 @@
+import py
+from pypy import conftest
+
+from pypy.rpython.test.test_llinterp import interpret
+from pypy.translator.translator import graphof
+from pypy.jit.timeshifter.test.test_timeshift import hannotate
+from pypy.jit.timeshifter.rtyper import HintRTyper
+from pypy.jit.timeshifter.test.test_timeshift import P_NOVIRTUAL
+from pypy.rpython.llinterp import LLInterpreter
+from pypy.objspace.flow.model import checkgraph
+from pypy.rpython.objectmodel import hint
+
+from pypy.lang.automata.dfa import *
+
+def rundfa():
+ a = getautomaton()
+ assert recognize(a, "aaaaaaaaaab")
+ assert recognize(a, "b")
+ assert not recognize(a, "a")
+ assert not recognize(a, "xyza")
+ assert recognize(a, "aaaacb")
+
+def test_dfa_simple():
+ rundfa()
+
+def test_dfa_interp():
+ interpret(rundfa, [])
+
+def test_dfa_compiledummy():
+ def main(gets):
+ a = getautomaton()
+ dfatable = convertdfa(a)
+ s = ["aaaaaaaaaab", "aaaa"][gets]
+ return recognizetable(dfatable, s)
+
+ interpret(main, [0])
+
+# class TestWithPortal(object):
+# from pypy.jit.codegen.llgraph.rgenop import RGenOp
+
+# def setup_class(cls):
+# cls._cache = {}
+# cls._cache_order = []
+
+# def teardown_class(cls):
+# del cls._cache
+# del cls._cache_order
+
+# def timeshift_from_portal(self, main, portal, main_args,
+# inline=None, policy=None,
+# backendoptimize=False):
+
+# key = main, portal, inline, policy, backendoptimize
+# try:
+# maingraph, rtyper = self._cache[key]
+# except KeyError:
+# if len(self._cache_order) >= 3:
+# del self._cache[self._cache_order.pop(0)]
+
+# hs, ha, rtyper = hannotate(main, main_args, portal=portal,
+# policy=policy, inline=inline,
+# backendoptimize=backendoptimize)
+
+# t = rtyper.annotator.translator
+# maingraph = graphof(t, main)
+# # make the timeshifted graphs
+# hrtyper = HintRTyper(ha, rtyper, self.RGenOp)
+# origportalgraph = graphof(t, portal)
+# hrtyper.specialize(origportalgraph=origportalgraph,
+# view = conftest.option.view)
+
+# for graph in ha.translator.graphs:
+# checkgraph(graph)
+# t.graphs.append(graph)
+
+# if conftest.option.view:
+# t.view()
+
+# self._cache[key] = maingraph, rtyper
+# self._cache_order.append(key)
+
+# llinterp = LLInterpreter(rtyper)
+# return llinterp.eval_graph(maingraph, main_args)
+
+# def test_dfa_compile(self):
+# def main(gets):
+# a = getautomaton()
+# dfatable = convertdfa(a)
+# s = ["aaaaaaaaaab", "aaaa"][gets]
+# return recognizetable(dfatable, s)
+
+# res = self.timeshift_from_portal(main, recognizetable, [0], policy=P_NOVIRTUAL)
+# assert res >= 0
More information about the Pypy-commit
mailing list