Commit 7ccc8080 authored by Stefan Behnel's avatar Stefan Behnel

Compile DFA.py and tie it into the other lexer classes.

parent 78aa444d
# cython:
cimport cython
from . cimport Machines
from .Transitions cimport TransitionMap
@cython.final
cdef class StateMap:
cdef Machines.FastMachine new_machine
cdef dict old_to_new_dict
cdef dict new_to_old_dict
cdef old_to_new(self, dict old_state_set)
@cython.locals(state=Machines.Node)
cdef highest_priority_action(self, dict state_set)
cdef make_key(self, dict state_set)
@cython.locals(new_machine=Machines.FastMachine, transitions=TransitionMap)
cpdef nfa_to_dfa(Machines.Machine old_machine, debug=*)
cdef set_epsilon_closure(dict state_set)
cdef dict epsilon_closure(Machines.Node state)
@cython.locals(state_set_2=dict, state2=Machines.Node)
cdef add_to_epsilon_closure(dict state_set, Machines.Node state)
# cython: auto_cpdef=True
""" """
Python Lexical Analyser Python Lexical Analyser
...@@ -95,14 +96,11 @@ class StateMap(object): ...@@ -95,14 +96,11 @@ class StateMap(object):
Helper class used by nfa_to_dfa() to map back and forth between Helper class used by nfa_to_dfa() to map back and forth between
sets of states from the old machine and states of the new machine. sets of states from the old machine and states of the new machine.
""" """
new_machine = None # Machine
old_to_new_dict = None # {(old_state,...) : new_state}
new_to_old_dict = None # {id(new_state) : old_state_set}
def __init__(self, new_machine): def __init__(self, new_machine):
self.new_machine = new_machine self.new_machine = new_machine # Machine
self.old_to_new_dict = {} self.old_to_new_dict = {} # {(old_state,...) : new_state}
self.new_to_old_dict = {} self.new_to_old_dict = {} # {id(new_state) : old_state_set}
def old_to_new(self, old_state_set): def old_to_new(self, old_state_set):
""" """
...@@ -140,9 +138,7 @@ class StateMap(object): ...@@ -140,9 +138,7 @@ class StateMap(object):
Convert a set of states into a uniquified Convert a set of states into a uniquified
sorted tuple suitable for use as a dictionary key. sorted tuple suitable for use as a dictionary key.
""" """
lst = list(state_set) return tuple(sorted(state_set))
lst.sort()
return tuple(lst)
def dump(self, file): def dump(self, file):
from .Transitions import state_set_str from .Transitions import state_set_str
......
cimport cython cimport cython
from .Actions cimport Action
from .Transitions cimport TransitionMap
@cython.final
cdef class Machine:
cdef readonly list states
cdef readonly dict initial_states
cdef readonly Py_ssize_t next_state_number
cpdef new_state(self)
cpdef new_initial_state(self, name)
@cython.final @cython.final
cdef class Node: cdef class Node:
cdef readonly object transitions # TransitionMap cdef readonly TransitionMap transitions
cdef readonly object action # Action cdef readonly Action action
cdef public object epsilon_closure # dict cdef public dict epsilon_closure
cdef readonly Py_ssize_t number cdef readonly Py_ssize_t number
cdef readonly long action_priority cdef readonly long action_priority
......
...@@ -24,13 +24,10 @@ LOWEST_PRIORITY = -maxint ...@@ -24,13 +24,10 @@ LOWEST_PRIORITY = -maxint
class Machine(object): class Machine(object):
"""A collection of Nodes representing an NFA or DFA.""" """A collection of Nodes representing an NFA or DFA."""
states = None # [Node]
next_state_number = 1
initial_states = None # {(name, bol): Node}
def __init__(self): def __init__(self):
self.states = [] self.states = [] # [Node]
self.initial_states = {} self.initial_states = {} # {(name, bol): Node}
self.next_state_number = 1
def __del__(self): def __del__(self):
for state in self.states: for state in self.states:
......
cimport cython
cdef long maxint
@cython.final
cdef class TransitionMap:
cdef list map
cdef dict special
@cython.locals(i=cython.Py_ssize_t, j=cython.Py_ssize_t)
cpdef add(self, event, new_state)
@cython.locals(i=cython.Py_ssize_t, j=cython.Py_ssize_t)
cpdef add_set(self, event, new_set)
@cython.locals(i=cython.Py_ssize_t, n=cython.Py_ssize_t, else_set=cython.bint)
cpdef iteritems(self)
@cython.locals(map=list, lo=cython.Py_ssize_t, mid=cython.Py_ssize_t, hi=cython.Py_ssize_t)
cdef split(self, long code)
cdef get_special(self, event)
...@@ -5,18 +5,12 @@ This version represents state sets directly as dicts for speed. ...@@ -5,18 +5,12 @@ This version represents state sets directly as dicts for speed.
""" """
from __future__ import absolute_import from __future__ import absolute_import
import cython
cython.declare(maxint=cython.long)
try: try:
from sys import maxsize as maxint from sys import maxsize as maxint
except ImportError: except ImportError:
from sys import maxint from sys import maxint
@cython.final
@cython.cclass
class TransitionMap(object): class TransitionMap(object):
""" """
A TransitionMap maps an input event to a set of states. A TransitionMap maps an input event to a set of states.
...@@ -45,8 +39,6 @@ class TransitionMap(object): ...@@ -45,8 +39,6 @@ class TransitionMap(object):
kept separately in a dictionary. kept separately in a dictionary.
""" """
cython.declare(map=list, special=dict)
def __init__(self, map=None, special=None): def __init__(self, map=None, special=None):
if not map: if not map:
map = [-maxint, {}, maxint] map = [-maxint, {}, maxint]
...@@ -55,7 +47,6 @@ class TransitionMap(object): ...@@ -55,7 +47,6 @@ class TransitionMap(object):
self.map = map # The list of codes and states self.map = map # The list of codes and states
self.special = special # Mapping for special events self.special = special # Mapping for special events
@cython.locals(i=cython.Py_ssize_t, j=cython.Py_ssize_t, map=list)
def add(self, event, new_state): def add(self, event, new_state):
""" """
Add transition to |new_state| on |event|. Add transition to |new_state| on |event|.
...@@ -71,7 +62,6 @@ class TransitionMap(object): ...@@ -71,7 +62,6 @@ class TransitionMap(object):
else: else:
self.get_special(event)[new_state] = 1 self.get_special(event)[new_state] = 1
@cython.locals(i=cython.Py_ssize_t, j=cython.Py_ssize_t, map=list)
def add_set(self, event, new_set): def add_set(self, event, new_set):
""" """
Add transitions to the states in |new_set| on |event|. Add transitions to the states in |new_set| on |event|.
...@@ -93,7 +83,6 @@ class TransitionMap(object): ...@@ -93,7 +83,6 @@ class TransitionMap(object):
""" """
return self.special.get('') return self.special.get('')
@cython.locals(map=list, i=cython.Py_ssize_t, n=cython.Py_ssize_t, else_set=cython.bint)
def iteritems(self): def iteritems(self):
""" """
Return the mapping as an iterable of ((code1, code2), state_set) and Return the mapping as an iterable of ((code1, code2), state_set) and
...@@ -121,8 +110,6 @@ class TransitionMap(object): ...@@ -121,8 +110,6 @@ class TransitionMap(object):
# ------------------- Private methods -------------------- # ------------------- Private methods --------------------
@cython.ccall
@cython.locals(map=list, lo=cython.Py_ssize_t, mid=cython.Py_ssize_t, hi=cython.Py_ssize_t, code=cython.long)
def split(self, code): def split(self, code):
""" """
Search the list for the position of the split point for |code|, Search the list for the position of the split point for |code|,
...@@ -153,7 +140,6 @@ class TransitionMap(object): ...@@ -153,7 +140,6 @@ class TransitionMap(object):
map[hi:hi] = [code, map[hi - 1].copy()] map[hi:hi] = [code, map[hi - 1].copy()]
return hi return hi
@cython.ccall
def get_special(self, event): def get_special(self, event):
""" """
Get state set for special event, adding a new entry if necessary. Get state set for special event, adding a new entry if necessary.
......
...@@ -86,6 +86,7 @@ def compile_cython_modules(profile=False, compile_more=False, cython_with_refnan ...@@ -86,6 +86,7 @@ def compile_cython_modules(profile=False, compile_more=False, cython_with_refnan
"Cython.Plex.Actions", "Cython.Plex.Actions",
"Cython.Plex.Machines", "Cython.Plex.Machines",
"Cython.Plex.Transitions", "Cython.Plex.Transitions",
"Cython.Plex.DFA",
"Cython.Compiler.Scanning", "Cython.Compiler.Scanning",
"Cython.Compiler.Visitor", "Cython.Compiler.Visitor",
"Cython.Compiler.FlowControl", "Cython.Compiler.FlowControl",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment