?? formula.c
字號:
/***************************************
Filename : formula.c
Version : Formula Language V1.1
Author : Shen Tu Hongnan
Modify :
Date : 2001/08/26
Remark :
***************************************/
#define UNIX
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdarg.h>
#include <time.h>
#ifdef UNIX
#include <sys/types.h>
#include <sys/times.h>
#endif
#include "formula.h"
//#include "d:\mds\formula.h"
/*************************************************************************/
/* 堆棧及變量 */
typedef struct {
FIELD *sp; /* 運算堆棧指針 */
FIELD **vp; /* 賦值堆棧指針 */
FIELD *px; /* 輸入變量組 */
FIELD *py; /* 輸出變量組 */
FIELD *pz; /* 臨時變量組 */
} PACK;
/* 函數(shù)名,函數(shù)指針 */
typedef struct {
char name[16];
int (*addr)(PACK *pp);
} FUN_LIST;
/* 運算符號 */
typedef struct {
int op; /* 操作符 */
short level; /* 優(yōu)先級 */
} SIGN;
extern int MaxFun;
extern FUN_LIST Fun[];
//#include "d:\mds\function.c"
/*****************************************************************************/
static void Calc65(PACK *pp);
static void Calc66(PACK *pp);
static void Calc67(PACK *pp);
static void Calc68(PACK *pp);
static void Calc69(PACK *pp);
static void Calc70(PACK *pp);
static void Calc71(PACK *pp);
static void Calc72(PACK *pp);
static void Calc73(PACK *pp);
static void Calc74(PACK *pp);
static void Calc75(PACK *pp);
static void Calc76(PACK *pp);
static void Calc77(PACK *pp);
typedef struct {
void (*addr)(PACK *pp);
} OPERATION;
static OPERATION Calc[13] = {
{Calc65,},
{Calc66,},
{Calc67,},
{Calc68,},
{Calc69,},
{Calc70,},
{Calc71,},
{Calc72,},
{Calc73,},
{Calc74,},
{Calc75,},
{Calc76,},
{Calc77,},
};
static short Level[12] = {2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 6};
/*65* ,66/,67+,68-,69<,70<=,71>,72>=,73==,74!=,75&&,76||,77=*/
/*************************************************************************
Function: ReadRuleFile()
Purpose : 從規(guī)則文件中讀入公式行到運算規(guī)則 rule 中。
Input : 規(guī)則文件指針 fp,規(guī)則指針 rule。
Return : 返回 0,出錯時返回非零的錯誤代碼。
Modify : 無
Remark : 對公式語言進行了預(yù)編譯
錯誤代碼:
1...函數(shù)名錯
2...if....goto 語句錯
3...goto 語句錯
4...賦值表達式錯
5...下標(biāo)超出范圍
6...標(biāo)號錯誤
7...無效字符
8...邏輯非對象缺少括號
9...配對符號錯誤
10...常數(shù)太多
11...規(guī)則文件超長
*************************************************************************/
#define ERROR5 printf("第 %d 行:下標(biāo)超出范圍\n", line)
#define ERROR9 printf("第 %d 行:配對符號錯誤\n", line)
/*****************************************************************************/
int ReadRuleFile(FILE *fp, RULE *rule)
{
int i = 0, np = 0, line = 0, par1 = 0, par2 = 0;
int j, k, n, m, if_goto_flag;
char *bp, *tp;
char buf[256], tmp[64];
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
while (fgets(buf, sizeof(buf), fp) != (char *)NULL)
{
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
line++;
/* 注釋行或空行,忽略 */
if (*buf == '#' || *buf == '\n' || *buf == '\0')
continue;
/* 解析公式行 */
bp = buf;
if_goto_flag = 0;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
while (*bp != '\n' && *bp != '\0')
{
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* # 號后為注釋,忽略 */
if (*bp == '#')
break;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 數(shù)值常量 */
if (isdigit(*bp) || *bp == '.')
{
if (np >= 256)
{
printf("第 %d 行:常數(shù)太多\n", line);
return (10);
}
/* 將常數(shù)串移入 tmp */
tp = tmp;
do {
*tp++ = *bp++;
} while (isdigit(*bp) || *bp == '.');
*tp = '\0';
/* 設(shè)置規(guī)則串并將值保存 */
rule->str[i++] = '?';
rule->str[i++] = np & 0x00FF;
rule->num[np++] = atof(tmp);
continue;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 大寫字母開頭的為函數(shù)名 */
if (isupper(*bp))
{
/* 取函數(shù)名 */
tp = tmp;
while (*bp != '(')
*tp++ = *bp++;
*tp = '\0';
/* 查找函數(shù)在數(shù)組中的下標(biāo) */
n = 1;
m = MaxFun;
while (n <= m)
{
j = (m + n)/2;
if ((k = strcmp(tmp, Fun[j].name)) == 0)
break;
if (k > 0)
n = j + 1;
else
m = j - 1;
}
if (k != 0)
{
printf("第 %d 行:錯誤的函數(shù)名\n", line);
return (1);
}
/* 置內(nèi)部函數(shù)名 */
rule->str[i++] = '@';
rule->str[i++] = j & 0x00FF;
rule->str[i++] = (j >> 8) & 0x00FF;
continue;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 其他情形的解析 */
switch (*bp)
{
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 空白字符,忽略 */
case ' ':
case '\t':
bp++;
break;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 字符串常量 */
case '"':
rule->str[i++] = *bp++;
while ((rule->str[i++] = *bp++) != '"');
continue;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* if 語句,置 if_goto_flag 標(biāo)志 */
case 'i':
bp++;
if (*bp++ == 'f' && if_goto_flag == 0)
if_goto_flag = 1;
else
{
printf("第 %d 行:if....goto 語句錯\n", line);
return (2);
}
break;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* goto 語句 */
case 'g':
bp++;
if (*bp++ != 'o' || if_goto_flag == 2)
{
printf("第 %d 行:goto 語句錯\n", line);
return (3);
}
while (islower(*bp) || *bp == ' ' || *bp == '\t')
bp++;
/* goto 后面沒有標(biāo)號 */
if (*bp++ != '@')
{
printf("第 %d 行:goto 語句錯\n", line);
return (3);
}
/* R 條件轉(zhuǎn)移,S 絕對轉(zhuǎn)移 */
if (if_goto_flag)
rule->str[i++] = 'R';
else
rule->str[i++] = 'S';
if_goto_flag = 2;
/* 計算標(biāo)號 */
j = 0;
while (isdigit(*bp))
j = 10*j + *bp++ - 48;
if (j >= RULE_ADDR_SIZE)
{
ERROR5;
return (5);
}
rule->str[i++] = j;
break;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 變量 */
case 'x':
case 'y':
case 'z':
/* 改為大寫字母 */
rule->str[i++] = *bp++ - 32;
/* 確定下標(biāo) */
j = 0;
while (isdigit(*bp))
j = 10*j + *bp++ - 48;
if (j >= 256 || (rule->str[i-1] == 'Z' && j >= Zarray_SIZE))
{
ERROR5;
return (5);
}
rule->str[i++] = j;
/* 賦值對象,XYZ 改為UVW,并且跳過等號 */
while (*bp == ' ' || *bp == '\t')
bp++;
if (*bp == '=' && *(bp+1) != '=')
{
rule->str[i-2] -= 3;
bp++;
}
break;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 標(biāo)號 */
case '@':
/* 取數(shù)字串 */
bp++;
j = 0;
while (isdigit(*bp))
j = 10*j + *bp++ - 48;
if (j >= RULE_ADDR_SIZE)
{
ERROR5;
return (5);
}
while (*bp == ' ' || *bp == '\t') bp++;
if (*bp++ != ':')
{
printf("第 %d 行:標(biāo)號錯誤\n", line);
return (6);
}
/* 置跳轉(zhuǎn)地址 */
rule->addr[j] = i;
break;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 運算符 */
case '*':
rule->str[i++] = 'A';
bp++;
break;
case '/':
rule->str[i++] = 'B';
bp++;
break;
case '+':
rule->str[i++] = 'C';
bp++;
break;
case '-':
rule->str[i++] = 'D';
bp++;
break;
/* <, <= */
case '<':
rule->str[i++] = 'E';
if (*(++bp) == '=')
{
bp++;
rule->str[i-1] = 'F';
}
break;
/* >, >= */
case '>':
rule->str[i++] = 'G';
if (*(++bp) == '=')
{
bp++;
rule->str[i-1] = 'H';
}
break;
/* == */
case '=':
rule->str[i++] = 'I';
bp++;
if (*bp++ != '=')
{
printf("第 %d 行:賦值表達式錯\n", line);
return (4);
}
break;
/* !, != */
case '!':
if (*(++bp) == '=')
{
bp++;
rule->str[i++] = 'J';
}
else
{
rule->str[i++] = '@';
rule->str[i++] = 0;
rule->str[i++] = 0;
while (*bp == ' ' || *bp == '\t') bp++;
if (*bp != '(')
{
printf("第 %d 行:邏輯非對象缺少括號\n", line);
return (8);
}
}
break;
/* && */
case '&':
rule->str[i++] = 'K';
if (*(++bp) == '&')
bp++;
break;
/* || */
case '|':
rule->str[i++] = 'L';
if (*(++bp) == '|')
bp++;
break;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 分隔符及括號 */
case '?':
case ':':
case ',':
rule->str[i++] = 'N';
bp++;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -