📄 tokenoper_c.cpp
字号:
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 + -