C++ AST Visitor - 存储表达式值的问题
C++ AST Visitor - Problems to store value of expressions
我正在尝试编写一个简单的脚本系统(用于视频游戏),其中没有复杂的任务,只有简单的布尔检查和操作集。
我是一名学生,但我不是在学习编程,我只是作为一种爱好,所以我正在学习基础知识,最近我觉得要编写自己的解析器和解释器,
但由于这是我的第一种 AST 方法,我不明白为什么结果一直是 true 而不是 false(对于给定的表达式),也想知道它是否是我正在寻找的最佳方法。
你可以用我的源文件编译就好了。
Expression.h
#pragma once
enum OperatorType
{
OPERATOR_EQUALS = 0, // =
OPERATOR_LESSER_THAN, // <
OPERATOR_GREATER_THAN, // >
OPERATOR_LESSER_OR_EQUALS, // <=
OPERATOR_GREATER_OR_EQUALS, // >=
OPERATOR_UNEQUAL, // <>
OPERATOR_MULTIPLY, // *
OPERATOR_SUM, // +
OPERATOR_SUB, // -
};
class Expression;
class ATSVisitor;
class ATSNode
{
public:
virtual void accept(ATSVisitor* visitor) = 0;
};
class ATSRoot
{
public:
Expression* expression;
};
class Expression : public ATSNode
{
public:
~Expression()
{
left = nullptr;
right = nullptr;
}
virtual void accept(ATSVisitor* visitor) = 0;
Expression* left;
Expression* right;
};
class OperationExpression : public Expression
{
public:
OperationExpression() : Expression(){}
virtual void accept(ATSVisitor* visitor);
OperatorType type;
};
class NumberExpression : public Expression
{
public:
NumberExpression() : Expression(){ value = 0; }
virtual void accept(ATSVisitor* visitor);
int value;
};
class ATSVisitor
{
public:
ATSVisitor()
{
Result = false;
}
bool evaluate(ATSRoot* root);
void visit(OperationExpression* expression);
void visit(NumberExpression* expression);
bool Result;
int number;
};
Expression.cpp
#include "expressions.h"
#include <iostream>
void OperationExpression::accept(ATSVisitor* visitor)
{
visitor->visit(this);
}
void NumberExpression::accept(ATSVisitor* visitor)
{
visitor->visit(this);
}
bool ATSVisitor::evaluate(ATSRoot* root)
{
std::cout << "Evaluating ROOT" << std::endl;
bool result = false;
root->expression->accept(this);
result = Result;
return result;
}
void ATSVisitor::visit(OperationExpression* expression)
{
std::cout << "Visitor just visited OPERATIONEXPRESSION: " << expression->type << std::endl;
expression->left->accept(this);
int leftValue = number;
expression->right->accept(this);
int rightValue = number;
switch (expression->type)
{
case OPERATOR_EQUALS:
Result = leftValue == rightValue;
case OPERATOR_GREATER_OR_EQUALS:
Result = leftValue >= rightValue;
case OPERATOR_GREATER_THAN:
Result = leftValue > rightValue;
case OPERATOR_LESSER_OR_EQUALS:
Result = leftValue <= rightValue;
case OPERATOR_LESSER_THAN:
Result = leftValue < rightValue;
case OPERATOR_MULTIPLY:
Result = leftValue * rightValue;
case OPERATOR_SUB:
Result = leftValue - rightValue;
case OPERATOR_SUM:
Result = leftValue + rightValue;
case OPERATOR_UNEQUAL:
Result = leftValue != rightValue;
}
}
void ATSVisitor::visit(NumberExpression* expression)
{
std::cout << "Visitor just visited NUMBEREXPRESSION: " << expression->value << std::endl;
number = expression->value;
}
Main.cpp
#include <iostream>
#include "expressions.h"
int main(int argc, char** argv)
{
ATSVisitor* visitor = new ATSVisitor();
// QuestValue(100)>=10
ATSRoot* root = new ATSRoot();
OperationExpression* operation = new OperationExpression();
operation->type = OPERATOR_GREATER_OR_EQUALS;
NumberExpression* number1 = new NumberExpression();
number1->value = 1;
NumberExpression* number2 = new NumberExpression();
number2->value = 10;
operation->left = number1;
operation->right = number2;
root->expression = operation;
if (!visitor->evaluate(root))
{
std::cout << "\nOperation evaluation FAILED!" << std::endl;
}
else
{
std::cout << "\nOperation evaluation SUCCEED!" << std::endl;
}
std::cout << "Finished" << std::endl;
std::cin.get();
delete root;
delete number1;
delete number2;
delete operation;
return EXIT_SUCCESS;
}
基本上这个带有访问者模式的 AST 应该解析如果当我的分词器解析这个脚本时:
1>=10
会不会return成功与否
您的 switch
陈述与您认为的不符。
在 C++ 中,与在 C 中一样,执行 switch
语句会导致控制流跳转到适当的 case 标签。然后它执行块的其余部分,这意味着它会执行以下 case 标签,然后执行下一个,除非它遇到 break
语句。
不用说,正常的风格是每个个案例部分以break
:
结束
switch (expression->type)
{
case OPERATOR_EQUALS:
Result = leftValue == rightValue;
break;
case OPERATOR_GREATER_OR_EQUALS:
Result = leftValue >= rightValue;
break;
case OPERATOR_GREATER_THAN:
Result = leftValue > rightValue;
break;
case OPERATOR_LESSER_OR_EQUALS:
Result = leftValue <= rightValue;
break;
case OPERATOR_LESSER_THAN:
Result = leftValue < rightValue;
break;
case OPERATOR_MULTIPLY:
Result = leftValue * rightValue;
break;
case OPERATOR_SUB:
Result = leftValue - rightValue;
break;
case OPERATOR_SUM:
Result = leftValue + rightValue;
break;
case OPERATOR_UNEQUAL:
Result = leftValue != rightValue;
break;
}
否则,不管expression->type
的计算结果是什么(只要它的计算结果是其中一个标签表达式),它最终都会执行最后的语句,Result = leftValue != rightValue;
.
我正在尝试编写一个简单的脚本系统(用于视频游戏),其中没有复杂的任务,只有简单的布尔检查和操作集。
我是一名学生,但我不是在学习编程,我只是作为一种爱好,所以我正在学习基础知识,最近我觉得要编写自己的解析器和解释器, 但由于这是我的第一种 AST 方法,我不明白为什么结果一直是 true 而不是 false(对于给定的表达式),也想知道它是否是我正在寻找的最佳方法。
你可以用我的源文件编译就好了。
Expression.h
#pragma once
enum OperatorType
{
OPERATOR_EQUALS = 0, // =
OPERATOR_LESSER_THAN, // <
OPERATOR_GREATER_THAN, // >
OPERATOR_LESSER_OR_EQUALS, // <=
OPERATOR_GREATER_OR_EQUALS, // >=
OPERATOR_UNEQUAL, // <>
OPERATOR_MULTIPLY, // *
OPERATOR_SUM, // +
OPERATOR_SUB, // -
};
class Expression;
class ATSVisitor;
class ATSNode
{
public:
virtual void accept(ATSVisitor* visitor) = 0;
};
class ATSRoot
{
public:
Expression* expression;
};
class Expression : public ATSNode
{
public:
~Expression()
{
left = nullptr;
right = nullptr;
}
virtual void accept(ATSVisitor* visitor) = 0;
Expression* left;
Expression* right;
};
class OperationExpression : public Expression
{
public:
OperationExpression() : Expression(){}
virtual void accept(ATSVisitor* visitor);
OperatorType type;
};
class NumberExpression : public Expression
{
public:
NumberExpression() : Expression(){ value = 0; }
virtual void accept(ATSVisitor* visitor);
int value;
};
class ATSVisitor
{
public:
ATSVisitor()
{
Result = false;
}
bool evaluate(ATSRoot* root);
void visit(OperationExpression* expression);
void visit(NumberExpression* expression);
bool Result;
int number;
};
Expression.cpp
#include "expressions.h"
#include <iostream>
void OperationExpression::accept(ATSVisitor* visitor)
{
visitor->visit(this);
}
void NumberExpression::accept(ATSVisitor* visitor)
{
visitor->visit(this);
}
bool ATSVisitor::evaluate(ATSRoot* root)
{
std::cout << "Evaluating ROOT" << std::endl;
bool result = false;
root->expression->accept(this);
result = Result;
return result;
}
void ATSVisitor::visit(OperationExpression* expression)
{
std::cout << "Visitor just visited OPERATIONEXPRESSION: " << expression->type << std::endl;
expression->left->accept(this);
int leftValue = number;
expression->right->accept(this);
int rightValue = number;
switch (expression->type)
{
case OPERATOR_EQUALS:
Result = leftValue == rightValue;
case OPERATOR_GREATER_OR_EQUALS:
Result = leftValue >= rightValue;
case OPERATOR_GREATER_THAN:
Result = leftValue > rightValue;
case OPERATOR_LESSER_OR_EQUALS:
Result = leftValue <= rightValue;
case OPERATOR_LESSER_THAN:
Result = leftValue < rightValue;
case OPERATOR_MULTIPLY:
Result = leftValue * rightValue;
case OPERATOR_SUB:
Result = leftValue - rightValue;
case OPERATOR_SUM:
Result = leftValue + rightValue;
case OPERATOR_UNEQUAL:
Result = leftValue != rightValue;
}
}
void ATSVisitor::visit(NumberExpression* expression)
{
std::cout << "Visitor just visited NUMBEREXPRESSION: " << expression->value << std::endl;
number = expression->value;
}
Main.cpp
#include <iostream>
#include "expressions.h"
int main(int argc, char** argv)
{
ATSVisitor* visitor = new ATSVisitor();
// QuestValue(100)>=10
ATSRoot* root = new ATSRoot();
OperationExpression* operation = new OperationExpression();
operation->type = OPERATOR_GREATER_OR_EQUALS;
NumberExpression* number1 = new NumberExpression();
number1->value = 1;
NumberExpression* number2 = new NumberExpression();
number2->value = 10;
operation->left = number1;
operation->right = number2;
root->expression = operation;
if (!visitor->evaluate(root))
{
std::cout << "\nOperation evaluation FAILED!" << std::endl;
}
else
{
std::cout << "\nOperation evaluation SUCCEED!" << std::endl;
}
std::cout << "Finished" << std::endl;
std::cin.get();
delete root;
delete number1;
delete number2;
delete operation;
return EXIT_SUCCESS;
}
基本上这个带有访问者模式的 AST 应该解析如果当我的分词器解析这个脚本时:
1>=10
会不会return成功与否
您的 switch
陈述与您认为的不符。
在 C++ 中,与在 C 中一样,执行 switch
语句会导致控制流跳转到适当的 case 标签。然后它执行块的其余部分,这意味着它会执行以下 case 标签,然后执行下一个,除非它遇到 break
语句。
不用说,正常的风格是每个个案例部分以break
:
switch (expression->type)
{
case OPERATOR_EQUALS:
Result = leftValue == rightValue;
break;
case OPERATOR_GREATER_OR_EQUALS:
Result = leftValue >= rightValue;
break;
case OPERATOR_GREATER_THAN:
Result = leftValue > rightValue;
break;
case OPERATOR_LESSER_OR_EQUALS:
Result = leftValue <= rightValue;
break;
case OPERATOR_LESSER_THAN:
Result = leftValue < rightValue;
break;
case OPERATOR_MULTIPLY:
Result = leftValue * rightValue;
break;
case OPERATOR_SUB:
Result = leftValue - rightValue;
break;
case OPERATOR_SUM:
Result = leftValue + rightValue;
break;
case OPERATOR_UNEQUAL:
Result = leftValue != rightValue;
break;
}
否则,不管expression->type
的计算结果是什么(只要它的计算结果是其中一个标签表达式),它最终都会执行最后的语句,Result = leftValue != rightValue;
.