Revision: 18667
Author: [email protected]
Date: Fri Jan 17 13:38:07 2014 UTC
Log: Experimental parser: visualize rule trees.
[email protected]
BUG=
Review URL: https://codereview.chromium.org/141293003
http://code.google.com/p/v8/source/detail?r=18667
Modified:
/branches/experimental/parser/tools/lexer_generator/generator.py
/branches/experimental/parser/tools/lexer_generator/nfa_builder.py
/branches/experimental/parser/tools/lexer_generator/rule_parser.py
=======================================
--- /branches/experimental/parser/tools/lexer_generator/generator.py Mon
Nov 25 13:28:43 2013 UTC
+++ /branches/experimental/parser/tools/lexer_generator/generator.py Fri
Jan 17 13:38:07 2014 UTC
@@ -80,9 +80,20 @@
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):
return CodeGenerator.rule_processor_to_code(rule_processor,
minimize_default)
@@ -104,6 +115,7 @@
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 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,
=======================================
--- /branches/experimental/parser/tools/lexer_generator/nfa_builder.py Fri
Nov 22 08:40:59 2013 UTC
+++ /branches/experimental/parser/tools/lexer_generator/nfa_builder.py Fri
Jan 17 13:38:07 2014 UTC
@@ -239,6 +239,41 @@
Automaton.visit_states(set([start]), f)
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)
=======================================
--- /branches/experimental/parser/tools/lexer_generator/rule_parser.py Tue
Jan 14 12:22:39 2014 UTC
+++ /branches/experimental/parser/tools/lexer_generator/rule_parser.py Fri
Jan 17 13:38:07 2014 UTC
@@ -246,6 +246,7 @@
def __init__(self, parser_state):
self.__automata = {}
+ self.__rule_trees = {}
self.__process_parser_state(parser_state)
@staticmethod
@@ -260,6 +261,12 @@
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 @@
# 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.