赋值节点的interpret接口、interpet_str接口、interpret_bool接口不是并列的关系……
这个自制编程语言的项目中,已经遇到太多的不对称的东西了,明明是相似的接口,相似的类型,但是实现却特别冗余!没办法把两个相似的函数放在一起比较,这说明一个问题,我的项目架构不好,有很多辣鸡代码!
现在来解决这个问题!
设置firstId_is_bool_flag标志项目中的数据类型:int/number/nil/bool/string
底层数据类型:double/bool/string
项目中的Token有下面三种情况
数字、数字类型的id 字符串、字符串类型的id 布尔类型的id之前为了将简单表达式从语句中抽离出来,就是用and , >= 之类的符号,分割简单表达式,将其作为判断式或逻辑式的单元!!!
为此引入了firstId_is_string_flag,因为要靠简单表达式开头的数据,区分简单表达式的模式,是否是字符串拼接模式!!!
a = TRUE;
这样的语句会调用到EqExpr的interpret接口,还会被当成计算式计算。也就是出现下面这张情况
a = 1 + TRUE;
[result]1
所以,规定
如果表达式是简单表达式,并且第一个是bool类型的id,那么,就准备退出——此id后面如果不是分号,就报错!如果是分号就如愿退出! void Parser::CreateASTree() {
//遍历全局中缀表达式
try {
for (int it = start; it *funcMap[global_infix[it]->type])(it);//处理Token和keyword
if (end_flag)break;//遇到分号跳出
if (firstId_is_bool_flag) {//表达式第一个id是bool类型的变量
if (global_infix[ ++ it]->type != SuatinTokenType_Sem) {//如果下一个不是分号
ThrowException(start,end,"boolean identifier cannot used for calculate");
return;
}
DealToken_Sem(it);
break;
}
}
if (root == NULL) ThrowException(start,end,"abstract syntax tree was none");
/*
judgeRoot exprRoot
logicRoot exprRoot
exprRoot root
最后除了root外,其他指针都为空!
*/
CheckASTreeSyntax();
}
catch (SuatinExcept& e) {
std::cout << e.what();
}
catch (...) {
std::cout <name]->type == SuatinIDType_bool) {
firstId_is_bool_flag = true;
}
}
}
void Parser::interpret() {
try {
if (m_exprType == ExprType_Simple) { //简单表达式
if (firstId_is_bool_flag) { //开头第一个是bool类型的id
bool result = root == NULL ? true : root->interpret_bool();
std::cout << "[result]" << BOOL2STR(result) << std::endl;
}
else if (m_simpleExprType == SimpleExprType_NumCalc) { //五则计算式
...
...
使EqExpr的三个解释接口并列
因为五则计算式中只有数字、字符串拼接式中只有字符串、开头bool或判断式或逻辑式的返回只有布尔,所以解释起来,清楚多了!
果然是自己辣鸡代码写多了!
//处理数字、数字类型的id--------------------
double EqExpr::interpret() {
double rightValue = right->interpret();//递归进去
////把右边的变量的值拷贝给左边的变量,因为是对符号表的操作,不改变指针,所以传入一级指针就好!!!
//auto copyBlock = [](Expr* _left,Expr* _right) {
// IDExpr* dst = dynamic_cast(_left);
// IDExpr* src = dynamic_cast(_right);
// CopyID(dst->GetName(), src->GetName());
//};
////赋值右边的表达式只有单个Id
//if (typeid(*(right->GetClassType())) == typeid(IDExpr)) { //右孩子只有个变量节点!!!
// copyBlock(left, right);
// return rightValue;
//}
//else if (typeid(*(right->GetClassType())) == typeid(EqExpr)) { //右孩子同样是个赋值节点!!!
// SymbolExpr* node_tmp = dynamic_cast(right);
// copyBlock(left, node_tmp->GetLeft());
// return rightValue;
//}
//赋值右边的表达式不是单个Id
IDExpr* var = dynamic_cast(left);
var->SetNumber(rightValue);
return rightValue;
}
//处理字符串、字符串类型的id------------------
std::string EqExpr::interpret_str() {
std::string rightValue = right->interpret_str();//递归进去
////把右边的变量的值拷贝给左边的变量,因为是对符号表的操作,不改变指针,所以传入一级指针就好!!!
//auto copyBlock = [](Expr* _left, Expr* _right) {
// IDExpr* dst = dynamic_cast(_left);
// IDExpr* src = dynamic_cast(_right);
// CopyID(dst->GetName(), src->GetName());
//};
////赋值右边的表达式只有单个Id
//if (typeid(*(right->GetClassType())) == typeid(IDExpr)) { //右孩子只有个变量节点!!!
// copyBlock(left, right);
// return rightValue;
//}
//else if (typeid(*(right->GetClassType())) == typeid(EqExpr)) { //右孩子同样是个赋值节点!!!
// SymbolExpr* node_tmp = dynamic_cast(right);
// copyBlock(left, node_tmp->GetLeft());
// return rightValue;
//}
IDExpr* var = dynamic_cast(left);
var->SetString(rightValue);
return rightValue;
}
//bool类型的id--------------------
bool EqExpr::interpret_bool() {
bool rightValue = right->interpret_bool();//递归进去
IDExpr* var = dynamic_cast(left);
var->SetBool(rightValue);
return rightValue;
}
这样操作一番后,可以看出,开头bool、五则计算、字符串拼接这几个已经是并列的了,可以看做三个模式!
项目代码下载地址