Commit ac2d22b1 authored by Igor Dejanovic's avatar Igor Dejanovic

fix #7 Support for Python 3.

Arpeggio now supports both python 2 and 3.
parent 2d654c9a
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
# notation. # notation.
################################################################################ ################################################################################
from __future__ import print_function
import re import re
import bisect import bisect
...@@ -150,7 +151,7 @@ class ParsingExpression(object): ...@@ -150,7 +151,7 @@ class ParsingExpression(object):
def _parse_intro(self, parser): def _parse_intro(self, parser):
if parser.debug: if parser.debug:
print "Parsing %s" % self.name print("Parsing {}".format(self.name))
# Skip whitespaces if we are not in the lexical rule # Skip whitespaces if we are not in the lexical rule
if not parser._in_lex_rule: if not parser._in_lex_rule:
...@@ -172,8 +173,7 @@ class ParsingExpression(object): ...@@ -172,8 +173,7 @@ class ParsingExpression(object):
# the result # the result
if c_pos in self.result_cache: if c_pos in self.result_cache:
if parser.debug: if parser.debug:
print "Result for [%s, %s] founded in result_cache." % \ print("Result for [{}, {}] founded in result_cache.".format(self, self.c_pos))
(self, self.c_pos)
result, new_pos = self.result_cache[c_pos] result, new_pos = self.result_cache[c_pos]
parser.position = new_pos parser.position = new_pos
return result return result
...@@ -226,7 +226,7 @@ class Sequence(ParsingExpression): ...@@ -226,7 +226,7 @@ class Sequence(ParsingExpression):
result = e.parse(parser) result = e.parse(parser)
if result: if result:
results.append(result) results.append(result)
except NoMatch, m: except NoMatch as m:
self._nm_change_rule(m, parser) self._nm_change_rule(m, parser)
raise raise
...@@ -245,7 +245,7 @@ class OrderedChoice(Sequence): ...@@ -245,7 +245,7 @@ class OrderedChoice(Sequence):
try: try:
result = e.parse(parser) result = e.parse(parser)
match = True match = True
except NoMatch, m: except NoMatch as m:
parser.position = self.c_pos # Backtracking parser.position = self.c_pos # Backtracking
self._nm_change_rule(m, parser) self._nm_change_rule(m, parser)
else: else:
...@@ -273,7 +273,6 @@ class Optional(Repetition): ...@@ -273,7 +273,6 @@ class Optional(Repetition):
result = self.nodes[0].parse(parser) result = self.nodes[0].parse(parser)
except NoMatch: except NoMatch:
parser.position = self.c_pos # Backtracking parser.position = self.c_pos # Backtracking
pass
return result return result
...@@ -421,7 +420,7 @@ class Match(ParsingExpression): ...@@ -421,7 +420,7 @@ class Match(ParsingExpression):
comments = [] comments = []
try: try:
match = self._parse(parser) match = self._parse(parser)
except NoMatch, nm: except NoMatch as nm:
# If not matched and not in lexical rule try to match comment # If not matched and not in lexical rule try to match comment
#TODO: Comment handling refactoring. Should think of better way to #TODO: Comment handling refactoring. Should think of better way to
# handle comments. # handle comments.
...@@ -469,12 +468,12 @@ class RegExMatch(Match): ...@@ -469,12 +468,12 @@ class RegExMatch(Match):
if m: if m:
parser.position += len(m.group()) parser.position += len(m.group())
if parser.debug: if parser.debug:
print "Match %s at %d" % (m.group(), self.c_pos) print("Match {} at {}".format(m.group(), self.c_pos))
return Terminal(self.rule if self.root else '', self.c_pos, return Terminal(self.rule if self.root else '', self.c_pos,
m.group()) m.group())
else: else:
if parser.debug: if parser.debug:
print "NoMatch at %d" % self.c_pos print("NoMatch at {}".format(self.c_pos))
parser._nm_raise(self.name, self.c_pos, parser) parser._nm_raise(self.name, self.c_pos, parser)
...@@ -493,12 +492,12 @@ class StrMatch(Match): ...@@ -493,12 +492,12 @@ class StrMatch(Match):
if parser.input[parser.position:].startswith(self.to_match): if parser.input[parser.position:].startswith(self.to_match):
parser.position += len(self.to_match) parser.position += len(self.to_match)
if parser.debug: if parser.debug:
print "Match %s at %d" % (self.to_match, self.c_pos) print("Match {} at {}".format(self.to_match, self.c_pos))
return Terminal(self.rule if self.root else '', self.c_pos, return Terminal(self.rule if self.root else '', self.c_pos,
self.to_match) self.to_match)
else: else:
if parser.debug: if parser.debug:
print "NoMatch at %d" % self.c_pos print("NoMatch at {}".format(self.c_pos))
parser._nm_raise(self.to_match, self.c_pos, parser) parser._nm_raise(self.to_match, self.c_pos, parser)
def __str__(self): def __str__(self):
...@@ -507,6 +506,9 @@ class StrMatch(Match): ...@@ -507,6 +506,9 @@ class StrMatch(Match):
def __eq__(self, other): def __eq__(self, other):
return self.to_match == str(other) return self.to_match == str(other)
def __hash__(self):
return hash(self.to_match)
# HACK: Kwd class is a bit hackish. Need to find a better way to # HACK: Kwd class is a bit hackish. Need to find a better way to
# introduce different classes of string tokens. # introduce different classes of string tokens.
...@@ -537,7 +539,7 @@ class EndOfFile(Match): ...@@ -537,7 +539,7 @@ class EndOfFile(Match):
return Terminal('EOF', self.c_pos, '') return Terminal('EOF', self.c_pos, '')
else: else:
if parser.debug: if parser.debug:
print "EOF not matched." print("EOF not matched.")
parser._nm_raise(self.name, self.c_pos, parser) parser._nm_raise(self.name, self.c_pos, parser)
...@@ -759,12 +761,12 @@ class Parser(object): ...@@ -759,12 +761,12 @@ class Parser(object):
return retval return retval
if self.debug: if self.debug:
print "ASG: First pass" print("ASG: First pass")
asg = tree_walk(self.parse_tree) asg = tree_walk(self.parse_tree)
# Second pass # Second pass
if self.debug: if self.debug:
print "ASG: Second pass" print("ASG: Second pass")
for sa_name, asg_node in for_second_pass: for sa_name, asg_node in for_second_pass:
sem_actions[sa_name].second_pass(self, asg_node) sem_actions[sa_name].second_pass(self, asg_node)
...@@ -872,11 +874,11 @@ class ParserPython(Parser): ...@@ -872,11 +874,11 @@ class ParserPython(Parser):
if rule in __rule_cache: if rule in __rule_cache:
c_rule = __rule_cache.get(rule) c_rule = __rule_cache.get(rule)
if self.debug: if self.debug:
print "Rule %s founded in cache." % rule print("Rule {} founded in cache.".format(rule))
if isinstance(c_rule, CrossRef): if isinstance(c_rule, CrossRef):
self.__cross_refs += 1 self.__cross_refs += 1
if self.debug: if self.debug:
print "CrossRef usage: %s" % c_rule.rule_name print("CrossRef usage: {}".format(c_rule.rule_name))
return c_rule return c_rule
# Semantic action for the rule # Semantic action for the rule
...@@ -893,8 +895,8 @@ class ParserPython(Parser): ...@@ -893,8 +895,8 @@ class ParserPython(Parser):
# Update cache # Update cache
__rule_cache[rule] = retval __rule_cache[rule] = retval
if self.debug: if self.debug:
print "New rule: %s -> %s" % \ print("New rule: {} -> {}".format(rule,
(rule, retval.__class__.__name__) retval.__class__.__name__))
elif isinstance(expression, Match): elif isinstance(expression, Match):
retval = expression retval = expression
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# License: MIT License # License: MIT License
####################################################################### #######################################################################
import StringIO import io
from arpeggio import Terminal from arpeggio import Terminal
...@@ -32,7 +32,7 @@ class Exporter(object): ...@@ -32,7 +32,7 @@ class Exporter(object):
""" """
Export of an obj to a string. Export of an obj to a string.
""" """
self._outf = StringIO() self._outf = io.StringIO()
self._export(obj) self._export(obj)
return self._outf.getvalue() return self._outf.getvalue()
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
# License: MIT License # License: MIT License
####################################################################### #######################################################################
from __future__ import print_function
__all__ = ['ParserPEG'] __all__ = ['ParserPEG']
from arpeggio import * from arpeggio import *
...@@ -49,7 +51,7 @@ class PEGSemanticAction(SemanticAction): ...@@ -49,7 +51,7 @@ class PEGSemanticAction(SemanticAction):
return return
for i,n in enumerate(node.nodes): for i,n in enumerate(node.nodes):
if isinstance(n, Terminal): if isinstance(n, Terminal):
if parser.peg_rules.has_key(n.value): if n.value in parser.peg_rules:
node.nodes[i] = parser.peg_rules[n.value] node.nodes[i] = parser.peg_rules[n.value]
else: else:
raise SemanticError("Rule \"%s\" does not exists." % n) raise SemanticError("Rule \"%s\" does not exists." % n)
...@@ -93,7 +95,7 @@ class SemOrderedChoice(PEGSemanticAction): ...@@ -93,7 +95,7 @@ class SemOrderedChoice(PEGSemanticAction):
class SemPrefix(PEGSemanticAction): class SemPrefix(PEGSemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
if parser.debug: if parser.debug:
print "Prefix: %s " % str(children) print("Prefix: {} ".format(str(children)))
if len(children)==2: if len(children)==2:
if children[0] == NOT(): if children[0] == NOT():
retval = Not() retval = Not()
...@@ -111,10 +113,10 @@ class SemPrefix(PEGSemanticAction): ...@@ -111,10 +113,10 @@ class SemPrefix(PEGSemanticAction):
class SemSufix(PEGSemanticAction): class SemSufix(PEGSemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
if parser.debug: if parser.debug:
print "Sufix : %s" % str(children) print("Sufix : {}".format(str(children)))
if len(children) == 2: if len(children) == 2:
if parser.debug: if parser.debug:
print "Sufix : %s" % str(children[1]) print("Sufix : {}".format(str(children[1])))
if children[1] == STAR(): if children[1] == STAR():
retval = ZeroOrMore(children[0]) retval = ZeroOrMore(children[0])
elif children[1] == QUESTION(): elif children[1] == QUESTION():
...@@ -133,7 +135,7 @@ class SemSufix(PEGSemanticAction): ...@@ -133,7 +135,7 @@ class SemSufix(PEGSemanticAction):
class SemExpression(PEGSemanticAction): class SemExpression(PEGSemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
if parser.debug: if parser.debug:
print "Expression : %s" % str(children) print("Expression : {}".format(str(children)))
if len(children)==1: if len(children)==1:
return children[0] return children[0]
else: else:
...@@ -142,19 +144,19 @@ class SemExpression(PEGSemanticAction): ...@@ -142,19 +144,19 @@ class SemExpression(PEGSemanticAction):
class SemIdentifier(SemanticAction): class SemIdentifier(SemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
if parser.debug: if parser.debug:
print "Identifier %s." % node.value print("Identifier {}.".format(node.value))
return node return node
class SemRegEx(SemanticAction): class SemRegEx(SemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
if parser.debug: if parser.debug:
print "RegEx %s." % children[1].value print("RegEx {}.".format(children[1].value))
return RegExMatch(children[1].value) return RegExMatch(children[1].value)
class SemLiteral(SemanticAction): class SemLiteral(SemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
if parser.debug: if parser.debug:
print "Literal: %s" % node.value print("Literal: {}".format(node.value))
match_str = node.value[1:-1] match_str = node.value[1:-1]
match_str = match_str.replace("\\'", "'") match_str = match_str.replace("\\'", "'")
match_str = match_str.replace("\\\\", "\\") match_str = match_str.replace("\\\\", "\\")
...@@ -198,6 +200,6 @@ class ParserPEG(Parser): ...@@ -198,6 +200,6 @@ class ParserPEG(Parser):
def _from_peg(self, language_def): def _from_peg(self, language_def):
parser = ParserPython(grammar, comment) parser = ParserPython(grammar, comment)
parser.root_rule_name = self.root_rule_name parser.root_rule_name = self.root_rule_name
parse_tree = parser.parse(language_def) parser.parse(language_def)
return parser.getASG() return parser.getASG()
...@@ -8,8 +8,9 @@ ...@@ -8,8 +8,9 @@
# #
# This example demonstrates grammar and parser for bibtex files. # This example demonstrates grammar and parser for bibtex files.
####################################################################### #######################################################################
import pprint from __future__ import print_function
import pprint
import sys import sys
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExporter, PTDOTExporter from arpeggio.export import PMDOTExporter, PTDOTExporter
...@@ -44,7 +45,7 @@ class BibFileSem(SemanticAction): ...@@ -44,7 +45,7 @@ class BibFileSem(SemanticAction):
""" """
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
if parser.debug: if parser.debug:
print "Processing Bibfile" print("Processing Bibfile")
# Return only dict nodes # Return only dict nodes
return [x for x in children if type(x) is dict] return [x for x in children if type(x) is dict]
...@@ -57,7 +58,7 @@ class BibEntrySem(SemanticAction): ...@@ -57,7 +58,7 @@ class BibEntrySem(SemanticAction):
""" """
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
if parser.debug: if parser.debug:
print " Processing bibentry %s" % children[2] print(" Processing bibentry %s" % children[2])
bib_entry_map = { bib_entry_map = {
'bibtype': children[0].value, 'bibtype': children[0].value,
'bibkey': children[2].value 'bibkey': children[2].value
...@@ -74,7 +75,7 @@ class FieldSem(SemanticAction): ...@@ -74,7 +75,7 @@ class FieldSem(SemanticAction):
""" """
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
if parser.debug: if parser.debug:
print " Processing field %s" % children[0] print(" Processing field %s" % children[0])
field = (children[0].value, children[2]) field = (children[0].value, children[2])
return field return field
...@@ -136,5 +137,5 @@ if __name__ == "__main__": ...@@ -136,5 +137,5 @@ if __name__ == "__main__":
pp.pprint(ast) pp.pprint(ast)
else: else:
print "Usage: python bibtex.py file_to_parse" print("Usage: python bibtex.py file_to_parse")
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Name: calc.py # Name: calc.py
# Purpose: Simple expression evaluator example # Purpose: Simple expression evaluator example
# Author: Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com> # Author: Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com>
# Copyright: (c) 2009 Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com> # Copyright: (c) 2009-2014 Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com>
# License: MIT License # License: MIT License
# #
# This example demonstrates grammar definition using python constructs as # This example demonstrates grammar definition using python constructs as
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# notation. # notation.
####################################################################### #######################################################################
from arpeggio import * from arpeggio import Optional, ZeroOrMore, OneOrMore, EndOfFile, SemanticAction, ParserPython
from arpeggio.export import PMDOTExporter, PTDOTExporter from arpeggio.export import PMDOTExporter, PTDOTExporter
from arpeggio import RegExMatch as _ from arpeggio import RegExMatch as _
...@@ -28,7 +28,7 @@ class ToFloat(SemanticAction): ...@@ -28,7 +28,7 @@ class ToFloat(SemanticAction):
Converts node value to float. Converts node value to float.
""" """
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Converting %s." % node.value print("Converting {}.".format(node.value))
return float(node.value) return float(node.value)
class Factor(SemanticAction): class Factor(SemanticAction):
...@@ -36,17 +36,17 @@ class Factor(SemanticAction): ...@@ -36,17 +36,17 @@ class Factor(SemanticAction):
Removes parenthesis if exists and returns what was contained inside. Removes parenthesis if exists and returns what was contained inside.
""" """
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Factor %s" % children print("Factor {}".format(children))
if len(children) == 1: if len(children) == 1:
return children[0] return children[0]
sign = -1 if children[0] == '-' else 1 sign = -1 if children[0] == '-' else 1
next = 0 next_chd = 0
if children[0] in ['+', '-']: if children[0] in ['+', '-']:
next = 1 next_chd = 1
if children[next] == '(': if children[next_chd] == '(':
return sign * children[next+1] return sign * children[next_chd+1]
else: else:
return sign * children[next] return sign * children[next_chd]
class Term(SemanticAction): class Term(SemanticAction):
""" """
...@@ -54,14 +54,14 @@ class Term(SemanticAction): ...@@ -54,14 +54,14 @@ class Term(SemanticAction):
Factor nodes will be already evaluated. Factor nodes will be already evaluated.
""" """
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Term %s" % children print("Term {}".format(children))
term = children[0] term = children[0]
for i in range(2, len(children), 2): for i in range(2, len(children), 2):
if children[i-1]=="*": if children[i-1]=="*":
term *= children[i] term *= children[i]
else: else:
term /= children[i] term /= children[i]
print "Term = %f" % term print("Term = {}".format(term))
return term return term
class Expr(SemanticAction): class Expr(SemanticAction):
...@@ -70,7 +70,7 @@ class Expr(SemanticAction): ...@@ -70,7 +70,7 @@ class Expr(SemanticAction):
Term nodes will be already evaluated. Term nodes will be already evaluated.
""" """
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Expression %s" % children print("Expression {}".format(children))
expr = 0 expr = 0
start = 0 start = 0
# Check for unary + or - operator # Check for unary + or - operator
...@@ -83,7 +83,7 @@ class Expr(SemanticAction): ...@@ -83,7 +83,7 @@ class Expr(SemanticAction):
else: else:
expr += children[i] expr += children[i]
print "Expression = %f" % expr print("Expression = {}".format(expr))
return expr return expr
class Calc(SemanticAction): class Calc(SemanticAction):
...@@ -111,10 +111,10 @@ if __name__ == "__main__": ...@@ -111,10 +111,10 @@ if __name__ == "__main__":
PMDOTExporter().exportFile(parser.parser_model, "calc_parse_tree_model.dot") PMDOTExporter().exportFile(parser.parser_model, "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_expr = "-(4-1)*5+(2+4.67)+5.89/(.2+7)"
# We create a parse tree out of textual input # We create a parse tree out of textual input_expr
parse_tree = parser.parse(input) parse_tree = parser.parse(input_expr)
# 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. # This is also optional.
...@@ -122,6 +122,6 @@ if __name__ == "__main__": ...@@ -122,6 +122,6 @@ if __name__ == "__main__":
# getASG will start semantic analysis. # getASG will start semantic analysis.
# In this case semantic analysis will evaluate expression and # In this case semantic analysis will evaluate expression and
# returned value will be the result of the input expression. # returned value will be the result of the input_expr expression.
print "%s = %f" % (input, parser.getASG()) print("{} = {}".format(input_expr, parser.getASG()))
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Name: calc_peg.py # Name: calc_peg.py
# Purpose: Simple expression evaluator example using PEG language # Purpose: Simple expression evaluator example using PEG language
# Author: Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com> # Author: Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com>
# Copyright: (c) 2009 Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com> # Copyright: (c) 2009-2014 Igor R. Dejanovic <igor DOT dejanovic AT gmail DOT com>
# License: MIT License # License: MIT License
# #
# This example is functionally equivalent to calc.py. The difference is that # This example is functionally equivalent to calc.py. The difference is that
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
# Parser model as well as parse tree exported to dot files should be # Parser model as well as parse tree exported to dot files should be
# the same as parser model and parse tree generated in calc.py example. # the same as parser model and parse tree generated in calc.py example.
####################################################################### #######################################################################
from __future__ import absolute_import
from arpeggio import *
from arpeggio.peg import ParserPEG from arpeggio.peg import ParserPEG
from arpeggio.export import PMDOTExporter, PTDOTExporter from arpeggio.export import PMDOTExporter, PTDOTExporter
...@@ -50,17 +50,17 @@ parser = ParserPEG(calc_grammar, "calc", debug=True) ...@@ -50,17 +50,17 @@ parser = ParserPEG(calc_grammar, "calc", debug=True)
PMDOTExporter().exportFile(parser.parser_model, "calc_peg_parser_model.dot") PMDOTExporter().exportFile(parser.parser_model, "calc_peg_parser_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_expr = "-(4-1)*5+(2+4.67)+5.89/(.2+7)"
# Then parse tree is created out of the input expression. # Then parse tree is created out of the input_expr expression.
parse_tree = parser.parse(input) parse_tree = parser.parse(input_expr)
# We save it to dot file in order to visualise it. # We save it to dot file in order to visualise it.
PTDOTExporter().exportFile(parse_tree, "calc_peg_parse_tree.dot") PTDOTExporter().exportFile(parse_tree, "calc_peg_parse_tree.dot")
# getASG will start semantic analysis. # getASG will start semantic analysis.
# In this case semantic analysis will evaluate expression and # In this case semantic analysis will evaluate expression and
# returned value will be evaluated result of the input expression. # returned value will be evaluated result of the input_expr expression.
# Semantic actions are supplied to the getASG function. # Semantic actions are supplied to the getASG function.
print "%s = %f" % (input, parser.getASG(sem_actions)) print("{} = {}".format(input_expr, parser.getASG(sem_actions)))
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
# right # right
# end # end
####################################################################### #######################################################################
from __future__ import print_function
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExporter, PTDOTExporter from arpeggio.export import PMDOTExporter, PTDOTExporter
...@@ -34,34 +35,38 @@ def right(): return 'right' ...@@ -34,34 +35,38 @@ def right(): return 'right'
# Semantic actions # Semantic actions
class Up(SemanticAction): class Up(SemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Going up" print("Going up")
return (0, 1) return (0, 1)
class Down(SemanticAction): class Down(SemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Going down" print("Going down")
return (0, -1) return (0, -1)
class Left(SemanticAction): class Left(SemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Going left" print("Going left")
return (-1, 0) return (-1, 0)
class Right(SemanticAction): class Right(SemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Going right" print("Going right")
return (1, 0) return (1, 0)
class Command(SemanticAction): class Command(SemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Command" print("Command")
return nodes[0] return children[0]
class Program(SemanticAction): class Program(SemanticAction):
def first_pass(self, parser, node, children): def first_pass(self, parser, node, children):
print "Evaluating position" print("Evaluating position")
return reduce(lambda x, y: (x[0]+y[0], x[1]+y[1]), children[1:-2]) position = [0, 0]
for move in children[1:-2]:
position[0] += move[0]
position[1] += move[1]
return position
# Connecting rules with semantic actions # Connecting rules with semantic actions
program.sem = Program() program.sem = Program()
...@@ -108,5 +113,5 @@ if __name__ == "__main__": ...@@ -108,5 +113,5 @@ if __name__ == "__main__":
# getASG will start semantic analysis. # getASG will start semantic analysis.
# In this case semantic analysis will evaluate expression and # In this case semantic analysis will evaluate expression and
# returned value will be the final position of the robot. # returned value will be the final position of the robot.
print "position = ", parser.getASG() print("position = ", parser.getASG())
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
# right # right
# end # end
####################################################################### #######################################################################
from __future__ import print_function
from arpeggio import * from arpeggio import *
from arpeggio.export import PMDOTExporter, PTDOTExporter from arpeggio.export import PMDOTExporter, PTDOTExporter
...@@ -82,5 +83,5 @@ if __name__ == "__main__": ...@@ -82,5 +83,5 @@ if __name__ == "__main__":
# getASG will start semantic analysis. # getASG will start semantic analysis.
# In this case semantic analysis will evaluate expression and # In this case semantic analysis will evaluate expression and
# returned value will be the final position of the robot. # returned value will be the final position of the robot.
print "position = ", parser.getASG(sem_actions=semantic_actions) print("position = ", parser.getASG(sem_actions=semantic_actions))
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