C言語-トランスレータ(mbas to C) |
6. END, INPUT, PRINT の処理 (1)
各命令の動作にあったC言語プログラムを出力していく。そのとき、各命令の文法(書式、使い方)の詳細も決めていく。
[END命令]
END命令の動作は、プログラムを終了させることである。具体的には、 % mbas reidai.mbのように実行したプログラムを終了し、OSのコマンド待ちにすることである。C言語では、関数exitまたは、関数mainを } で閉じることで終了することになる。END命令は、プログラムの途中にも記述する場合があるので、関数exitを出力する。
書式実際にEND命令でプログラムが終了したことがわかるように「終了します」とメッセージを表示して終了するようにする。
END
変換 END → printf("終了します\n");
exit(1);
変換後のC言語プログラムでは、関数exitを使用するので、定型句出力として#include<stdlib.h>を追加出力する。
関数printfでは、" や \ などは特殊な働きを持つ文字であるので、文字として表示させるには \ で働きを打ち消す必要がある。すなわち、" を出力するには \" 、\を出力するには \\ 、%を出力には %% と表す。
printf("終了します\n"); を表示するための printfの文は次のようになる。(\ = \)
printf("printf(\"終了します\\n\");\n");
また、プログラムをすべて処理した後、関数mainを閉じる } も出力する。
printf("}\n");
[main05.c] | |
35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 69: 70: 71: |
/* C言語 定型句出力 */ printf("#include <stdio.h>\n"); printf("@ "); /* ←追加 */ printf("void main(void)\n"); printf("{\n"); printf("\tdouble hensuu[26];\n"); printf("\tchar buff[256];\n\n"); /* 命令の判定 */ for(now = 0; now < last; ++now){ strcpy(gt_line, list[now]); /* 字句解析の準備 */ get_token(); /* トークンの取得 */ if(!strcmp("END", token)){ /* 命令の判定 */ printf("A "); printf("exit(1);\n"); }else if(!strcmp("INPUT", token)) printf("INPUT 命令です\n"); << 省略 >> } printf("B "); } |
D:\Data\src>cc main05.c gettoken.obj lld @link.i D:\Data\src>main05 reidai.mb #include <stdio.h> #include <stdlib.h> void main(void) { double hensuu[26]; char buff[256]; INPUT 命令です INPUT 命令です INPUT 命令です 命令以外です PRINT 命令です printf("終了します\n"); exit(1); } |
実行結果の緑色部分が追加したプログラムによって出力された部分である。
出力したい文字列を printf("終了します\n"); としたとき、次のように変換していく。
まず、特殊な働きの文字(", \)の直前に\を付ける。
printf(\"終了します\\n\");
この文字列を printf(" と \n"); ではさめば完成である。
printf("printf(\"終了します\\n\");\n");
一度に書くと複雑そうであるが、このように直していけば比較的簡単にできる。
字下げの処理
mbtのプログラムをC言語に変換したプログラムはそのままコンパイルするだけであるから、見やすさは特に重要ではない。また、C言語はプログラムを自由に書くことができるので、この場合、字下げなどの処理は不要である。しかし、変換されたC言語のプログラムリストを見ながら正しく変換されたかを確認するため字下げの処理を追加することにする。
END命令で出力したC言語のプログラムに、字下げ(インデント)を追加し、リストを見やすくする。インデントにはタブを出力する。C言語では、\t がタブ文字である。制御文内では、さらにインデントを深くすることになるので、タブ出力専用の関数ptabを作成する。
C言語プログラムを出力する前に実行することで、インデントすることができる。
関数 void ptab(void)
グローバル変数tabに指定した数値分だけタブ(\t)を出力する。
インデント数を持つ変数tabは別の関数でも使用することになるので、グローバル変数にした。
[main06.c] | |
1: 2: 3: 4: 5: 6: 7: 8: 9: |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "gettoken.h" /* 関数のプロトタイプ宣言 */ @ /* グローバル変数 */ int tab = 1; void main(int argc, char *argv[]) |
46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: |
/* 命令の判定 */ for(now = 0; now < last; ++now){ strcpy(gt_line, list[now]); /* 字句解析の準備 */ get_token(); /* トークンの取得 */ if(!strcmp("END", token)){ /* 命令の判定 */ A printf("printf(\"終了します\\n\");\n"); A printf("exit(1);\n"); }else if(!strcmp("INPUT", token)) printf("INPUT 命令です\n"); |
78: 79: 80: 81: 82: 83: 84: 85: 86: 87: |
void ptab(void)
{
int n;
if(tab <= 0)
return;
n = tab;
while(n--) /* Tabをn回出力 */
printf("\t");
}
|
D:\Data\src>cc main06.c gettoken.obj lld @link.i D:\Data\src>main06 reidai.mb #include <stdio.h> #include <stdlib.h> void main(void) { double hensuu[26]; char buff[256]; INPUT 命令です INPUT 命令です INPUT 命令です 命令以外です PRINT 命令です printf("終了します\n"); exit(1); } |
関数ptab()を使って、if文やfor文では次の行から変数tabを1加算して、字下げを深くすることができる。
Copyright © 2001 Hiroshi Masuda |