Commit fb675a56 authored by Igor Dejanović's avatar Igor Dejanović

Added robot DSL language example.

parent 261fa61b
#######################################################################
# 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>
# License: MIT License
#
# This example is inspired by an example from LISA tool (http://labraj.uni-mb.si/lisa/)
# presented during the lecture given by prof. Marjan Mernik (http://lpm.uni-mb.si/mernik/)
# at the University of Novi Sad in June, 2011.
#
# An example of the robot program:
# begin
# up
# up
# left
# down
# right
# end
#######################################################################
from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport
from arpeggio import RegExMatch as _
import logging
# Grammar rules
def program(): return Kwd('begin'), ZeroOrMore(command), Kwd('end'), EndOfFile
def command(): return [up, down, left, right]
def up(): return 'up'
def down(): return 'down'
def left(): return 'left'
def right(): return 'right'
# Semantic actions
class Up(SemanticAction):
def first_pass(self, parser, node, nodes):
logging.debug("Going up")
return (0, 1)
class Down(SemanticAction):
def first_pass(self, parser, node, nodes):
logging.debug("Going down")
return (0, -1)
class Left(SemanticAction):
def first_pass(self, parser, node, nodes):
logging.debug("Going left")
return (-1, 0)
class Right(SemanticAction):
def first_pass(self, parser, node, nodes):
logging.debug("Going right")
return (1, 0)
class Command(SemanticAction):
def first_pass(self, parser, node, nodes):
logging.debug("Command")
return nodes[0]
class Program(SemanticAction):
def first_pass(self, parser, node, nodes):
logging.debug("Evaluating position")
return reduce(lambda x, y: (x[0]+y[0], x[1]+y[1]), nodes[1:-2])
# Connecting rules with semantic actions
program.sem = Program()
command.sem = Command()
up.sem = Up()
down.sem = Down()
left.sem = Left()
right.sem = Right()
if __name__ == "__main__":
try:
logging.basicConfig(level=logging.DEBUG)
# Program code
input = '''
begin
up
up
left
down
right
end
'''
# 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)
# Then we export it to a dot file in order to visualize it. This is
# particularly handy for debugging purposes.
# We can make a jpg out of it using dot (part of graphviz) like this
# dot -O -Tjpg robot_parse_tree_model.dot
PMDOTExport().exportFile(parser.parser_model,
"robot_parse_tree_model.dot")
# We create a parse tree out of textual input
parse_tree = parser.parse(input)
# Then we export it to a dot file in order to visualize it.
# dot -O -Tjpg robot_parse_tree.dot
PTDOTExport().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.
print "position = ", parser.getASG()
except NoMatch, e:
print "Expected %s at position %s." % (e.value, str(e.parser.pos_to_linecol(e.position)))
#######################################################################
# Name: robot_peg.py
# Purpose: Simple DSL for defining robot movement (PEG version).
# Author: Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com>
# Copyright: (c) 2011 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/)
# presented during the lecture given by prof. Marjan Mernik (http://lpm.uni-mb.si/mernik/)
# at the University of Novi Sad in June, 2011.
#
# An example of the robot program:
# begin
# up
# up
# left
# down
# right
# end
#######################################################################
from arpeggio import *
from arpeggio.export import PMDOTExport, PTDOTExport
from arpeggio import RegExMatch as _
import logging
from arpeggio.peg import ParserPEG
# Grammar rules
robot_grammar = '''
program <- 'begin' (command)* 'end' EndOfFile;
command <- UP/DOWN/LEFT/RIGHT;
UP <- 'up';
DOWN <- 'down';
LEFT <- 'left';
RIGHT <- 'right';
'''
# Semantic actions
from robot import Up, Down, Left, Right, Command, Program
semantic_actions = {
'program': Program(),
'command': Command(),
'UP': Up(),
'DOWN': Down(),
'LEFT': Left(),
'RIGHT': Right()
}
if __name__ == "__main__":
try:
logging.basicConfig(level=logging.DEBUG)
# Program code
input = '''
begin
up
up
left
down
right
end
'''
# 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')
# Then we export it to a dot file in order to visualize it. This is
# particularly handy for debugging purposes.
# We can make a jpg out of it using dot (part of graphviz) like this
# dot -O -Tjpg robot_peg_parse_tree_model.dot
PMDOTExport().exportFile(parser.parser_model,
"robot_peg_parse_tree_model.dot")
# We create a parse tree out of textual input
parse_tree = parser.parse(input)
# Then we export it to a dot file in order to visualize it.
# dot -O -Tjpg robot_peg_parse_tree.dot
PTDOTExport().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.
print "position = ", parser.getASG(sem_actions=semantic_actions)
except NoMatch, e:
print "Expected %s at position %s." % (e.value, str(e.parser.pos_to_linecol(e.position)))
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