?? formula.c
字號:
break;
case '(':
rule->str[i++] = 'O';
bp++;
par1++;
break;
case ')':
if (par1 == 0)
{
ERROR9;
return (9);
}
rule->str[i++] = '$';
bp++;
par1--;
break;
case '[':
rule->str[i++] = 'P';
bp++;
par2++;
break;
case ']':
if (par2 == 0)
{
ERROR9;
return (9);
}
rule->str[i++] = 'Q';
bp++;
par2--;
break;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 其他字符 */
default:
printf("第 %d 行:無效字符\n", line);
return (7);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
} /* End of switch */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
} /* End of 公式行解析 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
if (if_goto_flag == 1)
{
printf("第 %d 行:if....goto 語句錯\n", line);
return (2);
}
if (par1 != 0 || par2 != 0)
{
ERROR9;
return (9);
}
/* 加公式語句結束符 'T' */
if (rule->str[i-1] != 'T' && if_goto_flag == 0)
rule->str[i++] = 'T';
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
} /* End of 規則文件 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 去掉最后一行的 'T' 并加規則結束符 */
while (rule->str[--i] == 'T');
rule->str[++i] = 0xFF;
rule->str[++i] = '\0';
if (i >= RULE_STR_SIZE)
{
printf("第 %d 行:規則文件超長\n", line);
return (11);
}
return (0);
}
/*****************************************************************************
Function: int Formula(RULE *rule, FIELD *Xarray, FIELD *Yarray)
Purpose : 解釋執行規則。
規則由用 T 分隔的語句組成。
規則用 0xFF 跟以 '\0' 結尾。
“標號:”標記的位置已存放在 rule->addr[i] 中。
數值常量已存放在 rule->num[i] 中,在規則串中用 ? 跟隨以一字節的
下標表示。
變量作為賦值對象時用 U,V,W 表示,規則串中沒有等號,解析時應向符
號堆棧中壓入等號;其他情形X,Y,Z 表示;都跟隨以一字節的下標。
函數名改為用 @ 跟以二位 ASCII 碼字符表示(低位在前)。
Input : 運算規則指針 rule,
數據域數組 Xarray, 用于存放輸入數據。
數據域數組 Yarray, 用于存放各返回值。
Return : 返回 0,出錯時返回非零的錯誤代碼。
Modify : 可能修改了 Xarray、Yarray 數組各成員的值。
Remark : 中間變量數組 Zarray。
一、公式內部符號表
———————————————————————————————————————
級別 符號 說明 ASCII 碼
———————————————————————————————————————
" 字符串界定符 34
———————————————————————————————————————
$ 右園括號 36
———————————————————————————————————————
? 數值常量 63
———————————————————————————————————————
1 @ 函數(邏輯非已改為函數) 64
———————————————————————————————————————
2 A~* B~/ 算術乘除 65 66
———————————————————————————————————————
3 C~+ D~- 算術加減 67 68
———————————————————————————————————————
4 E~< F~<= G~> H~>= I~== J~!= 算術比較 69 70 71 72 73 74
———————————————————————————————————————
5 K~& 邏輯與 75
———————————————————————————————————————
6 L~| 邏輯或 76
———————————————————————————————————————
7 M~= 賦值符 77
———————————————————————————————————————
8 N~? N~: N~, 條件運算符,函數參數分隔符 78
———————————————————————————————————————
9 O~( P~[ 左括號 79 80
———————————————————————————————————————
Q~] 右方括號 81
———————————————————————————————————————
R 公式結果為真跳轉 82
———————————————————————————————————————
S 無條件跳轉到標號 83
———————————————————————————————————————
T 公式語句結束符 84
———————————————————————————————————————
U x 作為賦值對象時 85
———————————————————————————————————————
V y 作為賦值對象時 86
———————————————————————————————————————
W z 作為賦值對象時 87
———————————————————————————————————————
X x 變量 88
———————————————————————————————————————
Y y 變量 89
———————————————————————————————————————
Z z 變量 90
———————————————————————————————————————
二、錯誤代碼:
n...第 n 號函數執行錯誤
*****************************************************************************/
int Formula(RULE *rule, FIELD *Xarray, FIELD *Yarray)
{
SIGN *ps; /* 符號堆棧指針 */
SIGN sign[STACK_SIZE]; /* 符號堆棧 */
SIGN next; /* 臨時存放雙目運算符 */
PACK pack; /* 運算堆棧及變量 */
FIELD sta[STACK_SIZE]; /* 運算堆棧 */
FIELD *pfield[16]; /* 賦值堆棧 */
FIELD Zarray[Zarray_SIZE]; /* 臨時變量 */
unsigned char *str, *cp;
short i;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
str = rule->str;
ps = sign;
pack.sp = sta;
pack.vp = pfield;
pack.px = Xarray;
pack.py = Yarray;
pack.pz = Zarray;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
while (*str != 0xFF)
{
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 判斷屬于 16 類情形中的那一類 */
if (*str <= 81)
{
if (*str <= 64)
{
if (*str <= 36)
{
if (*str == 34)
goto ASC34;
else
goto ASC36;
}
else
{
if (*str == 63)
goto ASC63;
else
goto ASC64;
}
}
else
{
if (*str <= 78)
{
if (*str <= 76)
goto ASC65_76;
else
goto ASC78;
}
else
{
if (*str <= 80)
goto ASC79_80;
else
goto ASC81;
}
}
}
else
{
if (*str <= 86)
{
if (*str <= 84)
{
if (*str <= 83)
goto ASC82_83;
else
goto ASC84;
}
else
{
if (*str == 85)
goto ASC85;
else
goto ASC86;
}
}
else
{
if (*str <= 88)
{
if (*str == 87)
goto ASC87;
else
goto ASC88;
}
else
{
if (*str == 89)
goto ASC89;
else
goto ASC90;
}
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 雙引號 '"', 字符串常量, 壓入字符串堆棧 */
ASC34:
cp = pack.sp->str;
pack.sp->type = STRING;
(pack.sp)++;
str++; /* 跳過引號 */
while (*str != '"')
*cp++ = *str++;
*cp = '\0';
str++; /* 跳過引號 */
continue;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 右園括號 $~), 不壓入符號堆棧 */
ASC36:
str++;
/* 處理前面所有運算符直至左園括號 */
while (ps > sign && (ps-1)->op != 79)
{
ps--;
Calc[ps->op - 65].addr(&pack);
}
ps--; /* 將左括號從堆棧中彈出 */
/* 左括號前是否有函數 */
if (ps > sign && (ps-1)->level == 1)
{
ps--;
if (Fun[ps->op].addr(&pack))
{
printf("第 %d 號函數執行錯誤\n", ps->op);
return (ps->op);
}
}
continue;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 數值常量 ?, 壓入數值堆棧 */
ASC63:
str++;
pack.sp->num = rule->num[*str++];
pack.sp->type = NUMBER;
(pack.sp)++;
continue;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 函數 @, 壓入符號堆棧 */
ASC64:
str++;
ps->op = *str++;
i = *str++;
ps->op |= (i << 8);
ps->level = 1;
ps++;
/* O~(, 壓入符號堆棧 */
ps->op = *str++;
ps->level = 9;
ps++;
continue;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 雙目運算符 A~* B~/ C~+ D~- E~< F~<= G~> H~>= I~== J~!= K~& L~|*/
ASC65_76:
next.op = *str++;
next.level = Level[next.op - 65];
/* 處理此前級別不高于此級別的所有運算符 */
while (ps > sign && (ps-1)->level <= next.level)
{
ps--;
Calc[ps->op - 65].addr(&pack);
}
/* 將新的雙目運算符壓入符號堆棧 */
*ps++ = next;
continue;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 分隔符 N~?~:~',' 都不壓入符號堆棧 */
ASC78:
str++;
/* 處理前面所有小級別運算符 */
while (ps > sign && (ps-1)->level < 8)
{
ps--;
Calc[ps->op - 65].addr(&pack);
}
continue;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 雙目定界符左括號 O~(, P~[, 壓入符號堆棧 */
ASC79_80:
ps->op = *str++;
ps->level = 9;
ps++;
continue;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 雙目定界符右方括號 Q~], 不壓入符號堆棧 */
ASC81:
str++;
/* 處理前面所有運算符直至左方括號 */
while (ps > sign && (ps-1)->op != 80)
{
ps--;
Calc[ps->op - 65].addr(&pack);
}
ps--; /* 將左括號從堆棧中彈出 */
/* 進行條件運算 */
pack.sp -= 3;
if ((pack.sp + 1)->type)
{
pack.sp->num = ((int)(pack.sp->num)) ? (pack.sp + 1)->num : (pack.sp + 2)->num;
(pack.sp)++;
}
else
{
/* 字符串條件運算 */
if ((int)pack.sp->num)
strcpy(pack.sp->str, (pack.sp + 1)->str);
else
strcpy(pack.sp->str, (pack.sp + 2)->str);
pack.sp->type = STRING;
(pack.sp)++;
}
continue;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 條件跳轉 R, 絕對跳轉 S */
ASC82_83:
/* 處理所有未處理的運算符 */
while (ps > sign)
{
ps--;
Calc[ps->op - 65].addr(&pack);
}
if (*str++ == 'R')
{
/* 條件跳轉 */
(pack.sp)--;
if (pack.sp->num)
str = rule->str + rule->addr[*str];
else
str++;
}
else
str = rule->str + rule->addr[*str]; /* 絕對跳轉 */
ps = sign;
pack.sp = sta;
pack.vp = pfield;
continue;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -