コンパイラを作るために開発した言語UCCScriptのインタープリタの再帰を無くして、高速化を図る機能を実装する前、テストとして
コード:
First Test End
$Test In { <o "+-"> <{ ( "+" | "-" ) }> <o "*/"> <{ ( "*" | "/" ) }> }
Is (If[?[0]][ (For[0 $0+[0] 1 - 1][ @1[0 `] ]) ] Else[])
(If[?[1]][ (For[0 $0+[1] 1 - 1][ @1[1 `] ]) ] Else[]) End
入力:
+*-/
コードを書いて入力を与えると+-*/
と返ってきて欲しいのですが、実際には
+-+*/
と返ってきました(中央の+
はどこから来たのだろうか…)。そんな致命的なバグを発見したことによって(インタープリタをC#からF#に書き換えていることもあって)、実装していませんでした(未実装の機能が強すぎて、このバグは放棄した)。
--追記
・このバグはUCCScriptの仕様によるもので解決のしようがないものでした(そもそもコードがぐちゃぐちゃで何がどうなっているのかもわからなくなっていた)。
マッチングの条件分岐
再帰をできるだけ行わないために、任意のアンカー'
に飛ぶ機能(それと、結果を返すところからマッチングを要求する機能)の実装を決め、具体的にどのように書こうかを決めている時でした。
First Test End
$Test In <( Char )> "|" m"r:0" j' "a" ret ' "b" ret j
Is j' (
If[@0[0] Num ~ 2 % 0 =][ (MoveP[0]) ]
Else[ (MoveP[1]) ]
)
Ret j End
条件分岐ができるだと……
これは正規表現[0-9]\|(a|b)
(C#)にマッチする文字列で、最初の一桁の数字が偶数ならa
で、奇数ならb
でマッチさせるコードなのです。
--追記
・仕様は変更されましたが、実装しました。UCCScript