Revision: 17618
Author:   [email protected]
Date:     Mon Nov 11 14:22:00 2013 UTC
Log:      Experimental lexer generator: Code generator skeleton.

[email protected]
BUG=

Review URL: https://codereview.chromium.org/68803002
http://code.google.com/p/v8/source/detail?r=17618

Modified:
 /branches/experimental/parser/tools/lexer_generator/dfa.py
 /branches/experimental/parser/tools/lexer_generator/generator.py
 /branches/experimental/parser/tools/lexer_generator/transition_keys.py

=======================================
--- /branches/experimental/parser/tools/lexer_generator/dfa.py Mon Nov 11 07:52:15 2013 UTC +++ /branches/experimental/parser/tools/lexer_generator/dfa.py Mon Nov 11 14:22:00 2013 UTC
@@ -53,19 +53,36 @@
   def transitions(self):
     return self.__transitions

+  def to_code(self):
+    # FIXME: add different check types (if, switch, lookup table)
+    # FIXME: add action + break / continue
+    # FIXME: add default action
+    code = '''
+code_%s:
+fprintf(stderr, "state %s, char at hand is %%c\\n", c);
+''' % (self.node_number(), self.node_number())
+
+    for key, state in self.__transitions.items():
+      code += key.to_code()
+      code += ''' {
+  c = *(++cursor);
+  goto code_%s;
+}''' % state.node_number()
+    return code
+
 class Dfa(Automaton):

   def __init__(self, start_name, mapping):
     super(Dfa, self).__init__()
     self.__terminal_set = set()
-    name_map = {}
+    self.__name_map = {}
     for i, (name, node_data) in enumerate(mapping.items()):
       node = DfaState(name, i, node_data['actions'])
-      name_map[name] = node
+      self.__name_map[name] = node
       if node_data['terminal']:
         self.__terminal_set.add(node)
     for name, node_data in mapping.items():
-      node = name_map[name]
+      node = self.__name_map[name]
       inversion = {}
       for key, state in node_data['transitions'].items():
         if not state in inversion:
@@ -73,8 +90,8 @@
         inversion[state].append(key)
       for state, keys in inversion.items():
         merged_key = TransitionKey.merged_key(keys)
-        node.add_transition(merged_key, name_map[state])
-    self.__start = name_map[start_name]
+        node.add_transition(merged_key, self.__name_map[state])
+    self.__start = self.__name_map[start_name]
     assert self.__terminal_set

   @staticmethod
@@ -127,3 +144,12 @@
iterator = lambda visitor, state: self.__visit_all_edges(visitor, state)
     state_iterator = lambda x : [x]
return self.generate_dot(self.__start, self.__terminal_set, iterator, state_iterator)
+
+  def to_code(self):
+    code = '''
+char c = *cursor;
+goto code_%s;
+''' % (self.__start.node_number())
+    for n in self.__name_map.values():
+      code += n.to_code()
+    return code
=======================================
--- /branches/experimental/parser/tools/lexer_generator/generator.py Mon Nov 11 12:28:48 2013 UTC +++ /branches/experimental/parser/tools/lexer_generator/generator.py Mon Nov 11 14:22:00 2013 UTC
@@ -134,12 +134,17 @@
     (nfa, dfa) = self.__automata['default']
     return dfa.lex(string)

+  def generate_code(self):
+    (nfa, dfa) = self.__automata['default']
+    return dfa.to_code()
+
 if __name__ == '__main__':

   parser = argparse.ArgumentParser()
   parser.add_argument('--html')
   parser.add_argument('--re', default='src/lexer/lexer_py.re')
   parser.add_argument('--input')
+  parser.add_argument('--code')
   args = parser.parse_args()

   re_file = args.re
@@ -155,6 +160,13 @@
       f.write(html)
       print "wrote html to %s" % html_file

+  code_file = args.code
+  if code_file:
+    code = generator.generate_code()
+    with open(code_file, 'w') as f:
+      f.write(code)
+      print "wrote code to %s" % code_file
+
   input_file = args.input
   if input_file:
     with open(input_file, 'r') as f:
=======================================
--- /branches/experimental/parser/tools/lexer_generator/transition_keys.py Fri Nov 8 14:05:26 2013 UTC +++ /branches/experimental/parser/tools/lexer_generator/transition_keys.py Mon Nov 11 14:22:00 2013 UTC
@@ -175,6 +175,20 @@
   def __eq__(self, other):
return isinstance(other, self.__class__) and self.__ranges == other.__ranges

+  def to_code(self):
+    code = 'if ('
+    first = True
+    for r in self.__ranges:
+      if not first:
+        code += ' || '
+      if r[0] == r[1]:
+        code += 'c == %s' % r[0]
+      else:
+        code += '(c >= %s && c <= %s)' % (r[0], r[1])
+      first = False
+    code += ')'
+    return code
+
   __printable_cache = {
     ord('\t') : '\\t',
     ord('\n') : '\\n',

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to