21.5. Eval 関数説明 |
関数名 | Eval |
---|---|
定義ファイル名 | pass2.cpp |
定義行 | 922 |
宣言形式 | int Eval ( TList * TokenList , int sPos , int ePos , TList * ValDataList , double * dData ) |
概要 | sPosからePosの式の解析と評価を実行する。 使用したトークンの数を返す。 定数として評価出来た場合(Parameter,Const)の場合は、EvalConstF=trueを設定 。 Paramater文の定数の計算にも使用される。 対象トークンは、 tid_Oprと数値(整数、実数)、数値、関数となる。 関数の引数部分の解析も行われる。 = を含む代入文に関しての処理は、呼び出し側で行うこと。(右辺のみが対象と なる) |
戻り値 | 使用したトークンの数を返す。 |
パラメタ説明 | TokenList トークンリスト sPos 開始位置 ePos 終了位置 ValDataList 変数データリスト dData 結果データ格納先 |
機能説明 | |
備考 |
名称 | 定義ファイル名 | 定義行 | |
---|---|---|---|
1 | AddDataDef | pass2.cpp | 533 |
2 | Pass2_Line | pass2.cpp | 104 |
名称 | 定義ファイル名 | 定義行 | |
---|---|---|---|
1 | ErrMsg | pass2.cpp | 1484 |
2 | Add | ||
3 | AnsiCompareText | ||
4 | Delete | ||
5 | pow |
名称 | 定義ファイル名 | 定義行 | |
---|---|---|---|
1 | EvalConstF | pass2.cpp | 24 |
2 | ImplType | pass2.cpp | 23 |
3 | ModuleIdx | pass2.cpp | 20 |
名称 | 種別 | 定義ファイル名 | 定義行 | |
---|---|---|---|---|
1 | TToken | クラス | pass1.h | 216 |
2 | TValData | クラス | pass2.h | 42 |
関数論理チャート | +--------------------------------------------------------------------------------+ 922 +--+ int Eval(TList *TokenList,int sPos,int ePos,TList *ValDataList,double *dData) | 923 | { | +--+-----------------------------------------------------------------------------+ 924 +--- int i,j; 925 +--- TToken *Token,*LastTokData; 926 +--- int TokId,LastTokId; 927 +--- AnsiString TokStr,LastTokStr; 928 +--- int UseToken; 929 +--- TList *DestList = new TList; 930 +--- TList *OpcList = new TList; 931 +--- int brLevel = 0; 932 | 933 +--- *dData = 0.0; 934 +--- LastTokId = -1; 935 +--- EvalConstF = false; | +----------------------------------+ 936 +--+ for(i = sPos ; i <= ePos ; i++){ | | +--+-------------------------------+ 937 | +--- Token = (TToken *)TokenList->Items[i]; 938 | +--- TokId = Token->TokId; 939 | +--- TokStr = Token->Str; 940 | | 941 | +--- // static int dd = 0; 942 | | // ErrMsg(TokenList,i,IntToStr(dd++)+" ["+TokStr+"]"); 943 | | | | +----------------+ 944 | +--+ switch(TokId){ | | | +--+-------------+ | | +-------------------------------+ 945 | | | case tid_ConstInt: // 定数 | | | +-------------------------------+ | | +-------------------------------+ 946 | | | case tid_ConstReal: // 定数 | | | +-------------------------------+ 947 | | +--- DestList->Add((void *)Token); | | | +--------+ 948 | | +--+ break; | | | | +--------+ | | +-----------------------------+ 949 | | | case tid_Opr: // 演算子 | | | +-----------------------------+ 950 | | +--- // 951 | | | // 演算子の単項かどうかと優先順位を求める。 952 | | | // 前が空か、演算子か、(ならば単項となる。 953 | | | // | | | +--------------------------------------------------------------------+ 954 | | +--+ if((i == sPos)||(LastTokId == tid_Opr)||(LastTokId == tid_Kakko)){ | | | | +--+-----------------------------------------------------------------+ 955 | | | +--- // 単項演算子 956 | | | +--- Token->priority = 10; // 優先度を変更 957 | | | +--- OpcList->Add((void *)Token); | | | | +--------+ 958 | | | +--+ break; | | | | | +--------+ | | | +-+---+ 959 | | | | } | | | | +-----+ 960 | | +--- // 961 | | | // 2項演算子の処理(優先順位を求めること) 962 | | | // | | | +--------------------------+ 963 | | +--+ if(OpcList->Count > 0){ | | | | +--+-----------------------+ 964 | | | +--- LastTokData = (TToken *)OpcList->Items[OpcList->Count-1]; 965 | | | +--- LastTokStr = LastTokData->Str; | | | | +--------------------------------------+ 966 | | | +--+ if(LastTokData->TokId == tid_Kakko){ | | | | | +--+-----------------------------------+ 967 | | | | +--- OpcList->Add((void *)Token); // スタックに積む | | | | +-+---+ 968 | | | | | } | | | | | +-+---+ | | | | +-+-----------------------------------------------------------------------+ 968 | | | | | else if((Token->priority <= LastTokData->priority)&&(TokStr == "**")){ | | | | | +-+-----------------------------------------------------------------------+ 969 | | | | +--- // ** 演算子は、右側結合 970 | | | | +--- OpcList->Add((void *)Token); // スタックに積む | | | | +-+---+ 971 | | | | | } | | | | | +-+---+ | | | | +-+---------------------------------------------------+ 971 | | | | | else if(Token->priority < LastTokData->priority){ | | | | | +-+---------------------------------------------------+ 972 | | | | +--- OpcList->Add((void *)Token); // スタックに積む | | | | +-+---+ 973 | | | | | } | | | | | +-+---+ | | | | +-+-------+ 973 | | | | | else{ | | | | | +-+-------+ | | | | | +----------------------------+ 974 | | | | +--+ while(OpcList->Count > 0){ | | | | | | +--+-------------------------+ 975 | | | | | +--- // 976 | | | | | | // スタックの内容を取り出す。 977 | | | | | | // 978 | | | | | +--- LastTokData = (TToken *)OpcList->Items[OpcList->Count-1]; 979 | | | | | +--- LastTokStr = LastTokData->Str; | | | | | | +----------------------------------------------+ 980 | | | | | +--+ if(Token->priority < LastTokData->priority){ | | | | | | | +--+-------------------------------------------+ | | | | | | | +----------------------------+ 981 | | | | | | +--+ if(Token->priority != 10){ | | | | | | | | +--+-------------------------+ | | | | | | | | +--------+ 982 | | | | | | | +--+ break; | | | | | | | | | +--------+ | | | | | | | +-+---+ 983 | | | | | | | | } | | | | | | | | +-+---+ | | | | | | | +-+-------+ 983 | | | | | | | | else{ | | | | | | | | +-+-------+ 984 | | | | | | | +--- // 単項演算子どおしの場合は、後方から | | | | | | | | +------------------------------------------------+ 985 | | | | | | | +--+ if(Token->priority <= LastTokData->priority){ | | | | | | | | | +--+---------------------------------------------+ | | | | | | | | | +--------+ 986 | | | | | | | | +--+ break; | | | | | | | | | | +--------+ | | | | | | | | +-+---+ 987 | | | | | | | | | } | | | | | | | | | +-----+ | | | | | | | +-+---+ 988 | | | | | | | | } | | | | | | | | +-----+ | | | | | | +-+---+ 989 | | | | | | | } | | | | | | | +-----+ 990 | | | | | +--- DestList->Add((void *)LastTokData); 991 | | | | | +--- OpcList->Delete(OpcList->Count-1); | | | | | +-+---+ 992 | | | | | | } | | | | | | +-----+ 993 | | | | +--- OpcList->Add((void *)Token); // スタックに積む | | | | +-+---+ 994 | | | | | } | | | | | +-----+ | | | +-+---+ 995 | | | | } | | | | +-+---+ | | | +-+-------+ 995 | | | | else{ | | | | +-+-------+ 996 | | | +--- OpcList->Add((void *)Token); // スタックに積む | | | +-+---+ 997 | | | | } | | | | +-----+ | | | +--------+ 998 | | +--+ break; | | | | +--------+ | | +-------------------+ 999 | | | case tid_Kakko: | | | +-------------------+ 1000 | | +--- brLevel++; | | | +--------+ 1001 | | +--+ break; | | | | +--------+ | | +---------------------------------------------------+ 1002 | | | case tid_Kokka: // Nest = 0の場合は終了となる。 | | | +---------------------------------------------------+ | | | +--------------------+ 1003 | | +--+ if(brLevel <= 0){ | | | | +--+-----------------+ 1004 | | | +--- // )まで解析があるので、エラーとはしない 1005 | | | +--- // ErrMsg(TokenList,i,"対応する'('がありません。"); 1006 | | | +--- UseToken = i-sPos; 1007 | | | +--- i = ePos+1; | | | | +--------+ 1008 | | | +--+ break; | | | | | +--------+ | | | +-+---+ 1009 | | | | } | | | | +-----+ 1010 | | +--- brLevel--; | | | +----------------------------+ 1011 | | +--+ while(OpcList->Count > 0){ | | | | +--+-------------------------+ 1012 | | | +--- LastTokData = (TToken *)OpcList->Items[OpcList->Count-1]; 1013 | | | +--- LastTokStr = LastTokData->Str; | | | | +----------------------------------------+ 1014 | | | +--+ if(LastTokData ->TokId == tid_Kakko){ | | | | | +--+-------------------------------------+ 1015 | | | | +--- // 最後が(なら削除で終わり 1016 | | | | +--- OpcList->Delete(OpcList->Count-1); | | | | | +--------+ 1017 | | | | +--+ break; | | | | | | +--------+ | | | | +-+---+ 1018 | | | | | } | | | | | +-----+ 1019 | | | +--- DestList->Add((void *)LastTokData); 1020 | | | +--- OpcList->Delete(OpcList->Count-1); | | | | +--------------------------+ 1021 | | | +--+ if(OpcList->Count == 0){ | | | | | +--+-----------------------+ 1022 | | | | +--- // )まで解析があるので、エラーとはしない 1023 | | | | +--- // ErrMsg(TokenList,i,"対応する'('がありません。"); | | | | | +--------+ 1024 | | | | +--+ break; | | | | | | +--------+ | | | | +-+---+ 1025 | | | | | } | | | | | +-----+ | | | +-+---+ 1026 | | | | } | | | | +-----+ | | | +--------+ 1027 | | +--+ break; | | | | +--------+ | | +-------------------+ 1028 | | | case tid_Kannma: | | | +-------------------+ | | | +------------------------------------------------------+ 1029 | | +--+ if(brLevel == 0){ // ()内以外の","は評価を終了する。 | | | | +--+---------------------------------------------------+ 1030 | | | +--- UseToken = i-sPos; 1031 | | | +--- i = ePos+1; | | | +-+---+ 1032 | | | | } | | | | +-----+ | | | +--------+ 1033 | | +--+ break; | | | | +--------+ | | +-------------------+ 1034 | | | case tid_Koron: | | | +-------------------+ | | +-----------------------+ 1035 | | | case tid_KoronKoron: | | | +-----------------------+ | | +---------------------+ 1036 | | | case tid_LineEnd: | | | +---------------------+ | | +-----------------+ 1037 | | | case tid_Set: | | | +-----------------+ 1038 | | +--- UseToken = i-sPos; 1039 | | +--- i = ePos+1; | | | +--------+ 1040 | | +--+ break; | | | | +--------+ | | +-------------------------------------+ 1041 | | | case -1: // 変数・関数トークン | | | +-------------------------------------+ 1042 | | +--- // 1043 | | | // 未定義トークン、PARAMETER変数でないかをチェックする 1044 | | | // PARAMETER変数の場合は、定数と同じ扱いとする。 1045 | | | // それ以外の場合は、終了する。 1046 | | | // Nestが0の場合は、エラーとはしない。 1047 | | | // Exp. 12*34*??? はエラー(スタックに残る) 1048 | | | // Exp. 12*34 ??? はエラー(スタックに残らない) 1049 | | | // 1050 | | +--- int ValIdx; 1051 | | +--- TValData *ValData; 1052 | | | 1053 | | +--- Token->RefType = vrf_ref; // 変数参照 | | | +------------------------------------------------------------+ 1054 | | +--+ for(ValIdx = 0 ; ValIdx < ValDataList->Count ; ValIdx++){ | | | | +--+---------------------------------------------------------+ 1055 | | | +--- // 有効なPARAMETER変数が見つかった場合には、 1056 | | | | // その値をToken->dDataにセットして抜ける 1057 | | | +--- ValData = (TValData *)ValDataList->Items[ValIdx]; | | | | +--------------------------------------------------+ 1058 | | | +--+ if((AnsiCompareText(ValData->Str,TokStr) == 0)&& | 1059 | | | | | (ValData->ModuleIdx == ModuleIdx)){ | | | | | +--+-----------------------------------------------+ 1060 | | | | +--- Token->ValData = ValData; // トークンに変数を関連付ける 1061 | | | | +--- ValData->RefCount++; 1062 | | | | +--- Token->dData = ValData->dData; 1063 | | | | +--- DestList->Add((void *)Token); 1064 | | | | +--- ValIdx = ValDataList->Count+10; | | | | | +--------+ 1065 | | | | +--+ break; | | | | | | +--------+ | | | | +-+---+ 1066 | | | | | } | | | | | +-----+ | | | +-+---+ 1067 | | | | } | | | | +-----+ | | | +--------------------------------------+ 1068 | | +--+ if(ValIdx != ValDataList->Count+10){ | | | | +--+-----------------------------------+ 1069 | | | +--- // 最初に出現した変数 1070 | | | | // 本来は、エラー(警告)だが、変数として追加する形としてある。 1071 | | | +--- ValData = new TValData(TokStr); 1072 | | | +--- ValDataList->Add((void *)ValData); 1073 | | | +--- ValData->ModuleIdx = ModuleIdx; 1074 | | | +--- ValData->DataType = ImplType[TokStr[1]]; // 暗黙の宣言 1075 | | | +--- Token->ValData = ValData; // トークンに変数を関連付ける 1076 | | | +--- ValData->RefCount++; 1077 | | | +--- Token->dData = ValData->dData; 1078 | | | +--- DestList->Add((void *)Token); 1079 | | | | 1080 | | | +--- // 次が(で 定義が以前にない場合は、関数 1081 | | | +--- Token = (TToken *)TokenList->Items[i+1]; | | | | +--------------------------------+ 1082 | | | +--+ if(Token->TokId == tid_Kakko){ | | | | | +--+-----------------------------+ 1083 | | | | +--- ValData->ArrayOrFuncF = true; 1084 | | | | +--- ValData->DataType = ImplType[TokStr[1]] + dt_IntFunc; | | | | +-+---+ 1085 | | | | | } | | | | | +-----+ | | | +-+---+ 1086 | | | | } | | | | +-----+ | | | +--------+ 1087 | | +--+ break; | | | | +--------+ | | +---------------------------------------+ 1088 | | | default: // その他のトークン then | | | +---------------------------------------+ 1089 | | +--- UseToken = i-sPos; 1090 | | +--- i = ePos+1; | | | +--------+ 1091 | | +--+ break; | | | | +--------+ | | +-+---+ 1092 | | | } | | | +-----+ 1093 | +--- LastTokId = TokId; | +-+---+ 1094 | | } | | +-----+ 1095 +--- // 1096 | // スタック上に残ったトークンを掃き出す 1097 | // | +------------------------------+ 1098 +--+ while(OpcList->Count != 0){ | | +--+---------------------------+ 1099 | +--- Token = (TToken *)OpcList->Items[OpcList->Count-1]; 1100 | +--- TokStr = Token->Str; | | +--------------------------------+ 1101 | +--+ if(Token->TokId == tid_Kakko){ | | | +--+-----------------------------+ 1102 | | +--- ErrMsg(TokenList,i,"対応する')'がありません。"); | | +-+---+ 1103 | | | } | | | +-----+ 1104 | +--- DestList->Add((void *)Token); 1105 | +--- OpcList->Delete(OpcList->Count-1); | +-+---+ 1106 | | } | | +-----+ 1107 +--- // 1108 | // 実際の演算を実行する。 1109 | // 型としては、 Int,Realの2種類だけをサポートする。 1110 | // 論理型、複素数、文字型は、エラーとして扱う。 1111 | // 1112 +--- double stack[1024]; 1113 +--- double IntF[1024]; 1114 +--- int sp = 0; 1115 | 1116 +--- EvalConstF = true; | +------------------------------------------+ 1117 +--+ for(i = 0 ; i < DestList->Count ; i++){ | | +--+---------------------------------------+ | | +------------------+ 1118 | +--+ if(!EvalConstF){ | | | +--+---------------+ | | | +--------+ 1119 | | +--+ break; | | | | +--------+ | | +-+---+ 1120 | | | } | | | +-----+ 1121 | +--- Token = (TToken *)DestList->Items[i]; 1122 | +--- TokStr = Token->Str; | | +------------------------+ 1123 | +--+ switch(Token->TokId){ | | | +--+---------------------+ | | +-------------------------------+ 1124 | | | case tid_ConstInt: // 定数 | | | +-------------------------------+ 1125 | | +--- IntF[sp] = true; 1126 | | +--- stack[sp++] = Token->dData; | | | +--------+ 1127 | | +--+ break; | | | | +--------+ | | +-------------------------------+ 1128 | | | case tid_ConstReal: // 定数 | | | +-------------------------------+ 1129 | | +--- IntF[sp] = false; 1130 | | +--- stack[sp++] = Token->dData; | | | +--------+ 1131 | | +--+ break; | | | | +--------+ | | +-----------------+ 1132 | | | case tid_Opr: | | | +-----------------+ | | | +------------------------------------------+ 1133 | | +--+ if(Token->priority == 10){ // 単項演算子 | | | | +--+---------------------------------------+ | | | | +--------------+ 1134 | | | +--+ if(sp < 1){ | | | | | +--+-----------+ 1135 | | | | +--- UseToken = -1; | | | | | +--------+ 1136 | | | | +--+ break; | | | | | | +--------+ | | | | +-+---+ 1137 | | | | | } | | | | | +-----+ | | | | +--------------------+ 1138 | | | +--+ if(TokStr == "-"){ | | | | | +--+-----------------+ 1139 | | | | +--- stack[sp-1] = -stack[sp-1]; | | | | +-+---+ 1140 | | | | | } | | | | | +-----+ | | | | +--------+ 1141 | | | +--+ break; | | | | | +--------+ | | | +-+---+ 1142 | | | | } | | | | +-----+ 1143 | | +--- // 1144 | | | // 2項演算子 1145 | | | // | | | +--------------+ 1146 | | +--+ if(sp < 2){ | | | | +--+-----------+ 1147 | | | +--- UseToken = -1; | | | | +--------+ 1148 | | | +--+ break; | | | | | +--------+ | | | +-+---+ 1149 | | | | } | | | | +-----+ | | | +--------------------+ 1150 | | +--+ if(TokStr == "+"){ | | | | +--+-----------------+ 1151 | | | +--- stack[sp-2] = stack[sp-2] + stack[sp-1]; | | | +-+---+ 1152 | | | | } | | | | +-+---+ | | | +-+-------------------------+ 1152 | | | | else if(TokStr == "-"){ | | | | +-+-------------------------+ 1153 | | | +--- stack[sp-2] == stack[sp-2] - stack[sp-1]; | | | +-+---+ 1154 | | | | } | | | | +-+---+ | | | +-+-------------------------+ 1154 | | | | else if(TokStr == "*"){ | | | | +-+-------------------------+ 1155 | | | +--- stack[sp-2] == stack[sp-2] * stack[sp-1]; | | | +-+---+ 1156 | | | | } | | | | +-+---+ | | | +-+-------------------------+ 1156 | | | | else if(TokStr == "/"){ | | | | +-+-------------------------+ | | | | +----------------------------------------+ 1157 | | | +--+ if(stack[sp-1] == 0){ // 0除算エラー | | | | | +--+-------------------------------------+ 1158 | | | | +--- EvalConstF = false; | | | | +-+---+ 1159 | | | | | } | | | | | +-+---+ | | | | +-+-------+ 1159 | | | | | else{ | | | | | +-+-------+ 1160 | | | | +--- stack[sp-2] = stack[sp-2] / stack[sp-1]; | | | | +-+---+ 1161 | | | | | } | | | | | +-----+ | | | +-+---+ 1162 | | | | } | | | | +-+---+ | | | +-+-------------------------+ 1162 | | | | else if(TokStr == "**"){ | | | | +-+-------------------------+ 1163 | | | +--- stack[sp-2] = pow(stack[sp-2],stack[sp-1]); | | | +-+---+ 1164 | | | | } | | | | +-----+ | | | +--------------------------------+ 1165 | | +--+ if(IntF[sp-2] && IntF[sp-1]){ | | | | +--+-----------------------------+ 1166 | | | +--- stack[sp-2] = (int)stack[sp-2]; | | | +-+---+ 1167 | | | | } | | | | +-+---+ | | | +-+-------+ 1167 | | | | else{ | | | | +-+-------+ 1168 | | | +--- IntF[sp-2] = false; | | | +-+---+ 1169 | | | | } | | | | +-----+ 1170 | | +--- sp--; | | | +--------+ 1171 | | +--+ break; | | | | +--------+ | | +---------------------------------------+ 1172 | | | default: // パラメータ変数の処理 | | | +---------------------------------------+ | | | +----------------------------------------------------------------------------+ 1173 | | +--+ if((Token->ValData == NULL)||(!((TValData *)Token->ValData)->ParamValF)){ | | | | +--+-------------------------------------------------------------------------+ 1174 | | | +--- EvalConstF = false; | | | +-+---+ 1175 | | | | } | | | | +-+---+ | | | +-+-------+ 1175 | | | | else{ | | | | +-+-------+ | | | | +--------------------------------------------------------+ 1176 | | | +--+ if(((TValData *)Token->ValData)->DataType == dt_Int){ | | | | | +--+-----------------------------------------------------+ 1177 | | | | +--- IntF[sp] = true; | | | | +-+---+ 1178 | | | | | } | | | | | +-+---+ | | | | +-+-------+ 1178 | | | | | else{ | | | | | +-+-------+ 1179 | | | | +--- IntF[sp] = false; | | | | +-+---+ 1180 | | | | | } | | | | | +-----+ | | | +-+---+ 1181 | | | | } | | | | +-----+ 1182 | | +--- stack[sp++] = Token->dData; | | | +--------+ 1183 | | +--+ break; | | | | +--------+ | | +-+---+ 1184 | | | } | | | +-----+ | +-+---+ 1185 | | } | | +-----+ | +--------------+ 1186 +--+ if(sp != 1){ | | +--+-----------+ 1187 | +--- EvalConstF = false; | +-+---+ 1188 | | } | | +-----+ 1189 +--- *dData = stack[0]; // 最後のスタックが値となる。 1190 | 1191 +--- delete DestList; 1192 +--- delete OpcList; | +------------------+ 1193 +--+ return UseToken; | | +------------------+ +-+---+ 1194 | } | +-----+