数式を解くプログラム その1 - 概要

下記の掲示板での質問に触発されて、私も
数式を解くプログラムをC#3.0で作ってみました。

■電卓 ((1+2)3)カッコの入れ子
http://bbs.wankuma.com/index.cgi?mode=al2&namber=32500

数式といっても対応するのは、四則演算(+, -, *, /)と丸括弧による演算のみで、数値についてはすべてdecimal型(System.Decimal)として扱うことにします。このプログラムでOKな式とNGな式の例を以下に示します。
【OKな式の例】

  • 1+(2-3)*4/5
  • 10+((9-8)*3)/2
  • -2 * 3.14 + 0 - 1.414
  • +8.9+10


【NGな式の例】

  • 1+a
  • 2**3
  • )1+3(
  • 100+20+

さて、例示だけでやろうとしていることは十分に伝わると思いますが、厳密さに欠けます。そこで、ここで取り扱う数式の文法を拡張したBNFで定義しておきます。BNFって何?という方は以下を参考にしてください。
wikipedia:バッカス・ナウア記法

   ::=  ('+' )* |  ('-' )*
         ::=  ('*' )* |  ('/' )*
       ::= '('  ')' | '+'  | '-'  | 
       ::= ('.'*)+
      ::= * | '0'
 ::= '1'...'9'
        ::= '0'...'9'
※字句と字句の間のホワイトスペースは無視するものとする。

< >で囲った部分は非終端記号といい、' 'で囲った部分はその文字そのものを表し、終端記号といいます。(非終端記号というのは文法を構成する抽象的要素で、終端記号は具体的な要素、というくらいの理解で十分です。) ( )で囲まれた部分はそれを1グループとして扱い、*はその直前の要素が0以上現れ、+は0または1回現れることを意味します。正規表現に似せたルールにしているのでなんとなくは理解できると思います。

数値はで定義しています。数値は0または1以上の整数部分で始まり、オプションで小数部を付けることができるものとしています。一般的なプログラミング言語でよく許可されている、「.5」(0.5の意味)や「1.」(.は単純に無視)は、許可しないようにします。これは単純に私の好みです。

今回はここまでの説明に加えて、このプログラムで作るクラスを一覧できる図を掲載して終わります。次回は字句解析部分を解説する予定です。