Reviewers: dcarney,

Message:
Committed patchset #2 manually as r18667 (presubmit successful).

Description:
Experimental parser: visualize rule trees.

[email protected]
BUG=

Committed: https://code.google.com/p/v8/source/detail?r=18667

Please review this at https://codereview.chromium.org/141293003/

SVN Base: https://v8.googlecode.com/svn/branches/experimental/parser

Affected files (+64, -1 lines):
  M tools/lexer_generator/generator.py
  M tools/lexer_generator/nfa_builder.py
  M tools/lexer_generator/rule_parser.py


Index: tools/lexer_generator/generator.py
diff --git a/tools/lexer_generator/generator.py b/tools/lexer_generator/generator.py index c1efba7318c84bd2b1a28ae590b7b05062e25bf5..8ed2fef731384f9c7e8d7a7f75f394b3b15b88ec 100644
--- a/tools/lexer_generator/generator.py
+++ b/tools/lexer_generator/generator.py
@@ -80,7 +80,18 @@ def generate_html(rule_processor, minimize_default):
     if mdfa and mdfa.node_count() != dfa.node_count():
       scripts.append(script_template % (mdfa_i, mdfa.to_dot()))
       loads.append(load_template % ("mdfa [%s]" % name, mdfa_i))
-    body = "\n".join(scripts) + (load_outer_template % "\n".join(loads))
+  body = "\n".join(scripts) + (load_outer_template % "\n".join(loads))
+  return file_template % body
+
+def generate_rule_tree_html(rule_processor):
+  scripts = []
+  loads = []
+  rule_tree_dots = rule_processor.rule_tree_dots()
+  for i, (rule, dot) in enumerate(rule_tree_dots.items()):
+    rule_i = "rule_%d" % i
+    scripts.append(script_template % (rule_i, dot))
+    loads.append(load_template % ("rules [%s]" % rule, rule_i))
+  body = "\n".join(scripts) + (load_outer_template % "\n".join(loads))
   return file_template % body

 def generate_code(rule_processor, minimize_default):
@@ -104,6 +115,7 @@ if __name__ == '__main__':
   parser.add_argument('--no-inline', action='store_true')
   parser.add_argument('--verbose', action='store_true')
   parser.add_argument('--debug-code', action='store_true')
+  parser.add_argument('--rule-html')
   args = parser.parse_args()

   minimize_default = not args.no_minimize_default
@@ -136,6 +148,14 @@ if __name__ == '__main__':
       if verbose:
         print "wrote html to %s" % html_file

+  rule_html_file = args.rule_html
+  if rule_html_file:
+    html = generate_rule_tree_html(rule_processor)
+    with open(rule_html_file, 'w') as f:
+      f.write(html)
+      if verbose:
+        print "wrote html to %s" % rule_html_file
+
   code_file = args.code
   if code_file:
     code_generator = CodeGenerator(rule_processor,
Index: tools/lexer_generator/nfa_builder.py
diff --git a/tools/lexer_generator/nfa_builder.py b/tools/lexer_generator/nfa_builder.py index e127ab4cecf4f3409adc7aa4a7a9742b762d4bdf..d591f5c39969a94d3d9559289b09f6ed7b3d0cc7 100644
--- a/tools/lexer_generator/nfa_builder.py
+++ b/tools/lexer_generator/nfa_builder.py
@@ -240,6 +240,41 @@ class NfaBuilder(object):
     return Nfa(self.__encoding, start, end, nodes_created)

   @staticmethod
+  def rule_tree_dot(graph):
+    node_ix = [0]
+    node_template = 'node [label="%s"]; N_%d;'
+    edge_template = 'N_%d -> N_%d'
+    nodes = []
+    edges = []
+
+    def escape(v):
+      v = str(v)
+ v = v.replace('\r', '\\\\r').replace('\t', '\\\\t').replace('\n', '\\\\n')
+      v = v.replace('\\', '\\\\').replace('\"', '\\\"')
+      return v
+
+    def process_thing(thing):
+      if isinstance(thing, str):
+        node_ix[0] += 1
+        nodes.append(node_template % (escape(thing), node_ix[0]))
+        return node_ix[0]
+      if isinstance(thing, tuple):
+        child_ixs = map(process_thing, list(thing)[1:])
+        node_ix[0] += 1
+        nodes.append(node_template % (escape(thing[0]), node_ix[0]))
+        for child_ix in child_ixs:
+          edges.append(edge_template % (node_ix[0], child_ix))
+        return node_ix[0]
+      if isinstance(thing, Action):
+        node_ix[0] += 1
+        nodes.append(node_template % (str(thing), node_ix[0]))
+        return node_ix[0]
+      raise Exception
+
+    process_thing(graph)
+    return 'digraph { %s %s }' % ('\n'.join(nodes), '\n'.join(edges))
+
+  @staticmethod
   def add_action(graph, action):
     return ('ACTION', graph, action)

Index: tools/lexer_generator/rule_parser.py
diff --git a/tools/lexer_generator/rule_parser.py b/tools/lexer_generator/rule_parser.py index 65b3f17a158fe9601a9c4e52ac4ad8e8cc92f779..fb823ca088511a38e896ed036f4314d533de57f5 100644
--- a/tools/lexer_generator/rule_parser.py
+++ b/tools/lexer_generator/rule_parser.py
@@ -246,6 +246,7 @@ class RuleProcessor(object):

   def __init__(self, parser_state):
     self.__automata = {}
+    self.__rule_trees = {}
     self.__process_parser_state(parser_state)

   @staticmethod
@@ -260,6 +261,12 @@ class RuleProcessor(object):
   def default_automata(self):
     return self.__automata['default']

+  def rule_tree_dots(self):
+    result = {}
+    for rule in self.__rule_trees:
+      result[rule] = NfaBuilder.rule_tree_dot(self.__rule_trees[rule])
+    return result
+
   class Automata(object):

     def __init__(self, builder, graph):
@@ -328,6 +335,7 @@ class RuleProcessor(object):
     # build the automata
     for rule_name, graph in rule_map.items():
       self.__automata[rule_name] = RuleProcessor.Automata(builder, graph)
+      self.__rule_trees[rule_name] = graph
     # process default_action
     default_action = parser_state.rules['default']['default_action']
self.default_action = Action(None, default_action[1]) if default_action else None


--
--
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