新しく発言する EXIT インデックスへ
計算式から結果を返すFunction

  計算式から結果を返すFunction2004/05/02 13:20:43 
  SAMPLEフォルダにあるINTERPRE.BASを参考に... 白石 和夫 2004/05/02 14:20:46 
   └ありがとうございます。参考になります。2004/05/02 16:09:45 
    └基本的な考え方は同じなので,容易に拡張で... 白石 和夫 2004/05/02 23:30:47 
     └なるほど、そうですね。2004/05/03 08:39:17 
      └大体理解できました。2004/05/04 16:30:36 
       └一応出来ました。2004/05/07 21:37:03 
        └これだと,関数の中に加減算を含む式が書け... 白石 和夫 2004/05/08 12:14:19 
         ├ちなみに,interpre.basで実装しているのは... 白石 和夫 2004/05/08 12:17:51 
         └数値一次子=符号なし数値定数|数値変数名... 白石 和夫 2004/05/08 13:25:19 
          └テストしましたが関数の中に加減算を含む式...2004/05/08 14:17:26 
           └よく見たら 白石 和夫 2004/05/08 18:19:56 

  計算式から結果を返すFunction2004/05/02 13:20:43  ツリーへ

計算式から結果を返すFunction 返事を書く
2004/05/02 13:20:43
以前に計算式を入力して計算できないかという質問がありました。
時々考えていたのですが、かなり複雑で実現できないのですが、
方法は少しまとまりましたのでどなたかチャレンジしてみてもらえないでしょうか?

計算式は文字列として与えられたとき、
一文字づつ読み込んで判断しながら必要な段階で確保したスタックに数値、演算、関数を入れて置いて、
必要な段階で計算を実行することで可能になると思うのですがどうでしょうか?

  SAMPLEフォルダにあるINTERPRE.BASを参考に... 白石 和夫 2004/05/02 14:20:46  ツリーへ

Re: 計算式から結果を返すFunction 返事を書く
白石 和夫 2004/05/02 14:20:46
SAMPLEフォルダにあるINTERPRE.BASを参考にしてください。

   └ありがとうございます。参考になります。2004/05/02 16:09:45  ツリーへ

Re: SAMPLEフォルダにあるINTERPRE.BASを参考に... 返事を書く
2004/05/02 16:09:45
ありがとうございます。参考になります。

でも私が考えていたのと少し違うようで、
関数も使えて2つまでの変数が渡せるようなものが欲しかったのですが、やはりかなり難しい様な?

    └基本的な考え方は同じなので,容易に拡張で... 白石 和夫 2004/05/02 23:30:47  ツリーへ

Re: ありがとうございます。参考になります。 返事を書く
白石 和夫 2004/05/02 23:30:47
基本的な考え方は同じなので,容易に拡張できます。
なお,Full BASICでは,明示的にスタックを作らずに,外部手続き内の変数を使うことで数式を評価するプログラムが作れます。逆ポーランド記法に変換したものを用意してそれを解釈実行する手法は再帰が苦手な言語向きでしょう。

     └なるほど、そうですね。2004/05/03 08:39:17  ツリーへ

Re: 基本的な考え方は同じなので,容易に拡張で... 返事を書く
2004/05/03 08:39:17
なるほど、そうですね。
じっくり考えてみます。

      └大体理解できました。2004/05/04 16:30:36  ツリーへ

Re: なるほど、そうですね。 返事を書く
2004/05/04 16:30:36
大体理解できました。
さすが白石先生、素晴らしいアルゴリズムです。
十進BASICが他の中間言語翻訳型BASICと比較して圧倒的な処理速度を持つ理由が解ったような気がします。
全く無駄の無い簡潔な記述や、こんな使い方が出来るのかと良い勉強になりました。
確かに少し付け加えるだけで完成できそうです。ありがとうございます。

       └一応出来ました。2004/05/07 21:37:03  ツリーへ

Re: 大体理解できました。 返事を書く
2004/05/07 21:37:03
一応出来ました。
バグがあるかと思いますが、最初と最後だけ書き換えてとりあえず動くようになりました。
ありがとうございました。

REM 文字式から計算するプログラム
REM 零除算エラーなどは考慮していない。
DECLARE EXTERNAL FUNCTION interpreter.fnstr ! 数値式関数
DECLARE EXTERNAL STRING interpreter.s$ ! 入力行
DECLARE EXTERNAL NUMERIC interpreter.X ! 変数x
DECLARE EXTERNAL NUMERIC interpreter.Y ! 変数y
INPUT PROMPT "X,Y=": x,y
LET s$="X^2+Y" !例1
PRINT s$,fnstr
LET s$="(sin(X))^2+(cos(x))^2"  !例2
PRINT s$,fnstr
END

MODULE interpreter
OPTION ANGLE DEGREES
PUBLIC STRING s$
PUBLIC NUMERIC i
PUBLIC NUMERIC X
PUBLIC NUMERIC Y
PUBLIC FUNCTION fnstr
PUBLIC SUB skip
SHARE FUNCTION expression,term,factor,primary,numeric
PUBLIC STRING num$
PUBLIC STRING func$
LET func$="ABS,COS,EXP,INT,LOG,SIN,SGN,SQR,TAN"

EXTERNAL FUNCTION fnstr
LET s$=UCASE$(s$)
LET i=1
CALL skip
LET fnstr=expression
END FUNCTION
-
-
-
EXTERNAL FUNCTION numeric
OPTION ANGLE DEGREES
DECLARE NUMERIC i0
DECLARE NUMERIC p
CALL skip

LET p=POS(func$,s$(i:i+2),1)
IF p>0 THEN
LET i=i+3
SELECT CASE p
CASE 1
LET numeric=ABS(primary)
CASE 5
LET numeric=COS(primary)
CASE 9
LET numeric=EXP(primary)
CASE 13
LET numeric=INT(primary)
CASE 17
LET numeric=LOG(primary)
CASE 21
LET numeric=SIN(primary)
CASE 25
LET numeric=SGN(primary)
CASE 29
LET numeric=SQR(primary)
CASE 33
LET numeric=TAN(primary)
CASE ELSE
END SELECT
ELSEIF s$(i:i)="X" THEN
LET i=i+1
LET numeric=X
CALL skip
ELSEIF s$(i:i)="Y" THEN
LET i=i+1
LET numeric=Y
CALL skip
ELSE
LET i0=i
DO WHILE s$(i:i)>="0" AND s$(i:i)<="9" OR s$(i:i)="."
LET i=i+1
LOOP
LET numeric=VAL(s$(i0:i-1))
CALL skip
END IF
END FUNCTION

        └これだと,関数の中に加減算を含む式が書け... 白石 和夫 2004/05/08 12:14:19  ツリーへ

Re: 一応出来ました。 返事を書く
白石 和夫 2004/05/08 12:14:19
これだと,関数の中に加減算を含む式が書けないのでは?(動かして確認したわけではないけれど)

Full BASIC規格5.3の「数値式」の文法を参考にしてみてください。
Full BASICの数値式の文法を簡略化すると,

数値式 = 符号? 数値項 {符号 数値項}*
数値項 = 数値因子 {乗除算演算子 数値因子}*
数値因子 = 数値一次子 {山記号 数値一次子}*
数値一次子 = 符号なし数値定数 | 数値変数名 | 数値関数引用 | 左括弧 数値式 右括弧
数値関数引用 = 数値関数名 左括弧 数値式 右括弧

? は,あってもなくてよい
{ }* は,繰り返し(なくてもよい)
| は,択一(いずれか)
を意味します。


 

         ├ちなみに,interpre.basで実装しているのは... 白石 和夫 2004/05/08 12:17:51  ツリーへ

Re: これだと,関数の中に加減算を含む式が書け... 返事を書く
白石 和夫 2004/05/08 12:17:51
ちなみに,interpre.basで実装しているのは,

数値式 = 符号? 数値項 {符号 数値項}*
数値項 = 数値因子 {乗除算演算子 数値因子}*
数値因子 = 数値一次子 {山記号 数値一次子}*
数値一次子 = 符号なし数値定数  左括弧 数値式 右括弧

です。

         └数値一次子=符号なし数値定数|数値変数名... 白石 和夫 2004/05/08 13:25:19  ツリーへ

Re: これだと,関数の中に加減算を含む式が書け... 返事を書く
白石 和夫 2004/05/08 13:25:19
数値一次子 = 符号なし数値定数 | 数値変数名 | 数値関数引用 | 左括弧 数値式 右括弧
数値関数引用 = 数値関数名 左括弧 数値式 右括弧
は,
数値一次子 = 符号なし数値定数 | 数値変数名 | 数値関数名 左括弧 数値式 右括弧| 左括弧 数値式 右括弧

としても同じです。

          └テストしましたが関数の中に加減算を含む式...2004/05/08 14:17:26  ツリーへ

Re: 数値一次子=符号なし数値定数|数値変数名... 返事を書く
2004/05/08 14:17:26
テストしましたが関数の中に加減算を含む式でも計算できました。
FUNCTION primaryできちんと実装されるようです。
interpre.basが見事に出来ているので助かります。
Full BASICの文法には合わないかもしれませんが、今のところこれで充分です。自己満足!

それにしても計算式を実行させることだけでも大変なんですねー。
Basic言語の開発してくださっている方の苦労には頭が下がります。

           └よく見たら 白石 和夫 2004/05/08 18:19:56  ツリーへ

Re: テストしましたが関数の中に加減算を含む式... 返事を書く
白石 和夫 2004/05/08 18:19:56
よく見たら

primary = numeric | 左括弧 数値式 右括弧
numeric = 数値定数 | 数値変数名 | 数値関数名 primary

みたいな文法になっているようです。
たとえば,
INT SQR 2
みたいな書き方を許容する文法になるようです。


インデックスへ EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。