From: Eric S. Raymond Date: Wed, 14 Jan 2004 19:03:32 +0000 (+0000) Subject: Summand parsing is screwed up. X-Git-Tag: 1.0~196 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=80e69123c791759a2884db77b4c9fefdb8a7dd5a;p=mad.git Summand parsing is screwed up. --- diff --git a/mad b/mad index 42dead6..d99123d 100755 --- a/mad +++ b/mad @@ -81,9 +81,10 @@ precedence = ( ('right', 'ABS', 'UPLUS') ) -cards = [] +deck = [] scopes = [] targets = [] +untyped = [] # Program level @@ -93,11 +94,11 @@ def p_program(t): def p_card(t): 'card : TAB statement SEMI' - cards.append((None, t[2])) + deck.append((None, t[2])) def p_labeled_card(t): 'card : NAME TAB statement SEMI' - cards.append((t[1], t[3])) + deck.append((t[1], t[3])) # Statement level @@ -183,6 +184,8 @@ def p_whenever_complex(t): def p_statement_substitution(t): 'statement : NAME EQUALS expression' t[0] = ('substitution', t[1], t[3]) + if t[1] not in untyped: + untyped.append(t[1]) # Expression parsing @@ -191,6 +194,7 @@ def p_expression_binop1(t): | expression MINUS expression | expression TIMES expression | expression DIVIDE expression''' + print "Foo" t[0] = (t[2].lower(), t[1], t[3]) def p_expression_binop2(t): @@ -234,7 +238,7 @@ def p_expression_integer(t): def p_expression_float(t): 'expression : FLOATNUM' - t[0] = ('float', t[1]) + t[0] = ('floatnum', t[1]) def p_expression_subscript(t): 'expression : NAME application' @@ -270,18 +274,31 @@ yacc.yacc() import sys, re -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 +integers = [] +floats = [] +bools = [] +dimensions = {} + +def declare(var, lst): + if var in untyped: + untyped.remove(var) + lst.append(var) + +def analyze(deck): + "Gather variable types." + global integers, floats, bools + for (label, statement) in deck: + if statement[0] == 'integer': + print "Bar!", statement + for var in statement[1:]: + declare(var, integers) + elif statement[0] == 'dimension': + for (var, dimlist) in statement[1]: + dimensions[var] = dimlist + elif statement[0] == 'substitution': + var = statement[1] + if var not in integers + bools + floats + untyped: + untyped.append(var) def print_expr(t): if t[0] == 'variable': @@ -312,7 +329,7 @@ def print_expr(t): 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': + elif t[0] == 'p': 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])) @@ -328,33 +345,23 @@ def print_expr(t): return "%s" % print_expr(t[1]) elif t[0] == '-': return "(-%s)" % print_expr(t[1]) - elif t[0] == 'intnum': + elif t[0] in ('intnum', 'floatnum'): return 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] + ";") + if statement[0] in ('dimension', 'end_program', 'integer'): + pass elif statement[0] == 'for': (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] == 'goto': + return "goto " + statement[1] + ";" elif statement[0] == 'if': - return "if (" + print_expr(statement[1]) + ") " + print_statement(statement[2]) + ";" - elif statement[0] == 'integer': - return "int " + ", ".join(statement[1:]) + ";" + return "if (" + print_expr(statement[1]) + ") " + print_statement(statement[2]) elif statement[0] == 'substitution': - return statement[1] + " = " + print_expr(statement[2]) + return statement[1] + " = " + print_expr(statement[2]) + ";" else: return(`statement`) @@ -362,16 +369,30 @@ 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) + yacc.parse(source, debug=1) + + analyze(deck) print "#include " print "main(int argc, char *argv[])" print "{" - for (label, statement) in cards: + if integers: + print "\tint " + ", ".join(integers) + ";\t/* INTEGER */" + if bools: + print "\tint " + ", ".join(bools) + ";\t/* boolean */" + if untyped: + print "\tint " + ", ".join(untyped) + ";\t/* untyped */" + if floats: + print "\tfloat " + ", ".join(floats) + ";" + indent = 0 + for (label, statement) in deck: if label in targets: sys.stdout.write(label+":") - sys.stdout.write("\t" + " "*indent +print_statement(statement) + "\n") + rep = print_statement(statement) + if rep: + sys.stdout.write("\t" + " "*indent + rep + "\n") + if rep[-1] == '{': + indent += 1 if label in scopes: indent -= 1 print ("\t" + " "*indent) + "}"