オートマトン
オートマトンがじつはよくわかってないので、いろいろ見てみてます。
自動人形であるとか言う話は置いといて、実装しようとするとなかなか。。。
情けない。
逆にいえば、はっきりオートマトンが分かれば、何かと都合がいいと
思っています。
受理したときはいいとして、受理しなかったときのエラーメッセージを
どうすればいい感じに出せるのかなぁとか思ってみてるのだけど、
よくわかりましぇん。
生け垣オートマトンとかが、自分が考えてる言語にはあってるような
気がするのだけども、これまた難解というかなんというか、、、。
わかってるような、わかってないような、微妙な感じです。
頭悪いなぁ。
以下とりあえず、HSPのプログラムをjavascriptに移植してみたのソースです。
http://rpen.blogspot.com/2007/06/blog-post_30.html
字句解析するものですねぇ。
これのエラー状態が今1つしかないけども、きちんとエラーを出すには
複数のエラー状態が必要でしょう。
そして、エラーからの復帰も必要となるかもしれないです。
そのとき、どうしたらよいのでしょうか???
うーん。いろいろ、分からんこと多しなので、勉強してみまーす。
<script> // オートマトンによる字句解析 var STATE_ERROR = 0; var STATE_FIRST = 1; // 初期状態。 0〜9でSTATE_INPUT_INTEGERへ、+-でSTATE_SIGNへ。 var STATE_SIGN = 2; // 符号解析後。 0〜9でSTATE_INPUT_INTEGERへ。 var STATE_INPUT_INTEGER = 3; // 整数部入力状態。 0〜9でSTATE_INPUT_INTEGERへ、.でSTATE_INPUT_FLOATへ。 var STATE_INPUT_FLOAT = 4; // 小数点以下入力状態。0〜9でSTATE_INPUT_FLOATへ。 var IS_ERROR = 0; var IS_INTEGER = 1; var IS_FLOAT = 2; var canAccept = new Array(STATE_INPUT_FLOAT + 1); // モジュール初期化用命令 function init() { // 受理集合に属する状態を定義 canAccept[STATE_INPUT_INTEGER] = IS_INTEGER; canAccept[STATE_INPUT_FLOAT] = IS_FLOAT; } // 文字列が数値か否かを判別する関数 function isDigit(sArg) { var tmp = sArg.charAt(0); return ('0' <= tmp) & (tmp <= '9'); } // 次の状態を返す関数 function nextState(nowState, sArg) { switch (nowState) { case STATE_FIRST: if ((sArg == "+") | (sArg == "-")) return STATE_SIGN; case STATE_SIGN: if (isDigit(sArg)) return STATE_INPUT_INTEGER; break; case STATE_INPUT_INTEGER: if (isDigit(sArg)) return STATE_INPUT_INTEGER; if (sArg == ".") return STATE_INPUT_FLOAT; break; case STATE_INPUT_FLOAT: if (isDigit(sArg)) return STATE_INPUT_FLOAT; break; default: break; } return STATE_ERROR; } // 受理される文字列か否か判定する命令 function judge(sArg) { var state = STATE_FIRST; var tmp = sArg; for (var cnt = 0; cnt < sArg.length; cnt++) { state = nextState(state, tmp.charAt(cnt)); if (state == STATE_ERROR) break; } return canAccept[state]; } init(); // モジュールここまで // 以下サンプルコード var sQuestion = ["+123", "456", "-3.14", "1e-03", "10.", "I may be refused."]; for (var cnt = 0; cnt < sQuestion.length; cnt++) { switch (judge(sQuestion[cnt])) { case IS_INTEGER: p( sQuestion[cnt] + "は整数として受理されます。"); break; case IS_FLOAT: p(sQuestion[cnt] + "は実数として受理されます。"); break; default: p(sQuestion[cnt] + "は受理されませんでした。"); break; } } function p(str) { document.write(str+"<br>"); } </script>