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