📄 logic.c
字号:
//逻辑运算 用于条件判断
#include <CsAgb.h>
#include <cal.h>
#include <rb_string.h>
#include <rbasic.h>
#include <rb_stdio.h>
void exp_unfold(char *exp)//删除多余括号
{
u8 i=0;
u8 fla;
exp_adj(exp);
if (exp[0]!='(') return;
fla=1;
i=1;
while(fla && exp[i]!='\0')
{
if (exp[i]=='(') fla++;
else if (exp[i]==')') fla--;
i++;
}
if (exp[i]=='\0')//可以删除
{
exp[i-1]='\0';
exp[0]=' ';
exp_adj(exp);
}
}
u8 is_cmp(char ch) //是否为比较符
{
char cmp[4]="><=";
u8 i;
for (i=0;i<3;i++)
{
if (ch==cmp[i]) return i+1;
}
return 0;
}
u8 get_cmp_tp(char *exp)//获得比较类型
{
exp_adj(exp);
if (str_len(exp)>2) return 0;//错误
if (exp[0]=='<' && exp[1]=='>') return 6;//<>
if (exp[0]=='<' && exp[1]=='=') return 5;//<=
if (exp[0]=='>' && exp[1]=='=') return 4;//>=
if (exp[0]=='=' && exp[1]=='\0') return 3;//=
if (exp[0]=='<' && exp[1]=='\0') return 2;//<
if (exp[0]=='>' && exp[1]=='\0') return 1;//>
return 0;//ERROR!
}
u8 logic_cmp(char *exp)//计算逻辑比较真值
{
u8 i=0,j=0;
u8 istr=0;
u8 cmp_tp=0;
double x1=0,x2=0;
char cmp[3]="\0\0\0";
char str[str_max_len];
exp_unfold(exp);
while (exp[i]!='\0')
{
if (exp[i]=='\"')
{
istr=!istr;
str[i]=exp[i];
i++;
}
else if (is_cmp(exp[i]) && istr==0)//发现逻辑比较符
{
str[i]='\0';
cmp[0]=exp[i];
if (is_cmp(exp[i+1]))
{
cmp[1]=exp[i+1];
i++;
}
cmp_tp=get_cmp_tp(cmp);
if (!cmp_tp || exp[i+1]=='\0')//语法错误
{
rb_error=6;
return 0;
}
x1=rb_cal(str);
j=0;
i++;
while(exp[i]!='\0')
{
str[j]=exp[i];
i++;
j++;
}
str[j]='\0';
x2=rb_cal(str);
x1=x1-x2;
switch (cmp_tp)
{
case 1://x1>x2
return x1>0?1:0;
case 2://x1<x2
return x1<0?1:0;
case 3://x1=x2
return x1==0?1:0;
case 4://x1>=x2
return x1>=0?1:0;
case 5://x1<=x2
return x1<=0?1:0;
case 6://x1<>x2
return x1!=0?1:0;
default:
return 0;
}
}
else
{
str[i]=exp[i];
i++;
}
}
x1=rb_cal(exp);//没有发现比较符
return x1>0?1:0;
}
u8 is_logic(char ch)//获得逻辑运算类型
{
return (ch=='&' || ch=='|' || ch=='!');
}
/*void exp_chg(char *exp)
{
u8 i=0;
while (exp[i]!='#')
{
if (exp[i]=='0') exp[i]=0;
else if(exp[i]=='1') exp[i]=1;
i++;
}
}
void exp_rchg(char *exp)
{
u8 i=0;
while (exp[i]!='#')
{
if (exp[i]==0) exp[i]='0';
else if(exp[i]==1) exp[i]='1';
i++;
}
}*/
void logic_simple(char *exp)//!!化简
{
u8 i=0,j=0;
u8 count=0;
if (exp[0]>1 && exp[i]!='!')//出错
{
exp[0]='#';
return;
}
while (exp[i]!='#')
{
if (exp[i]=='!')
{
count=1;
i++;
while(exp[i]=='!')
{
count++;
i++;
}
if (count%2)//奇数个!
{
if (exp[i]<2)
{
exp[j]=!exp[i];
i++;
j++;
}
else//出错
{
exp[0]='#';
return;
}
}
}
else
{
exp[j]=exp[i];
i++;
j++;
}
}
if (exp[i-1]>1) j=0;
exp[j]='#';
}
u8 logic_cal(char *exp)//原子逻辑运算(诸如1*0+1+0)
{
u8 i=0;
u8 reg[3];
u8 rp=0;
u8 orp=0;
logic_simple(exp);
if (exp[0]=='#')
{
rb_error=6;
return 0;
}
while (exp[i]!='#')//exp以#结束
{
if (i%2)//运算符
{
if(exp[i]=='&' && exp[i+1]<2)//与运算
{
reg[rp-1]=reg[rp-1]&exp[i+1];
i++;
}
else if(exp[i]=='|')
{
//if (reg[0]) return 1;//已经为真
if (orp)//可以先行运算
{
reg[rp-2]=reg[rp-2]||reg[rp-1];
rp--;
}
else orp=1;
}
else//出错
{
rb_error=6;
return 0;
}
}
else
{
if (exp[i]>1)//出错
{
rb_error=6;
return 0;
}
reg[rp]=exp[i];
rp++;
}
i++;
}
if (rp==1) return reg[0];
return reg[0]||reg[1];
}
u8 logic_exe(char *exp)//逻辑运算解释执行器(逻辑运算符必须以空格断开)
{
u8 i=0;
u8 lgc[str_max_len]="#";
u8 lgcp=0;
char str[str_max_len];
u8 strp=0;
u8 fla=0,fla1=0;
exp_adj(exp);//删除首尾空格
exp_unfold(exp);//删除多余括号
str_replace(exp,"AND ","&");
str_replace(exp,"AND(","&(");
str_replace(exp,"OR ","|");
str_replace(exp,"OR(","|(");
str_replace(exp,"NOT ","!");
str_replace(exp,"NOT!(","!(");//逻辑运算符变换
while (exp[i]!='\0')
{
if (is_logic(exp[i]))//发现逻辑运算符
{
if (fla) {str[strp]=exp[i];strp++;fla1=1;}//在括号之内
else
{
if (strp==0 && exp[i]!='!')//错误的逻辑运算符位置
{
rb_error=6;
return 0;
}
if (!(exp[i]=='!' && strp==0))
{
str[strp]='\0';
strp=0;
if(fla1)
{
lgc[lgcp]=logic_exe(str);
fla1=0;
}//是逻辑式
else lgc[lgcp]=logic_cmp(str);//是比较式
lgcp++;
}
lgc[lgcp]=exp[i];
lgcp++;
}
}
else
{
if (exp[i]=='(') fla++;
else if (exp[i]==')') fla--;
if (exp[i]!=' ') {str[strp]=exp[i];strp++;}
}
i++;
}
if (fla)//括号不配对
{
rb_error=6;
return 0;
}
str[strp]='\0';
if (fla1) lgc[lgcp]=logic_exe(str);
else lgc[lgcp]=logic_cmp(str);
lgc[lgcp+1]='#';//置结束符
return logic_cal(lgc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -