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

📄 formula.c

📁 一个简单的解析器
💻 C
📖 第 1 页 / 共 3 页
字号:
      	                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 + -