Commit 3f9714aa authored by Igor Dejanovic's avatar Igor Dejanovic

DOT export integrated in parsers

If parser runs in debug mode dot files will be generated.
parent ac6afe41
......@@ -899,6 +899,14 @@ class Parser(object):
self.input = _input
self.parser_model.clear_cache()
self.parse_tree = self._parse()
# In debug mode export parse tree to dot file for
# visualization
if self.debug:
from arpeggio.export import PTDOTExporter
root_rule = self.parse_tree.rule
PTDOTExporter().exportFile(self.parse_tree,
"{}_parse_tree.dot".format(root_rule))
return self.parse_tree
def getASG(self, sem_actions=None, defaults=True):
......@@ -1094,6 +1102,14 @@ class ParserPython(Parser):
self.comments_model = self._from_python(comment_def) \
if comment_def else None
# In debug mode export parser model to dot for
# visualization
if self.debug:
from arpeggio.export import PMDOTExporter
root_rule = language_def.__name__
PMDOTExporter().exportFile(self.parser_model,
"{}_parser_model.dot".format(root_rule))
# Comments should be optional and there can be more of them
if self.comments_model: # and not isinstance(self.comments_model, ZeroOrMore):
self.comments_model.root = True
......
......@@ -34,7 +34,7 @@ def str_match(): return _(r'(\'(\\\'|[^\'])*\')|("[^"]*")')
def comment(): return "//", _(".*\n")
# PEG syntax rules
def grammar(): return OneOrMore(rule), EOF
def peggrammar(): return OneOrMore(rule), EOF
def rule(): return rule_name, LEFT_ARROW, ordered_choice, ";"
def ordered_choice(): return sequence, ZeroOrMore(SLASH, sequence)
def sequence(): return OneOrMore(prefix)
......@@ -205,7 +205,7 @@ class SemStrMatch(SemanticAction):
return StrMatch(match_str, ignore_case=parser.ignore_case)
grammar.sem = SemGrammar()
peggrammar.sem = SemGrammar()
rule.sem = SemRule()
ordered_choice.sem = SemOrderedChoice()
sequence.sem = SemSequence()
......@@ -226,6 +226,14 @@ class ParserPEG(Parser):
# PEG Abstract Syntax Graph
self.parser_model = self._from_peg(language_def)
# In debug mode export parser model to dot for
# visualization
if self.debug:
from arpeggio.export import PMDOTExporter
root_rule = self.parser_model.rule
PMDOTExporter().exportFile(self.parser_model,
"{}_peg_parser_model.dot".format(root_rule))
# Comments should be optional and there can be more of them
if self.comments_model: # and not isinstance(self.comments_model, ZeroOrMore):
self.comments_model.root = True
......@@ -235,7 +243,7 @@ class ParserPEG(Parser):
return self.parser_model.parse(self)
def _from_peg(self, language_def):
parser = ParserPython(grammar, comment, reduce_tree=False)
parser = ParserPython(peggrammar, comment, reduce_tree=False, debug=self.debug)
parser.root_rule_name = self.root_rule_name
parser.parse(language_def)
......
......@@ -13,7 +13,6 @@ from __future__ import print_function
import pprint
import sys, os
from arpeggio import *
from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _
......@@ -59,7 +58,7 @@ class BibEntrySem(SemanticAction):
"""
def first_pass(self, parser, node, children):
if parser.debug:
print(" Processing bibentry %s" % children[2])
print(" Processing bibentry %s" % children[1])
bib_entry_map = {
'bibtype': children[0],
'bibkey': children[1]
......@@ -109,14 +108,7 @@ def main(debug=False, file_name=None):
# First we will make a parser - an instance of the bib parser model.
# Parser model is given in the form of python constructs therefore we
# are using ParserPython class.
parser = ParserPython(bibfile, reduce_tree=True)
if debug:
# Then we export it to a dot file in order to visualise it. This is
# particulary handy for debugging purposes.
# We can make a jpg out of it using dot (part of graphviz) like this
# dot -O -Tjpg calc_parse_tree_model.dot
PMDOTExporter().exportFile(parser.parser_model, "bib_parse_tree_model.dot")
parser = ParserPython(bibfile, reduce_tree=True, debug=debug)
if not file_name:
file_name = os.path.join(os.path.dirname(__file__), 'bibtex_example.bib')
......@@ -128,10 +120,6 @@ def main(debug=False, file_name=None):
# textual input
parse_tree = parser.parse(bibtexfile_content)
if debug:
# Then we export it to a dot file in order to visualize it.
PTDOTExporter().exportFile(parse_tree, "bib_parse_tree.dot")
# getASG will start semantic analysis.
# In this case semantic analysis will list of bibentry maps.
ast = parser.getASG()
......
......@@ -12,7 +12,6 @@
from arpeggio import Optional, ZeroOrMore, OneOrMore, EOF, SemanticAction,\
ParserPython
from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _
def number(): return _(r'\d*\.\d*|\d+')
......@@ -107,25 +106,12 @@ def main(debug=False):
# are using ParserPython class.
parser = ParserPython(calc, debug=debug)
if debug:
# Then we export it to a dot file in order to visualise it.
# 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
# dot -O -Tpng calc_parse_tree_model.dot
PMDOTExporter().exportFile(parser.parser_model,
"calc_parse_tree_model.dot")
# An expression we want to evaluate
input_expr = "-(4-1)*5+(2+4.67)+5.89/(.2+7)"
# We create a parse tree out of textual input_expr
parse_tree = parser.parse(input_expr)
if debug:
# Then we export it to a dot file in order to visualise it.
# This is also optional.
PTDOTExporter().exportFile(parse_tree, "calc_parse_tree.dot")
result = parser.getASG()
if debug:
......
......@@ -15,7 +15,6 @@
from __future__ import absolute_import
from arpeggio.peg import ParserPEG
from arpeggio.export import PMDOTExporter, PTDOTExporter
# Semantic actions
from calc import ToFloat, Factor, Term, Expr
......@@ -45,20 +44,12 @@ def main(debug=False):
# are using ParserPEG class. Root rule name (parsing expression) is "calc".
parser = ParserPEG(calc_grammar, "calc", debug=debug)
if debug:
# Then we export it to a dot file.
PMDOTExporter().exportFile(parser.parser_model, "calc_peg_parser_model.dot")
# An expression we want to evaluate
input_expr = "-(4-1)*5+(2+4.67)+5.89/(.2+7)"
# Then parse tree is created out of the input_expr expression.
parse_tree = parser.parse(input_expr)
if debug:
# We save it to dot file in order to visualise it.
PTDOTExporter().exportFile(parse_tree, "calc_peg_parse_tree.dot")
result = parser.getASG(sem_actions)
if debug:
......
......@@ -6,7 +6,6 @@
# License: MIT License
##############################################################################
from arpeggio import *
from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _
def record(): return field, ZeroOrMore(",", field)
......@@ -31,22 +30,9 @@ def main(debug=False):
# have semantics in csv files. They are used to separate records.
parser = ParserPython(csvfile, ws='\t ', reduce_tree=True, debug=debug)
if debug:
# Then we export it to a dot file in order to visualise it.
# 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:
# dot -O -Tpng calc_parse_tree_model.dot
PMDOTExporter().exportFile(parser.parser_model, "csv_parse_tree_model.dot")
# Creating parse tree out of textual input
parse_tree = parser.parse(test_data)
if debug:
# Then we export it to a dot file in order to visualise it.
# This is also optional.
# dot -O -Tpng calc_parse_tree.dot
PTDOTExporter().exportFile(parse_tree, "csv_parse_tree.dot")
if __name__ == "__main__":
main(debug=True)
......@@ -34,7 +34,6 @@ value
"""
from arpeggio import *
from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _
def TRUE(): return "true"
......@@ -85,17 +84,9 @@ def main(debug=False):
# Creating parser from parser model.
parser = ParserPython(jsonFile, debug=debug)
if debug:
# Exporting parser model to dot file in order to visualise it.
PMDOTExporter().exportFile(parser.parser_model, "json_parser_model.dot")
# Parse json string
parse_tree = parser.parse(testdata)
if debug:
# Export parse tree for visualization
PTDOTExporter().exportFile(parser.parse_tree, "json_parse_tree.dot")
if __name__ == "__main__":
main(debug=True)
......@@ -19,7 +19,7 @@ from arpeggio.peg import SemGrammar, SemRule, SemOrderedChoice, SemSequence,\
SemPrefix, SemSufix, SemExpression, SemRegEx, SemStrMatch, SemRuleCrossRef
sem_actions = {
"grammar": SemGrammar(),
"peggrammar": SemGrammar(),
"rule": SemRule(),
"ordered_choice": SemOrderedChoice(),
"sequence": SemSequence(),
......@@ -34,7 +34,7 @@ sem_actions = {
# PEG defined using PEG itself.
peg_grammar = r"""
grammar <- rule+ EOF;
peggrammar <- rule+ EOF;
rule <- rule_name LEFT_ARROW ordered_choice ';';
ordered_choice <- sequence (SLASH sequence)*;
sequence <- prefix+;
......@@ -64,24 +64,13 @@ def main(debug=False):
# ParserPEG will use ParserPython to parse peg_grammar definition and
# create parser_model for parsing PEG based grammars
parser = ParserPEG(peg_grammar, 'grammar', debug=debug)
if debug:
# Exporting parser model to dot file for visualization.
PMDOTExporter().exportFile(parser.parser_model,
"peg_peg_parser_model.dot")
parser = ParserPEG(peg_grammar, 'peggrammar', debug=debug)
# Now we will use created parser to parse the same peg_grammar used for
# parser initialization. We can parse peg_grammar because it is specified
# using PEG itself.
parser.parse(peg_grammar)
if debug:
# Again we export parse tree in dot file for visualization.
PTDOTExporter().exportFile(parser.parse_tree,
"peg_peg_parse_tree.dot")
# ASG should be the same as parser.parser_model because semantic
# actions will create PEG parser (tree of ParsingExpressions).
asg = parser.getASG(sem_actions)
......
......@@ -2,7 +2,7 @@
# Name: robot.py
# Purpose: Simple DSL for defining robot movement.
# Author: Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com>
# Copyright: (c) 2011 Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com>
# Copyright: (c) 2011-2014 Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com>
# License: MIT License
#
# This example is inspired by an example from LISA tool (http://labraj.uni-mb.si/lisa/)
......@@ -21,10 +21,9 @@
from __future__ import print_function
from arpeggio import *
from arpeggio.export import PMDOTExporter, PTDOTExporter
# Grammar rules
def program(): return Kwd('begin'), ZeroOrMore(command), Kwd('end'), EOF
def robot(): return Kwd('begin'), ZeroOrMore(command), Kwd('end'), EOF
def command(): return [up, down, left, right]
def up(): return 'up'
def down(): return 'down'
......@@ -68,7 +67,7 @@ class Command(SemanticAction):
return children[0]
class Program(SemanticAction):
class Robot(SemanticAction):
def first_pass(self, parser, node, children):
if parser.debug:
print("Evaluating position")
......@@ -79,7 +78,7 @@ class Program(SemanticAction):
return position
# Connecting rules with semantic actions
program.sem = Program()
robot.sem = Robot()
command.sem = Command()
up.sem = Up()
down.sem = Down()
......@@ -101,25 +100,11 @@ def main(debug=False):
# First we will make a parser - an instance of the robot parser model.
# Parser model is given in the form of python constructs therefore we
# are using ParserPython class.
parser = ParserPython(program, debug=debug)
if debug:
# Then we export it to a dot file in order to visualize it.
# 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
# dot -O -Tpng robot_parser_model.dot
PMDOTExporter().exportFile(parser.parser_model,
"robot_parser_model.dot")
parser = ParserPython(robot, debug=debug)
# We create a parse tree out of textual input
parse_tree = parser.parse(input_program)
if debug:
# Then we export it to a dot file in order to visualize it.
# dot -O -Tpng robot_parse_tree.dot
PTDOTExporter().exportFile(parse_tree,
"robot_parse_tree.dot")
# getASG will start semantic analysis.
# In this case semantic analysis will evaluate expression and
# returned value will be the final position of the robot.
......
......@@ -21,12 +21,11 @@
from __future__ import print_function
from arpeggio import *
from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio.peg import ParserPEG
# Grammar rules
robot_grammar = '''
program <- 'begin' (command)* 'end' EOF;
robot <- 'begin' (command)* 'end' EOF;
command <- UP/DOWN/LEFT/RIGHT;
UP <- 'up';
DOWN <- 'down';
......@@ -35,9 +34,9 @@ RIGHT <- 'right';
'''
# Semantic actions
from robot import Up, Down, Left, Right, Command, Program
from robot import Up, Down, Left, Right, Command, Robot
semantic_actions = {
'program': Program(),
'robot': Robot(),
'command': Command(),
'UP': Up(),
'DOWN': Down(),
......@@ -62,25 +61,11 @@ def main(debug=False):
# First we will make a parser - an instance of the robot parser model.
# Parser model is given in the form of PEG specification therefore we
# are using ParserPEG class.
parser = ParserPEG(robot_grammar, 'program', debug=debug)
if debug:
# Then we export it to a dot file in order to visualize it.
# 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
# dot -O -Tpng robot_peg_parser_model.dot
PMDOTExporter().exportFile(parser.parser_model,
"robot_peg_parser_model.dot")
parser = ParserPEG(robot_grammar, 'robot', debug=debug)
# We create a parse tree out of textual input
parse_tree = parser.parse(input)
if debug:
# Then we export it to a dot file in order to visualize it.
# dot -O -Tpng robot_peg_parse_tree.dot
PTDOTExporter().exportFile(parse_tree,
"robot_peg_parse_tree.dot")
# getASG will start semantic analysis.
# In this case semantic analysis will evaluate expression and
# returned value will be the final position of the robot.
......
......@@ -10,7 +10,6 @@
#######################################################################
from arpeggio import *
from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _
# Grammar
......@@ -47,21 +46,8 @@ def main(debug=False):
# and comment is a grammar rule for comments.
parser = ParserPython(simpleLanguage, comment, debug=debug)
if debug:
# We save parser model to dot file in order to visualise it.
# We can make a png out of it using dot (part of graphviz) like this
# dot -Tpng -O simple_parser.dot
PMDOTExporter().exportFile(parser.parser_model, "simple_parser_model.dot")
# Parser model for comments is handled as separate model
PMDOTExporter().exportFile(parser.comments_model, "simple_parser_comments.dot")
parse_tree = parser.parse(input)
if debug:
# Export parse tree for visualization
PTDOTExporter().exportFile(parse_tree, "simple_parse_tree.dot")
if __name__ == "__main__":
main(debug=True)
......
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