Commit d0deda8d authored by Igor Dejanovic's avatar Igor Dejanovic

Reworked robot examples to use visitor

parent 9e09e374
......@@ -23,68 +23,52 @@ from __future__ import print_function, unicode_literals
from arpeggio import *
# Grammar rules
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'
def left(): return 'left'
def right(): return 'right'
# Semantic actions
class Up(SemanticAction):
def first_pass(self, parser, node, children):
if parser.debug:
def robot(): return 'begin', ZeroOrMore(command), 'end', EOF
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 visitor
class RobotVisitor(PTNodeVisitor):
def visit_robot(self, node, children):
if self.debug:
print("Evaluating position")
position = [0, 0]
for move in children:
position[0] += move[0]
position[1] += move[1]
return position
def visit_command(self, node, children):
if self.debug:
print("Command")
return children[0]
def visit_UP(self, node, children):
if self.debug:
print("Going up")
return (0, 1)
class Down(SemanticAction):
def first_pass(self, parser, node, children):
if parser.debug:
def visit_DOWN(self, node, children):
if self.debug:
print("Going down")
return (0, -1)
class Left(SemanticAction):
def first_pass(self, parser, node, children):
if parser.debug:
def visit_LEFT(self, node, children):
if self.debug:
print("Going left")
return (-1, 0)
class Right(SemanticAction):
def first_pass(self, parser, node, children):
if parser.debug:
def visit_RIGHT(self, node, children):
if self.debug:
print("Going right")
return (1, 0)
class Command(SemanticAction):
def first_pass(self, parser, node, children):
if parser.debug:
print("Command")
return children[0]
class Robot(SemanticAction):
def first_pass(self, parser, node, children):
if parser.debug:
print("Evaluating position")
position = [0, 0]
for move in children:
position[0] += move[0]
position[1] += move[1]
return position
# Connecting rules with semantic actions
robot.sem = Robot()
command.sem = Command()
up.sem = Up()
down.sem = Down()
left.sem = Left()
right.sem = Right()
def main(debug=False):
# Program code
input_program = '''
......@@ -105,10 +89,10 @@ def main(debug=False):
# We create a parse tree out of textual input
parse_tree = parser.parse(input_program)
# getASG will start semantic analysis.
# visit_parse_tree will start semantic analysis.
# In this case semantic analysis will evaluate expression and
# returned value will be the final position of the robot.
result = parser.getASG()
result = visit_parse_tree(parse_tree, RobotVisitor(debug=debug))
if debug:
print("position = ", result)
......
......@@ -33,16 +33,8 @@ LEFT <- 'left';
RIGHT <- 'right';
'''
# Semantic actions
from robot import Up, Down, Left, Right, Command, Robot
semantic_actions = {
'robot': Robot(),
'command': Command(),
'UP': Up(),
'DOWN': Down(),
'LEFT': Left(),
'RIGHT': Right()
}
# Semantic actions visitor
from robot import RobotVisitor
def main(debug=False):
......@@ -57,7 +49,6 @@ def main(debug=False):
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.
......@@ -66,10 +57,10 @@ def main(debug=False):
# We create a parse tree out of textual input
parse_tree = parser.parse(input)
# getASG will start semantic analysis.
# visit_parse_tree will start semantic analysis.
# In this case semantic analysis will evaluate expression and
# returned value will be the final position of the robot.
return parser.getASG(sem_actions=semantic_actions)
return visit_parse_tree(parse_tree, RobotVisitor(debug=debug))
if __name__ == "__main__":
# In debug mode dot (graphviz) files for parser model
......
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