scriptを読む2つのパーサー

1つは字句(トークン)解析(パーサー)。
単調なパターン、主に正規化表現で読める範囲でテクストを切り取るのが主な役目。
読むようによっては何通りもの値(Value)が出てくるので、文字列なら0123、数値なら123、でも8進数なら83、16進数なら291のハズなどと余計なことはしない方がいい。
for ( var  i ; i < 1/3 ;  i+= 0.000100000 ) {
のような場合は解析した値の精度が不十分だと、困った結果になるし、コード単位でデバッガをステップ動作させるには、テクストから切り取った文字の長さも重要だからだ。
「リテラル」「何かの名前」「数値」「演算子」「空白」「改行」程度の字句(トークン)に分類できればOK。
2つめは文法解析(パーサー)。
var i = j * 2;
をトークンの組み合わせを短い文法のパターンを優先順位順にパターンのマッチングを行い、正解があれば、パターンと対になる処理を実行する。
トークン(字句)ベースの正規化表現を処理する感じ。
字句解析との違いは、内包表現が可能で、
処理 ::= 処理 | 文
のように、処理に文と追加したものは処理としてまとめる、な感じの拡張ができる。
当然、
処理 ::= 文
処理ブロック ::=処理 +
のように内包しない書き方も可能。
 
自己拡張型トークン定義を用い、トークンパーサーとパーサーを1つで実装し、中間コード生成(コード・オーガナイザー)、中間コード実行(インタープリタ)の3つにまとめて考えるとすると・・・
つまり、
リテラル文字 ::= \[rntsd”]   \\   \u[0-9a-fA-F]{4}  [\u0000-\uffff]
リテラル文字A ::= [^”] & リテラル文字
リテラル文字B ::= [^”] & リテラル文字
リテラル ::= \”  リテラル文字A  \” | ’   リテラル文字B  ‘
数字 ::= [0-9]+  “.” *  [0-9]*
のように最下層から定義することになる。
厄介なのは\エスケープ表現で、こんな感じで自己拡張可能なようにしないと内部コードに\エスケープ表現や\uxxxxの文字表現を埋め込まないといけなくなる。
また自己拡張型の欠点としてすぐ思いつくのが「処理が遅い」がある。
さらに、リテラル文字とリテラルの表現を観れば、なんとなく リテラル文字の中に”が含まれているので、永久にリテラルの左の”や’を判別する気がないように感じる。
そこは、リテラル文字A,Bの最初の [^”] [^’]で回避する。
つまり、この自己拡張型トークン処理ではサブルーチンにお任せではなく、1本の文字列ストリームを各階層でチェックしながら分析することになる。
それではやはり処理が重い、毎回正規化表現テクストの解析の後に、対象テクストを読み込むことになるので、正規化表現テクストの分析結果をキャッシュし、2度目は再利用することにする。
つまり、文法を解析し、文法解析する中間コードを生成し、インタープリタで実行させ、対象テクストを文法解析し、その中間コードを作り、最後にそれを実行することになる。
勿論、ターゲットとなるCPUやOSが限定する環境では各中間コードを完成直後に、バイナリーコードに置き換えて実行しても構わない。
さて細かい実装を考えると、
parser -g grammer-text  -i  analize-text
のように引数で与えるのは好ましくない。
なぜならファイルシステムが存在しなければ、grammer-text  も  analize-text も読みようがないからだ。これはサンドバックの多くがファイルシステムへのアクセスを好ましく思わない現状を考えると、現実味のあることで、外部インタフェースを頼った方がいいので、DLLやシェアライブラリィのエントリィつまり一般に許可されているAPIを直接使うことにする。
parser -imports imports-defines -g grammer-text  -i  analize-text
な感じになる。
imports-definesには各OSごとに異なるAPIアクセス方法を記述した何か、ファイルシステムが無くても読みこむ様にする方法は、パーサーに組み込んだソースに依存する。
もちろん、パーサーでimports-definesの文法解析を行い、結果の中間コードをキャッシュしたままつかってもよく、対になる処理は、パーサーの初期設定にエントリィを組み込んでおけばよいので、imports-definesはWIN64とかLH6と宣言のみで中身はパーサーのソースの中でいいような気がするけどね。
 
な感じかな?
正規化表現をどこで解釈するのか記述しないと困るのかな?
やっぱり重そうだな(笑




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA