Commit 58e82c62 authored by Igor Dejanovic's avatar Igor Dejanovic

Refactoring exporter and tidying up examples.

parent ed5cc11a
...@@ -11,13 +11,13 @@ import StringIO ...@@ -11,13 +11,13 @@ import StringIO
from arpeggio import Terminal from arpeggio import Terminal
class Export(object): class Exporter(object):
""" """
Base class for all Exporters. Base class for all Exporters.
""" """
def __init__(self): def __init__(self):
super(Export, self).__init__() super(Exporter, self).__init__()
# Export initialization # Export initialization
self._render_set = set() # Used in rendering to prevent self._render_set = set() # Used in rendering to prevent
...@@ -25,7 +25,6 @@ class Export(object): ...@@ -25,7 +25,6 @@ class Export(object):
# of the same node multiple times # of the same node multiple times
self._adapter_map = {} # Used as a registry of adapters to self._adapter_map = {} # Used as a registry of adapters to
# ensure
# ensure that the same adapter is # ensure that the same adapter is
# returned for the same adaptee object # returned for the same adaptee object
...@@ -64,14 +63,14 @@ class Export(object): ...@@ -64,14 +63,14 @@ class Export(object):
class ExportAdapter(object): class ExportAdapter(object):
''' """
Base adapter class for the export support. Base adapter class for the export support.
Adapter should be defined for every graph type. Adapter should be defined for every export and graph type.
Attributes: Attributes:
adaptee: A node to adapt. adaptee: A node to adapt.
export: An export object used as a context of the export. export: An export object used as a context of the export.
''' """
def __init__(self, node, export): def __init__(self, node, export):
self.adaptee = node # adaptee is adapted graph node self.adaptee = node # adaptee is adapted graph node
self.export = export self.export = export
...@@ -100,9 +99,9 @@ class DOTExportAdapter(ExportAdapter): ...@@ -100,9 +99,9 @@ class DOTExportAdapter(ExportAdapter):
raise NotImplementedError() raise NotImplementedError()
@property @property
def children(self): def neighbours(self):
""" """
Children of the graph node. A set of adjacent graph nodes.
""" """
raise NotImplementedError() raise NotImplementedError()
...@@ -120,26 +119,27 @@ class PMDOTExportAdapter(DOTExportAdapter): ...@@ -120,26 +119,27 @@ class PMDOTExportAdapter(DOTExportAdapter):
return self.adaptee.desc return self.adaptee.desc
@property @property
def children(self): def neighbours(self):
if not hasattr(self, "_children"): if not hasattr(self, "_neighbours"):
self._children = [] self._neighbours= []
# Registry of adapters used in this export # Registry of adapters used in this export
adapter_map = self.export._adapter_map adapter_map = self.export._adapter_map
for c, n in enumerate(self.adaptee.nodes): for c, n in enumerate(self.adaptee.nodes):
if isinstance(n, PMDOTExportAdapter): if isinstance(n, PMDOTExportAdapter):
# if child node is already adapted use that adapter # if the neighbour node is already adapted use that adapter
self._children.append((str(c + 1), n)) self._neighbours.append((str(c + 1), n))
elif id(n) in adapter_map: elif id(n) in adapter_map:
# current node is adaptee -> there is registered adapter # current node is adaptee -> there is registered adapter
self._children.append((str(c + 1), adapter_map[id(n)])) self._neighbours.append((str(c + 1), adapter_map[id(n)]))
else: else:
# Create new adapter
adapter = PMDOTExportAdapter(n, self.export) adapter = PMDOTExportAdapter(n, self.export)
self._children.append((str(c + 1), adapter)) self._neighbours.append((str(c + 1), adapter))
adapter_map[adapter.id] = adapter adapter_map[adapter.id] = adapter
return self._children return self._neighbours
class PTDOTExportAdapter(PMDOTExportAdapter): class PTDOTExportAdapter(PMDOTExportAdapter):
...@@ -147,19 +147,19 @@ class PTDOTExportAdapter(PMDOTExportAdapter): ...@@ -147,19 +147,19 @@ class PTDOTExportAdapter(PMDOTExportAdapter):
Adapter for ParseTreeNode graph types. Adapter for ParseTreeNode graph types.
""" """
@property @property
def children(self): def neighbours(self):
if isinstance(self.adaptee, Terminal): if isinstance(self.adaptee, Terminal):
return [] return []
else: else:
if not hasattr(self, "_children"): if not hasattr(self, "_neighbours"):
self._children = [] self._neighbours = []
for c, n in enumerate(self.adaptee.nodes): for c, n in enumerate(self.adaptee.nodes):
adapter = PTDOTExportAdapter(n, self.export) adapter = PTDOTExportAdapter(n, self.export)
self._children.append((str(c + 1), adapter)) self._neighbours.append((str(c + 1), adapter))
return self._children return self._neighbours
class DOTExport(Export): class DOTExporter(Exporter):
""" """
Export to DOT language (part of GraphViz, see http://www.graphviz.org/) Export to DOT language (part of GraphViz, see http://www.graphviz.org/)
""" """
...@@ -173,7 +173,7 @@ class DOTExport(Export): ...@@ -173,7 +173,7 @@ class DOTExport(Export):
# retval += self.node(root.comments) # retval += self.node(root.comments)
# retval += '\n%s->%s [label="comment"]' % \ # retval += '\n%s->%s [label="comment"]' % \
#(id(root), id(root.comments)) #(id(root), id(root.comments))
for name, n in node.children: for name, n in node.neighbours:
self._outf.write('\n%s->%s [label="%s"]' % self._outf.write('\n%s->%s [label="%s"]' %
(node.id, n.id, name)) (node.id, n.id, name))
self._outf.write('\n') self._outf.write('\n')
...@@ -192,27 +192,27 @@ class DOTExport(Export): ...@@ -192,27 +192,27 @@ class DOTExport(Export):
return to_esc return to_esc
class PMDOTExport(DOTExport): class PMDOTExporter(DOTExporter):
""" """
A convenience DOTExport extension that uses ParserExpressionDOTExportAdapter A convenience DOTExport extension that uses ParserExpressionDOTExportAdapter
""" """
def export(self, obj): def export(self, obj):
return super(PMDOTExport, self).\ return super(PMDOTExporter, self).\
export(PMDOTExportAdapter(obj, self)) export(PMDOTExportAdapter(obj, self))
def exportFile(self, obj, file_name): def exportFile(self, obj, file_name):
return super(PMDOTExport, self).\ return super(PMDOTExporter, self).\
exportFile(PMDOTExportAdapter(obj, self), file_name) exportFile(PMDOTExportAdapter(obj, self), file_name)
class PTDOTExport(DOTExport): class PTDOTExporter(DOTExporter):
""" """
A convenience DOTExport extension that uses PTDOTExportAdapter A convenience DOTExport extension that uses PTDOTExportAdapter
""" """
def export(self, obj): def export(self, obj):
return super(PTDOTExport, self).\ return super(PTDOTExporter, self).\
export(PTDOTExportAdapter(obj, self)) export(PTDOTExportAdapter(obj, self))
def exportFile(self, obj, file_name): def exportFile(self, obj, file_name):
return super(PTDOTExport, self).\ return super(PTDOTExporter, self).\
exportFile(PTDOTExportAdapter(obj, self), file_name) exportFile(PTDOTExportAdapter(obj, self), file_name)
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
import sys import sys
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _ from arpeggio import RegExMatch as _
...@@ -94,7 +94,7 @@ if __name__ == "__main__": ...@@ -94,7 +94,7 @@ if __name__ == "__main__":
# particulary handy for debugging purposes. # particulary handy for debugging purposes.
# We can make a jpg out of it using dot (part of graphviz) like this # We can make a jpg out of it using dot (part of graphviz) like this
# dot -O -Tjpg calc_parse_tree_model.dot # dot -O -Tjpg calc_parse_tree_model.dot
PMDOTExport().exportFile(parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"bib_parse_tree_model.dot") "bib_parse_tree_model.dot")
# First parameter is bibtex file # First parameter is bibtex file
...@@ -107,7 +107,7 @@ if __name__ == "__main__": ...@@ -107,7 +107,7 @@ if __name__ == "__main__":
parse_tree = parser.parse(bibtexfile_content) parse_tree = parser.parse(bibtexfile_content)
# Then we export it to a dot file in order to visualise it. # Then we export it to a dot file in order to visualise it.
PTDOTExport().exportFile(parse_tree, PTDOTExporter().exportFile(parse_tree,
"bib_parse_tree.dot") "bib_parse_tree.dot")
# getASG will start semantic analysis. # getASG will start semantic analysis.
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
####################################################################### #######################################################################
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _ from arpeggio import RegExMatch as _
def number(): return _(r'\d*\.\d*|\d+') def number(): return _(r'\d*\.\d*|\d+')
...@@ -104,21 +104,22 @@ if __name__ == "__main__": ...@@ -104,21 +104,22 @@ if __name__ == "__main__":
# are using ParserPython class. # are using ParserPython class.
parser = ParserPython(calc) parser = ParserPython(calc)
# Then we export it to a dot file in order to visualise it. This is # Then we export it to a dot file in order to visualise it.
# particularly handy for debugging purposes. # This step is optional but it is handy for debugging purposes.
# We can make a jpg out of it using dot (part of graphviz) like this # We can make a png out of it using dot (part of graphviz) like this
# dot -O -Tjpg calc_parse_tree_model.dot # dot -O -Tpng calc_parse_tree_model.dot
PMDOTExport().exportFile(parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"calc_parse_tree_model.dot") "calc_parse_tree_model.dot")
# An expression we want to evaluate # An expression we want to evaluate
input = "-(4-1)*5+(2+4.67)+5.89/(.2+7)" input = "-(4-1)*5+(2+4.67)+5.89/(.2+7)"
# We create a parse tree or abstract syntax tree out of textual input # We create a parse tree out of textual input
parse_tree = parser.parse(input) parse_tree = parser.parse(input)
# Then we export it to a dot file in order to visualise it. # Then we export it to a dot file in order to visualise it.
PTDOTExport().exportFile(parse_tree, # This is also optional.
PTDOTExporter().exportFile(parse_tree,
"calc_parse_tree.dot") "calc_parse_tree.dot")
# getASG will start semantic analysis. # getASG will start semantic analysis.
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
from arpeggio import * from arpeggio import *
from arpeggio.peg import ParserPEG from arpeggio.peg import ParserPEG
from arpeggio.export import PMDOTExport, PTDOTExport from arpeggio.export import PMDOTExporter, PTDOTExporter
# Semantic actions # Semantic actions
from calc import ToFloat, Factor, Term, Expr, Calc from calc import ToFloat, Factor, Term, Expr, Calc
...@@ -48,7 +48,7 @@ try: ...@@ -48,7 +48,7 @@ try:
# Then we export it to a dot file. # Then we export it to a dot file.
PMDOTExport().exportFile(parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"calc_peg_parser_model.dot") "calc_peg_parser_model.dot")
# An expression we want to evaluate # An expression we want to evaluate
...@@ -58,7 +58,7 @@ try: ...@@ -58,7 +58,7 @@ try:
parse_tree = parser.parse(input) parse_tree = parser.parse(input)
# We save it to dot file in order to visualise it. # We save it to dot file in order to visualise it.
PTDOTExport().exportFile(parse_tree, PTDOTExporter().exportFile(parse_tree,
"calc_peg_parse_tree.dot") "calc_peg_parse_tree.dot")
# getASG will start semantic analysis. # getASG will start semantic analysis.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# License: MIT License # License: MIT License
############################################################################## ##############################################################################
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _ from arpeggio import RegExMatch as _
def record(): return field, ZeroOrMore(",", field) def record(): return field, ZeroOrMore(",", field)
...@@ -34,19 +34,20 @@ Unquoted test 3, "Quoted test 3", 23234, One Two Three, "343456.45" ...@@ -34,19 +34,20 @@ Unquoted test 3, "Quoted test 3", 23234, One Two Three, "343456.45"
# have semantics in csv files. They are used to separate records. # have semantics in csv files. They are used to separate records.
parser = ParserPython(csvfile, ws='\t ', reduce_tree=True, debug=True) parser = ParserPython(csvfile, ws='\t ', reduce_tree=True, debug=True)
# Then we export it to a dot file in order to visualise it. This is # Then we export it to a dot file in order to visualise it.
# particularly handy for debugging purposes. # This step is optional but it is handy for debugging purposes.
# We can make a png out of it using dot (part of graphviz) like this: # We can make a png out of it using dot (part of graphviz) like this:
# dot -O -Tpng calc_parse_tree_model.dot # dot -O -Tpng calc_parse_tree_model.dot
PMDOTExport().exportFile(parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"csv_parse_tree_model.dot") "csv_parse_tree_model.dot")
# Creating parse tree out of textual input # Creating parse tree out of textual input
parse_tree = parser.parse(test_data) parse_tree = parser.parse(test_data)
# Then we export it to a dot file in order to visualise it. # Then we export it to a dot file in order to visualise it.
# This is also optional.
# dot -O -Tpng calc_parse_tree.dot # dot -O -Tpng calc_parse_tree.dot
PTDOTExport().exportFile(parse_tree, PTDOTExporter().exportFile(parse_tree,
"csv_parse_tree.dot") "csv_parse_tree.dot")
except NoMatch, e: except NoMatch, e:
......
...@@ -34,7 +34,7 @@ value ...@@ -34,7 +34,7 @@ value
""" """
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _ from arpeggio import RegExMatch as _
def TRUE(): return "true" def TRUE(): return "true"
...@@ -86,12 +86,12 @@ if __name__ == "__main__": ...@@ -86,12 +86,12 @@ if __name__ == "__main__":
parser = ParserPython(jsonFile, debug=True) parser = ParserPython(jsonFile, debug=True)
# Exporting parser model to dot file in order to visualise it. # Exporting parser model to dot file in order to visualise it.
PMDOTExport().exportFile(parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"json_parser_model.dot") "json_parser_model.dot")
parse_tree = parser.parse(testdata) parse_tree = parser.parse(testdata)
PTDOTExport().exportFile(parser.parse_tree, PTDOTExporter().exportFile(parser.parse_tree,
"json_parse_tree.dot") "json_parse_tree.dot")
except NoMatch, e: except NoMatch, e:
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# grammar definition language. # grammar definition language.
############################################################################## ##############################################################################
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio.peg import ParserPEG from arpeggio.peg import ParserPEG
# Semantic actions # Semantic actions
...@@ -71,8 +71,8 @@ try: ...@@ -71,8 +71,8 @@ try:
# create parser_model for parsing PEG based grammars # create parser_model for parsing PEG based grammars
parser = ParserPEG(peg_grammar, 'grammar', debug=True) parser = ParserPEG(peg_grammar, 'grammar', debug=True)
# Exporting parser model to dot file in order to visualise. # Exporting parser model to dot file for visualization.
PMDOTExport().exportFile(parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"peg_peg_parser_model.dot") "peg_peg_parser_model.dot")
# Now we will use created parser to parse the same peg_grammar used for # Now we will use created parser to parse the same peg_grammar used for
...@@ -80,7 +80,8 @@ try: ...@@ -80,7 +80,8 @@ try:
# using PEG itself. # using PEG itself.
parser.parse(peg_grammar) parser.parse(peg_grammar)
PTDOTExport().exportFile(parser.parse_tree, # Again we export parse tree in dot file for vizualization.
PTDOTExporter().exportFile(parser.parse_tree,
"peg_peg_parse_tree.dot") "peg_peg_parse_tree.dot")
# ASG should be the same as parser.parser_model because semantic # ASG should be the same as parser.parser_model because semantic
...@@ -89,7 +90,7 @@ try: ...@@ -89,7 +90,7 @@ try:
# This graph should be the same as peg_peg_parser_model.dot because # This graph should be the same as peg_peg_parser_model.dot because
# they define the same parser. # they define the same parser.
PMDOTExport().exportFile(asg, PMDOTExporter().exportFile(asg,
"peg_peg_asg.dot") "peg_peg_asg.dot")
# If we replace parser_mode with ASG constructed parser it will still # If we replace parser_mode with ASG constructed parser it will still
......
...@@ -20,8 +20,7 @@ ...@@ -20,8 +20,7 @@
####################################################################### #######################################################################
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _
# Grammar rules # Grammar rules
def program(): return Kwd('begin'), ZeroOrMore(command), Kwd('end'), EndOfFile def program(): return Kwd('begin'), ZeroOrMore(command), Kwd('end'), EndOfFile
...@@ -92,19 +91,19 @@ if __name__ == "__main__": ...@@ -92,19 +91,19 @@ if __name__ == "__main__":
# are using ParserPython class. # are using ParserPython class.
parser = ParserPython(program, debug=True) parser = ParserPython(program, debug=True)
# Then we export it to a dot file in order to visualize it. This is # Then we export it to a dot file in order to visualize it.
# particularly handy for debugging purposes. # This step is optional but it is handy for debugging purposes.
# We can make a jpg out of it using dot (part of graphviz) like this # We can make a png out of it using dot (part of graphviz) like this
# dot -O -Tjpg robot_parse_tree_model.dot # dot -O -Tpng robot_parser_model.dot
PMDOTExport().exportFile(parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"robot_parse_tree_model.dot") "robot_parser_model.dot")
# We create a parse tree out of textual input # We create a parse tree out of textual input
parse_tree = parser.parse(input) parse_tree = parser.parse(input)
# Then we export it to a dot file in order to visualize it. # Then we export it to a dot file in order to visualize it.
# dot -O -Tjpg robot_parse_tree.dot # dot -O -Tpng robot_parse_tree.dot
PTDOTExport().exportFile(parse_tree, PTDOTExporter().exportFile(parse_tree,
"robot_parse_tree.dot") "robot_parse_tree.dot")
# getASG will start semantic analysis. # getASG will start semantic analysis.
......
...@@ -20,8 +20,7 @@ ...@@ -20,8 +20,7 @@
####################################################################### #######################################################################
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _
from arpeggio.peg import ParserPEG from arpeggio.peg import ParserPEG
# Grammar rules # Grammar rules
...@@ -66,19 +65,19 @@ if __name__ == "__main__": ...@@ -66,19 +65,19 @@ if __name__ == "__main__":
# are using ParserPEG class. # are using ParserPEG class.
parser = ParserPEG(robot_grammar, 'program', debug=True) parser = ParserPEG(robot_grammar, 'program', debug=True)
# Then we export it to a dot file in order to visualize it. This is # Then we export it to a dot file in order to visualize it.
# particularly handy for debugging purposes. # This step is optional but it is handy for debugging purposes.
# We can make a jpg out of it using dot (part of graphviz) like this # We can make a png out of it using dot (part of graphviz) like this
# dot -O -Tjpg robot_peg_parse_tree_model.dot # dot -O -Tpng robot_peg_parser_model.dot
PMDOTExport().exportFile(parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"robot_peg_parse_tree_model.dot") "robot_peg_parser_model.dot")
# We create a parse tree out of textual input # We create a parse tree out of textual input
parse_tree = parser.parse(input) parse_tree = parser.parse(input)
# Then we export it to a dot file in order to visualize it. # Then we export it to a dot file in order to visualize it.
# dot -O -Tjpg robot_peg_parse_tree.dot # dot -O -Tpng robot_peg_parse_tree.dot
PTDOTExport().exportFile(parse_tree, PTDOTExporter().exportFile(parse_tree,
"robot_peg_parse_tree.dot") "robot_peg_parse_tree.dot")
# getASG will start semantic analysis. # getASG will start semantic analysis.
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
####################################################################### #######################################################################
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _ from arpeggio import RegExMatch as _
def comment(): return [_("//.*"), _("/\*.*\*/")] def comment(): return [_("//.*"), _("/\*.*\*/")]
...@@ -36,13 +36,13 @@ try: ...@@ -36,13 +36,13 @@ try:
parser = ParserPython(simpleLanguage, comment, debug=True) parser = ParserPython(simpleLanguage, comment, debug=True)
# We save parser model to dot file in order to visualise it. # We save parser model to dot file in order to visualise it.
# We can make a jpg out of it using dot (part of graphviz) like this # We can make a png out of it using dot (part of graphviz) like this
# dot -Tjpg -O simple_parser.dot # dot -Tpng -O simple_parser.dot
PMDOTExport().exportFile(parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"simple_parser_model.dot") "simple_parser_model.dot")
# Parser model for comments is handled as separate model # Parser model for comments is handled as separate model
PMDOTExport().exportFile(parser.comments_model, PMDOTExporter().exportFile(parser.comments_model,
"simple_parser_comments.dot") "simple_parser_comments.dot")
input = """ input = """
...@@ -57,7 +57,7 @@ try: ...@@ -57,7 +57,7 @@ try:
""" """
parse_tree = parser.parse(input) parse_tree = parser.parse(input)
PTDOTExport().exportFile(parse_tree, PTDOTExporter().exportFile(parse_tree,
"simple_parse_tree.dot") "simple_parse_tree.dot")
except NoMatch, e: except NoMatch, e:
......
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