Skip to content
gg edited this page Sep 8, 2016 · 2 revisions

rhino-c の仕様(9/6)

9/8 更新

  • トークン処理: この時点では演算子を特別視せずすべて記号として扱う。

##トークン処理 入力文字列に対してプリプロセッサ、コメント除去をしたあと、識別子、演算子、記号(括弧、:など)、文字列リテラル、数値リテラル、文字リテラルを解析する。

識別子に関しては、識別子の文字並びを格納しトークンとする。演算子については演算子表から検索を行い、対応するenum rh_token_typeの値を格納しトークンとする。

記号(記号類のうち演算子表から見いだせなかったもの)は文字並びを格納しトークンとする。各種リテラルについては、文字列型の場合は実行時メモリに格納した上で、それらの値を表すstruct rh_variableを生成し(別途記述)、それを格納したトークンとする。ただし、リテラルの処理中に、そのリテラルの値を一時的に格納しておく自動変数が別途必要である。(現状の(long long) intval, (long double) dblval)(longをサポートしなければ、ただのint, doubleでよい)

すべてのトークンには、エラー時の診断情報を表示するため、ファイル名(struct rh_file *)、開始位置、終了位置を保持している。 ##rh_variableについて リテラルから生成する場合、rh_malloc()を用いて新しくメモリ領域を確保しデータをコピーする。後述する宣言文によって生成され記号表に格納される場合、識別子を示す識別子トークン(これはファイル上の位置情報を含み、デバッグ時に便利)を含み、データは含まない(NULL)。

もちろん、すべてのrh_variableには型情報(rh_type)が含まれる。 ##rh_typeについて これに関しては現状の実装から大きく変更する必要はない。rh_typeは再帰的に入れ子にできるようにした上で、当面pointer, array, int, charのみをサポートする。 ##解析処理 解析処理はトークン処理に問い合わせつつ解析を実行する。解析処理の目的は、解析時に処理されるべきトークンを処理し(例えば宣言文)、変換すべきトークンを変換し(ループ文など)、変数名を記号表から検索してrh_variableに変換し、オペレーターを前置表記にすることである。

これらを、rh_token型の配列(添字がメモリ番地に相当、ただしトークン処理で文字列を確保した場合はその文シフトする)に格納する。(この配列の1要素=1文となっている)

宣言文の処理については、その関数スコープ内での記号表(もちろんブロック階層も考える必要がある)を命令コンテキストにそって更新していき、識別名よりrh_variable要素を検索できるようにする。(ebpからの相対アドレスは、記号表登録時に判明する。)ループ文については、各ポイントでの命令アドレスを記録しておき、IFJMPトークン(もし式1がtrueなら番地にジャンプ)、無条件JMPトークンに変換する。オペレータの前置表記については、各オペレータが木構造となるように(すなわちオペレータトークンの元に複数個のオペランドトークンへの参照をもたせる) 再帰的下降パーサによって組み替える。この際、演算子の優先順位等に気をつける(現状のコードのほとんどが役に立つはずである)。また演算子表に情報を持たせることで可能となるならばエラーチェックを行う。(オペランドの型によって別々の式を生成する場合にも使える。)

生成したトークンを配列に格納する処理はrh_execute(), 各文に対応するトークンを生成する処理はrh_execute_statement(), 各式をパースする処理は現状のrh_execute_expression()を 置き換える。 ##実行処理 配列に格納されたトークンを順番に実行する。ただし、実行時のスタック領域を確保する必要がある。

構文木では実行単位である各文がツリー構造となっているが、これを、できるかぎり関数再帰せずに実行したい。

ソースコードがある程度長くなってしまうのは仕方がないので、場合によってはトークンをスタック構造で管理する必要がある。 式の実行については、レジスタに相当する十分な長さの変数が3つ(オペランド数2 + 返却値1)必要である。(Intel CPUでは、各演算命令のオペランドは1つである。

edxをオペランド用、eaxを返却値用に使用しているようだ。)(FPUをサポートする場合は、さらに4つ必要。)注意点としては、たとえば&&や?:は、条件がマッチしない場合は副作用を防止するため後の式を評価してはならない。

Clone this wiki locally