'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
'NOT', 'OR', 'AND', 'THEN', 'EQV',
'EQ', 'NE', 'LT', 'LE', 'GT', 'GE',
- 'ABS', 'EXP',
+ 'ABS', 'POW',
)
# Tokens
t_TAB = r'\t'
t_COMMA = r'\,'
t_ABS = r'\.ABS\.'
-t_EXP = r'\.P\.'
+t_POW = r'\.P\.'
t_NOT = r'\.NOT\.'
t_OR = r'\.OR\.'
t_AND = r'\.AND\.'
t.type = reserved_map.get(t.value, "NAME")
if t.type and t.value[-1] == '.':
t.type = 'FUNCALL'
+ t.value = t.value.lower()
return t
t_ignore = " \n"
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
- ('left','EXP'),
+ ('left','POW'),
('right', 'ABS', 'UPLUS')
)
cards = []
+scopes = []
+targets = []
# Program level
## DIMENSION
def p_statement_dimension(t):
'statement : DIMENSION dimension_list'
- t[0] = ('dimension', t[1], t[2])
+ t[0] = ('dimension', t[2])
def p_dimension_list(t):
'dimension_list : NAME application'
t[0] = [[t[1], tuple(t[2])]]
## END
def p_end_of_program(t):
"statement : END OF PROGRAM"
- t[0] = ('end_program')
+ t[0] = ('end_program',)
def p_end_of_conditional(t):
"statement : END OF CONDITIONAL"
- t[0] = ('end_conditional')
+ t[0] = ('end_conditional',)
def p_end_of_functions(t):
"statement : END OF FUNCTION"
- t[0] = ('end_function')
+ t[0] = ('end_function',)
## INTEGER
def p_integer(t):
## THROUGH
def p_through_for(t):
'statement : THROUGH NAME COMMA FOR NAME EQUALS expression COMMA expression COMMA expression'
- t[0] = ('for', t[2], t[7], t[9], t[11])
+ t[0] = ('for', t[2], t[5], t[7], t[9], t[11])
+ scopes.append(t[2])
def p_through_map(t):
'statement : THROUGH NAME COMMA FOR VALUES OF NAME EQUALS value_list'
t[0] = ('map', t[2], t[7], t[9])
+ scopes.append(t[2])
def p_map(t):
'value_list : expression'
t[0] = [t[1]]
def p_transfer(t):
"statement : TRANSFER TO NAME"
t[0] = ('goto', t[3])
+ targets.append(t[3])
## WHENEVER
def p_whenever_simple(t):
# "statement : VECTOR VALUES assignlist"
# t[0] = ('values',) + tuple(t[3])
-
## Assignment
def p_statement_substitution(t):
'statement : NAME EQUALS expression'
| expression GE expression
| expression EQ expression
| expression NE expression
- | expression EXP expression
+ | expression POW expression
'''
t[0] = (t[2][1:-1].lower(), t[1], t[3])
def p_expression_integer(t):
'expression : INTNUM'
- t[0] = ('integer', t[1])
+ t[0] = ('intnum', t[1])
def p_expression_float(t):
'expression : FLOATNUM'
import sys, re
-source = sys.stdin.read()
-# Grotty hack to add end-of-statement delimiters
-source = re.sub("\n([A-Z]|\t)", " ;\n\\1", source).rstrip() + " ;\n"
-yacc.parse(source, debug=1)
-for card in cards:
- print card
+indent = 0
+
+def recode(cards):
+ "Rewrite the statement list."
+ # Find first INTEGER declaration, move it to the front.
+ for statement in cards:
+ if statement[1][0] == 'integer':
+ declaration = statement
+ cards.remove(declaration)
+ cards = [declaration] + cards
+ break
+ return cards
+
+def print_expr(t):
+ if t[0] == 'variable':
+ res = t[1]
+ if len(t) > 2:
+ for dim in t[2]:
+ res += "[" + dim[1] + "]"
+ return res
+ elif t[0] == 'apply':
+ return t[1] + `t[2]`
+ elif t[0] == 'plus':
+ return "(%s + %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'minus':
+ return "(%s - %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'times':
+ return "(%s * %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'divide':
+ return "(%s / %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'l':
+ return "(%s < %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'g':
+ return "(%s > %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'le':
+ return "(%s <= %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'ge':
+ return "(%s >= %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'e':
+ return "(%s == %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'ne':
+ return "(%s != %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'pow':
+ return "pow(%s, %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'and':
+ return "(%s && %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'or':
+ return "(%s || %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'then':
+ return "!(%s && !(%s))" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'eqv':
+ return "(%s == %s)" % (print_expr(t[1]), print_expr(t[2]))
+ elif t[0] == 'abs':
+ return "abs(%s)" % print_expr(t[1])
+ elif t[0] == '+':
+ return "%s" % print_expr(t[1])
+ elif t[0] == '-':
+ return "(-%s)" % print_expr(t[1])
+ elif t[0] in ('variable', 'intnum'):
+ return "%s" % print_expr(t[1])
+ else:
+ return "***"+`t`
+
+def print_statement(statement):
+ global indent
+ if statement[0] == 'end_program':
+ return "/* END OF PROGRAM */"
+ elif statement[0] == 'dimension':
+ declaration = "int";
+ for (var, dimlist) in statement[1]:
+ declaration += " " + var
+ for dim in dimlist:
+ declaration += "[" + dim[1] + "]"
+ declaration += ", "
+ return(declaration[:-2] + ";")
+ elif statement[0] == 'for':
+ print statement
+ (keyword, label, dummy, start, increment, predicate) = statement
+ indent += 1
+ return "for (%s = %s; %s; %s += %s) {" % (dummy, print_expr(start), print_expr(predicate), dummy, print_expr(increment))
+ elif statement[0] == 'if':
+ return "if (" + print_expr(statement[1]) + ") " + print_statement(statement[2]) + ";"
+ elif statement[0] == 'integer':
+ return "int " + ", ".join(statement[1:]) + ";"
+ elif statement[0] == 'substitution':
+ return statement[1] + " = " + print_expr(statement[2])
+ else:
+ return(`statement`)
+
+if __name__ == '__main__':
+ source = sys.stdin.read()
+ # Grotty hack to add end-of-statement delimiters
+ source = re.sub("\n([A-Z]|\t)", " ;\n\\1", source).rstrip() + " ;\n"
+ yacc.parse(source)
+ cards = recode(cards)
+
+ print "#include <math.h>"
+ print "main(int argc, char *argv[])"
+ print "{"
+ for (label, statement) in cards:
+ if label in targets:
+ sys.stdout.write(label+":")
+ sys.stdout.write("\t" + " "*indent +print_statement(statement) + "\n")
+ if label in scopes:
+ indent -= 1
+ print ("\t" + " "*indent) + "}"
+ print "}"