⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logic.c

📁 可以在嵌入式应用中
💻 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 + -