This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -0,0 +1,43 @@
import std.stdio, std.string, std.array;
void parseRPN(in string e) {
enum nPrec = 9;
static struct Info { int prec; bool rAssoc; }
immutable /*static*/ opa = ["^": Info(4, true),
"*": Info(3, false),
"/": Info(3, false),
"+": Info(2, false),
"-": Info(2, false)];
writeln("\nPostfix input: ", e);
static struct Sf { int prec; string expr; }
Sf[] stack;
foreach (immutable tok; e.split()) {
writeln("Token: ", tok);
if (tok in opa) {
immutable op = opa[tok];
immutable rhs = stack.back;
stack.popBack();
auto lhs = &stack.back;
if (lhs.prec < op.prec ||
(lhs.prec == op.prec && op.rAssoc))
lhs.expr = "(" ~ lhs.expr ~ ")";
lhs.expr ~= " " ~ tok ~ " ";
lhs.expr ~= (rhs.prec < op.prec ||
(rhs.prec == op.prec && !op.rAssoc)) ?
"(" ~ rhs.expr ~ ")" :
rhs.expr;
lhs.prec = op.prec;
} else
stack ~= Sf(nPrec, tok);
foreach (immutable f; stack)
writefln(` %d "%s"`, f.prec, f.expr);
}
writeln("Infix result: ", stack[0].expr);
}
void main() {
foreach (immutable test; ["3 4 2 * 1 5 - 2 3 ^ ^ / +",
"1 2 + 3 4 + ^ 5 6 + ^"])
parseRPN(test);
}

View file

@ -0,0 +1,35 @@
import std.stdio, std.typecons, std.string, std.array, std.algorithm;
void rpmToInfix(in string str) {
alias Exp = Tuple!(int,"p", string,"e");
immutable P = (in Exp pair, in int prec) pure =>
pair.p < prec ? format("( %s )", pair.e) : pair.e;
immutable F = (string[] s...) pure nothrow => s.join(" ");
writefln("=================\n%s", str);
Exp[] stack;
foreach (const w; str.split) {
if (w.isNumeric)
stack ~= Exp(9, w);
else {
const y = stack.back; stack.popBack;
const x = stack.back; stack.popBack;
switch (w) {
case "^": stack ~= Exp(4, F(P(x, 5), w, P(y, 4)));
break;
case "*", "/": stack ~= Exp(3, F(P(x, 3), w, P(y, 3)));
break;
case "+", "-": stack ~= Exp(2, F(P(x, 2), w, P(y, 2)));
break;
default: throw new Error("Wrong part: " ~ w);
}
}
stack.map!q{ a[1] }.writeln;
}
writeln("-----------------\n", stack.back.e);
}
void main() {
"3 4 2 * 1 5 - 2 3 ^ ^ / +".rpmToInfix;
"1 2 + 3 4 + ^ 5 6 + ^".rpmToInfix;
}

View file

@ -1,5 +1,6 @@
from math import log as ln
from math import sqrt, log, exp, sin, cos, tan, pi, e
from ast import literal_eval
"""
>>> # EXAMPLE USAGE
@ -34,8 +35,6 @@ arity_dict = {'abs':1, 'sqrt':1, 'exp':1, 'log':1, 'ln':1,
class Node:
def __init__(self,x,op,y=None):
global prec_dict,assoc_dict,arity_dict
self.precedence = prec_dict[op]
self.assocright = assoc_dict[op]
self.arity = arity_dict[op]
@ -91,22 +90,16 @@ class Node:
"""
return 'Node(%s,%s,%s)'%(repr(self.x), repr(self.op), repr(self.y))
def __cmp__(self, other):
"""
polymorphic comparisons to determine precedence
>>> Node('3','+','4') < Node('6','*','7') < Node('3','**','4')
True
>>> Node('3','+','4') == Node('6','+','7')
True
>>> Node('3','+','4') == '-'
True
>>> Node('3','**','4') < '1'
True
"""
def __lt__(self, other):
if isinstance(other, Node):
return cmp(self.precedence, other.precedence)
return cmp(self.precedence, prec_dict.get(other,9))
return self.precedence < other.precedence
return self.precedence < prec_dict.get(other,9)
def __gt__(self, other):
if isinstance(other, Node):
return self.precedence > other.precedence
return self.precedence > prec_dict.get(other,9)
def rpn_to_infix(s, VERBOSE=False):
@ -168,8 +161,6 @@ def rpn_to_infix(s, VERBOSE=False):
>>> rpn_to_infix('3 4 2 * 1 -5 - ln 2 3 ** ** / +')
'3 + 4 * 2 / ln(1 + 5) ** 2 ** 3'
"""
global prec_dict, arity_dict
if VERBOSE : print('TOKEN STACK')
stack=[]
@ -203,21 +194,20 @@ def rpn_eval(s):
True
"""
global prec_dict, arity_dict
stack=[]
for token in s.replace('^','**').split():
if token in prec_dict:
if arity_dict[token] == 1:
stack.append(eval('%s(%s)'%(token,stack.pop())))
stack.append(literal_eval('%s(%s)'%(token,stack.pop())))
elif arity_dict[token] == 2:
x,y=stack.pop(),stack.pop()
stack.append(eval('(%s) %s %s'%(y,token,x)))
stack.append(literal_eval('(%s) %s %s'%(y,token,x)))
else:
stack.append(token)
return stack[0]
if __name__ == "__main__":
import doctest
doctest.testmod()
strTest = "3 4 2 * 1 -5 - ln 2 3 ** ** / +"
strResult = rpn_to_infix(strTest)
print ("Input: ",strTest)
print ("Output:",strResult)