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

📄 tokenoper_c.cpp

📁 MCS51单片机的宏汇编器源程序。有需要的朋友请下载!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    case StrDataKn : break;
    default : { err = ExpToPack(pt);       // pt不受影响
                if( err ) { return -1; }   // 不是数值表达式, 或者数值表达式有错误!
                 // 是数值表达式开头, pt->next = "Exp Token"
              } // end default
  } // end switch
  ++count;
  Tokenfield* prev = pt->next; pt = prev->next;  // Now, pt="ExpToken"->next, maybe ','.

  while(pt && pt->Token == ',')
  { if(!pt->next) { err = ExcesComErr; return count; } // 如果它为空, 表达式个数为1.
    switch(pt->next->Token)
    { case LongCharn :
      case StrDataKn : break;
      default : { err = ExpToPack(pt);      // pt不受影响
                  if( err ) { return -1; }   // 不是数值表达式, 或者数值表达式有错误!
                } // end default
    } // end switch
    pt = pt->next;
    DelnextTokenNode(prev);      // Delete the ','
    prev = pt; pt = pt->next;
    ++count;
  } // end while
  // 如果正确的话,pt==NULL. pt!=NULL, 说明发生了错误。
  if(pt) { err = ExpExcessErr; return count; } // 表达式后面出现多余的不合法的字符
  // Now, pt == NULL, succeed.
            //DebugMsg(printf("\nCalCExpNo count=%d",count); Debugkey;)
  return count;
} // end IsCExpList
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 该函数返回 "p->next" 的操作数个数(可以是零), 各个操作数以','作为分隔.
// 注意,是"p->next"!! 所以p 不能为空.
// 有错返回-1. err返回出错码.
// 最多有127个操作数.
// err = ExpNULLErr, MissRtErr, MissLtErr, ExpSyrErr, MissEleErr
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// 如果是表达式之间有语法错误, err返回出错码.
// err = ExcesComErr, ExpExcessErr, OPadExcessErr
//---------------------------------------------------------------------------
int8 TokenOper::CalOPadNum(Tokenfield* pt, ERR &err)
{ err = OPadToPack(pt);      // 判断它是否操作数, pt不受影响
  if( err )
  { if(err == ExpNULLErr) { err = 0; return 0; } // 操作数个数为零.
    else return -1;  // 不是操作数, 或者操作数有错误!
  } // endif
  // 是操作数开头, p->next = "OPad Token"
  Tokenfield* prev = pt->next; // Now, prev = "OPad Token"
  pt = prev->next;      // Now, p = "OPad Token"->next, maybe ','
  int8u count = 1;

  while(pt && pt->Token == ',')
  { if(!pt->next)            // 如果它为空
     { err = ExcesComErr; return count; }
    err = OPadToPack(pt);    // pt不受影响
    if( err ) { return -1; } // 不是操作数, 或者操作数有错误!
  // 又是操作数, pt->next = "OPad Token"
    pt = pt->next;  // Now, pt = "OPad Token"
    DelnextTokenNode(prev);      // Delete the ','
    prev = pt;               // Now, prev = "OPad Token"
    pt = pt->next;     // Now, p = "OPad Token"->next
    count++;
  } // end while
  // 如果正确的话,pt==NULL. pt!=NULL, 说明发生了错误。
  if(pt) { err = OPadExcessErr; return count; } // 表达式后面出现多余的不合法的字符
  // Now, pt == NULL, succeed.
             //DebugMsg(printf("\nCal OPad Num count=%d",count); Debugkey;)
  return count;
} // end CalOPadNum
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 计算pt->next所指的Token为起点的WordsToken串的长度。
// 注意:是pt->next!
// pt不能为空。注意pt带值返回。pt移到了WordList之后,可能为NULL, ','。
//---------------------------------------------------------------------------
int8 TokenOper::CalWordNum(Tokenfield* &pt, ERR &err)
{ int8u len = 0; err = OK_no_Err;          // 对err值清零。

  pt = pt->next;            // 移到下一个Token.
  if(pt == NULL) { return 0; } // endif
  if(pt->Token == ',')              // 在Word之前就先有','?
   { err = ExcesComErr; return 0; } // endif
  if(pt->Token == WordSToken)
   { ++len;
     pt = pt->next;         // 移到','上。
     while(pt && pt->Token == ',')
      { pt = pt->next;      // 移到','后。
        if(pt && pt->Token == WordSToken)
         { ++len;
           pt = pt->next;   // 移到WordsToken后。
         } // endif
        else { err = ExcesComErr; break; } // end else
      } // end while
   } // endif
  return len;
} // end CalWordNum
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 注意: 是 pt->next !! pt不能为空.
// 把pt->next所指的Token为起点, 长度为len的一个表达式封装为WordList.
// 其 ExpPt 域指向Word表。
// 要特别注意的是,len!=0,也不要超长(视乎该表达式的实际长度而定),否则程序崩溃!!
// 在使用完后,要释放节点!
//---------------------------------------------------------------------------
void TokenOper::WordListToToken(Tokenfield* pt, int8u len)
{ Tokenfield* ExpNode = new Tokenfield;
  ExpNode->Token = WordList;
  ExpNode->ExpPt = pt->next;    // 创建一棵子树。
  pt->next = ExpNode;
  for( pt = ExpNode->ExpPt; len > 1; len-- )
   { if(pt->next && pt->next->Token == ',')  // 如果下一个节点是',',删除。
      { DelnextTokenNode(pt); } // endif
     pt = pt->next;
   } // end for
  // Now, pt 移到表达式尾部。
  ExpNode->next = pt->next;
  pt->next = NULL;
} // end WordListToToken
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 注意: 是 pt->next !! pt不能为空.
// 把pt->next所指的Token为起点, 长度为len的一个表达式封装为WordList.
// 该WordList用()括住。返回WordList长度。
// 注意:pt带值返回!!!
//---------------------------------------------------------------------------
int8 TokenOper::CalWordNumAndPack(Tokenfield* &pt, ERR &err)
{ err = OK_no_Err;  // 置初值为正确 = 0
  if(pt->next == NULL)
   { err = ArguInsufErr; return 0; } // endif
  // Now, pt->next != NULL
  if(pt->next->Token != '(')
   { err = MissLtErr; return 0; } // endif
  // Now, pt->next == '('
  DelnextTokenNode(pt);
  // Now, pt->next == '('后。
  Tokenfield* npt = pt;
  int8 len = CalWordNum(npt, err); // 查看pt->next...
  if(err) { return err; } // endif
  if(len == 0) { err = ArguInsufErr; return 0; } // endif
  // Now, no error. len!=0.
  WordListToToken(pt, len);
  pt = pt->next;
  // Now, pt->Token == WordList

  if(pt->next == NULL)
   { err = MissRtErr; return 0; } // endif
  // pt->next != NULL
  if(pt->next->Token != ')')
   { err = MissRtErr; return 0; } // endif
  if(pt->next)     // pt->next != NULL, pt->next == ')'
   { DelnextTokenNode(pt);
     if(pt->next && pt->next->Token == ',')  // 删除后面紧跟着的','
      { DelnextTokenNode(pt); } // endif
   } // endif
  // Now, pt->Token == WordList
  return len;
} // end CalWordNumAndPack
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// pt + ',' + word   word不能是保留字或其他符号。
// 该函数会把‘,’结点删除。
// 注意pt->next才是开头。而输入的是pt。pt->next不能为空!!
//  err = ExcesComErr
//  err = ArguExcevErr
//  err = ParaNameDefErr
//---------------------------------------------------------------------------
ERR TokenOper::ArgvWordParser(Tokenfield* pt)
{ if(pt->next->Token == ',')
   { DelnextTokenNode(pt); } // endif
  // 已经把参数前面的逗号删除了。
  pt = pt->next;
  if( !pt )                          // <==> pt == NULL
   { return ExcesComErr; } // endif
  if(pt->Token < WordSToken)         // 是其他符号
   { return ArguExcevErr; } // endif
  if(pt->Token > WordSToken)         // 是保留字
   { return ParaNameDefErr; } // endif

  return OK_no_Err;
} // end ArgvWordParser
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// pt + ',' + word + [= val]   word不能是保留字或其他符号。
// 该函数用于$SET的语法分析。
// 该函数会把‘,’结点删除。   val默认为0xFFFF。
// 注意pt->next才是开头。而输入的是pt。pt->next不能为空!!
//  err = ExcesComErr
//  err = ArguExcevErr
//  err = ParaNameDefErr
//  err = MissParasErr
//  err = ArguExcevErr
//---------------------------------------------------------------------------
ERR TokenOper::ArgvWordEvluParser(Tokenfield* pt)
{ if(pt->next->Token == ',')
   { DelnextTokenNode(pt); } // endif
  // 已经把参数前面的逗号删除了。
  pt = pt->next;
  if( !pt )                          // <==> pt == NULL
   { return ExcesComErr; } // endif
  if(pt->Token < WordSToken)         // 是其他符号
   { return ArguExcevErr; } // endif
  if(pt->Token > WordSToken)         // 是保留字
   { return ParaNameDefErr; } // endif
  // Now, pt->Token == WordSToken
  pt->Value = 0xffff;                // 赋上默认值。

  if(pt->next && pt->next->Token == '=')
   { DelnextTokenNode(pt); // 把等号删除。
     if(pt->next == NULL) { return MissParasErr; } // endif
     if(pt->next->Token != ValueToken) { return ArguExcevErr; } // endif
     // Now, pt->next->Token == Value
     pt->Value = pt->next->Value; // 把数值放到WordSToken的下面。
     DelnextTokenNode(pt); // 把数值删除。
   } // endif
  return OK_no_Err;
} // end ArgvWordEvluParser
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 在一个链表中寻找含有指定名字的Token。
// 输入head为一个Token链表。
//---------------------------------------------------------------------------
Tokenfield* TokenOper::SearchToken(Tokenfield* head, const Jstring& fname)
{ register Tokenfield* lpt;
  for( lpt = head;
           lpt && fname != lpt->Name;
               lpt = lpt->next ); // end for
  return lpt;
} // end SearchLocalArg
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 检查从lpt指向的Token链开始到pt之前的结点的Name是否与pt所指向的Name相同。
// 相同表示有重名错误。返回Have_Errs;
// 注意,lpt必须是链表!而且lpt必须在pt之前或相等!lpt可以是NULL。
//---------------------------------------------------------------------------
bool TokenOper::HaveArguName(Tokenfield* lpt, Tokenfield* pt)
{ for( ; lpt && lpt != pt; lpt = lpt->next )
   { if(pt->Name == lpt->Name) { return true; } // endif
   } // end for
  return false;
} // end HaveArguName
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
// 从pt开始的Token节点直到链尾, 在屏幕上显示出来.
//---------------------------------------------------------------------------
void TokenOper::showTknList(Tokenfield* pt)
{ cout<<"----------------------------";
  int16u count=0;
  for( ; pt; pt = pt->next )            // 直到 pt==NULL 为止
   { printf("\n[%u]:",count++);
     pt->show();
   } // end for
  cout<<"\n----------------------------"; Debugkey;
} // end showTknList
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// end TokenOper_C.cpp
//---------------------------------------------------------------------------
//               Written by JamesyFront.    ZLGmcu Dev.Co.Ltd.  2002.
//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -