C言語-インタプリタminiCASL |
9. 命令も英大文字・小文字のどちらでも使えるようにする
変数は、関数toupper()で英大文字に変換して、大文字・小文字が区別されないようにした。同じように、命令も大文字でも小文字でも使用できるようにする。
関数toupperは、1文字分のデータしか大文字に変換することができない。文字列中の英小文字だけを大文字に、または、その逆に変換するの標準関数にはない。ここでは、文字列中の英小文字だけを大文字に変換するユーザ関数str_upperを作成する。
1行読み込んだ直後に、ユーザ関数str_upperを使用して英小文字を大文字に変換する。変数名も含めてすべて英大文字に変換されるので、関数toupperで変数名を大文字に変換する必要はなくなる。
[mc10.c] (修正部分は赤色太字で示す。) | |
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "gettoken.h" #define STRMAX 80 /* 文字列配列の大きさ */ /* グローバル変数 */ double hensuu[26]; /* mc言語の変数用 */ void main(int argc, char *argv[]) { char *str_upper(char *); /* 文字列大文字変換関数 */ int get_valnum(void); /* 変数番号取得関数 */ double get_para(void); /* 引数取得関数 */ FILE *fp; /* ファイル操作用 */ char inbuff[STRMAX]; /* 入力データ用 */ int val; /* 変数番号用 */ if(argc != 2){ /* パラメータのチェック */ printf("使い方:MC filename\n"); exit(1); } if((fp = fopen(argv[1], "r")) == NULL){ /* ファイルのオープン */ printf("ファイルがオープンできませんでした。\n"); exit(1); } while(fgets(gt_line, STRMAX, fp)){ /* データの読み込み */ str_upper(gt_line); get_token(); if(!strcmp(token, "ADD")){ /* 命令判定 */ get_token(); val = get_valnum(); get_token(); hensuu[val] = hensuu[val] + get_para(); }else if(!strcmp(token, "SUB")){ get_token(); val = get_valnum(); get_token(); hensuu[val] = hensuu[val] - get_para(); }else if(!strcmp(token, "MUL")){ get_token(); val = get_valnum(); get_token(); hensuu[val] = hensuu[val] * get_para(); }else if(!strcmp(token, "DIV")){ get_token(); val = get_valnum(); get_token(); hensuu[val] = hensuu[val] / get_para(); }else if(!strcmp(token, "END")){ break; }else if(!strcmp(token, "IN")){ get_token(); val = get_valnum(); printf("in="); gets(inbuff); hensuu[val] = atof(inbuff); }else if(!strcmp(token, "OUT")){ get_token(); val = get_valnum(); printf("%f\n", hensuu[val]); }else{ printf("Error : コマンドエラー\n"); continue; } } fclose(fp); /* ファイルのクローズ */ } char *str_upper(char *str) { char *top = str; while(*str){ if(*str >= 'a' && *str <= 'z') *str = *str - 0x20; ++str; } return(top); } int get_valnum(void){ if(isalpha(*token)){ return(*token - 'A'); /* 変数番号 */ }else{ printf("変数を指定してください。\n"); exit(1); } } double get_para(void){ if(isalpha(*token)){ return(hensuu[*token - 'A']); /* 変数値 */ }else if(isdigit(*token) || *token == '+' || *token == '-'){ return(atof(token)); /* 数値 */ }else{ printf("変数または数値を指定してください。\n"); exit(1); } } |
D:\Data\src>cc mc10.c gettoken.obj lld @link.i D:\Data\src>mc10 reidai04.mc in=12.345 in=11.111 23.456000 12.345000 123.450000 -12.345000 |
変数gt_lineはgettoken.hで宣言されているグローバル変数なので、関数str_upper()の引数として渡す必要はない。しかし、言語処理プログラムでは文字列全体を大文字に変換するケースがあるので、どのようなケースでも使えるように引数として変換したい文字列を指定するようにしている。
これでmc言語の一応の完成である。
【課題】
CASL風の言語を作成してきたので、さらに次のような機能の拡張を各自で研究して追加してみよう。
機能の追加は、どれから行っても問題はないと思うので、実現しやすそうなものから取りかかってみよう。
等々
Copyright © 2001 Hiroshi Masuda |