| 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 | } |
+-----+