わんくま同盟 大阪勉強会 #12 お疲れっした。
アクアさんによる「電卓祭りの報告」のビデオを楽しみにしてます。
僕は逆ポーランド16進電卓で参加したんですが、
もいっこ考えててボツになったのがありまして、数式電卓。
数式をそのまんま入力し"計算"ボタンを押すと一気に計算ってやつ。
入力された数式、たとえば"(4+2)/2"を構文解析し、
↓みたいな構文木をこさえます。
ほんでもって"計算"ボタン押したら
木の根(この例では'÷')に対して"評価しろ!"って言うの。
"÷の評価"
→ "+の評価" / "2の評価"
→ ("4の評価" + "2の評価") / "2の評価"
→ (4 + 2) / 2
→ 3
なんてな。
using System;
namespace Formula {
interface IVal {
int val { get; }
}
// 数
class Number : IVal {
private int value_;
public int val { get { return value_; }}
public Number(int value) { value_ = value; }
public override string ToString()
{ return value_.ToString(); }
}
#region 単項演算子
abstract class UnaryOperator : IVal {
public abstract int val { get; }
protected IVal node_;
public UnaryOperator(IVal node) { node_ = node; }
}
// 単項'-'
class Negate : UnaryOperator {
public override int val { get { return -node_.val; }}
public Negate(IVal node) : base(node) {}
public override string ToString()
{ return string.Format("-{0}", node_.ToString()); }
}
#endregion
#region 二項演算子
abstract class BinaryOperator : IVal {
public abstract int val { get; }
protected IVal node1_;
protected IVal node2_;
protected string format_;
public BinaryOperator(IVal n1, IVal n2) { node1_ = n1; node2_ = n2; }
public override string ToString()
{ return string.Format(format_, node1_.ToString(), node2_.ToString()); }
}
class Minus : BinaryOperator {
public override int val { get { return node1_.val - node2_.val; }}
public Minus(IVal n1, IVal n2) : base(n1,n2) { format_ = "({0}-{1})"; }
}
class Divides : BinaryOperator {
public override int val { get { return node1_.val / node2_.val; }}
public Divides(IVal n1, IVal n2) : base(n1, n2) { format_ = "({0}/{1})"; }
}
class Plus : BinaryOperator {
public override int val { get { return node1_.val + node2_.val; }}
public Plus(IVal n1, IVal n2) : base(n1, n2) { format_ = "({0}+{1})"; }
}
class Multiplies : BinaryOperator {
public override int val { get { return node1_.val * node2_.val; } }
public Multiplies(IVal n1, IVal n2) : base(n1,n2) { format_ = "({0}*{1})"; }
}
#endregion
class Program {
static void Main() {
// "(4+2)/2"の構文木を評価する
IVal formula = new Plus(new Number(4), new Number(2));
formula = new Divides(formula, new Number(2));
Console.WriteLine("{0} = {1}", formula.ToString(), formula.val);
}
}
}
このやり方だと"プログラム電卓"てゆーか"電卓インタプリタ"が作れます♪