"); //-->
我们提出这个例子是为了让同学更加透彻的理解Expression Layer, 我们举一个复杂点的例子:
add(mul(@0,@1),@2),我们将以人工分析的方式去还原词法和语法分析的过程.
例子中的词法分析我们将以上的这个输入划分为多个token,多个token分别为
add | left bracket| |mul|left bracket|@0|comma|@1|right bracket| @2 |right bracket
例子中的语法分析在ExpressionParser::Generate_函数对例子add(mul(@0,@1),@2),如下的列表为token 数组.
index = 0, 当前遇到的token为add, 调用层为1
index = 1, 根据以上的流程,我们期待add token之后的token为left bracket, 否则就报错. 调用层为1
**开始递归调用,构建add的左子树.**从层1进入层2
index = 2, 遇到了mul token. 调用层为2.
index = 3, 根据以上的流程,我们期待mul token之后的token是第二个left bracket. 调用层为2.
开始递归调用用来构建mul token的左子树.
index = 4, 遇到@0,进入递归调用,进入层3, 但是因为操作数都是叶子节点,构建好之后就直接返回了,得到mul token的左子节点.放在mul token的left 指针上.
index = 5, 我们希望遇到一个逗号,否则就报错mul(@0,@1)中中间的逗号.调用层为2.
index = 6, 遇到@2,进入递归调用,进入层3, 但是因为操作数是叶子节点, 构建好之后就直接返回到2,得到mul token的右子节点.
index = 7, 我们希望遇到一个右括号,就是mul(@1,@2)中的右括号.调用层为2.
到现在为止mul token已经构建完毕,返回形成add token的左子节点,add token的left指针指向构建完毕的mul树. 返回到调用层1.
...
add token开始构建right token,但是因为@2是一个输入操作数,所以直接递归就返回了,至此得到add的右子树,并用right指针指向.
所以构建好的抽象语法树如图:
需要完成test/tet_expression.cpp下的expression3函数
TEST(test_expression, expression3) {
using namespace kuiper_infer;
const std::string &statement = "add(@0,div(@1,@2))";
ExpressionParser parser(statement);
const auto &node_tokens = parser.Generate();
ShowNodes(node_tokens);
}
static void ShowNodes(const std::shared_ptr<kuiper_infer::TokenNode> &node) {
if (!node) {
return;
}
ShowNodes(node->left);
if (node->num_index < 0) {
if (node->num_index == -int(kuiper_infer::TokenType::TokenAdd)) {
LOG(INFO) << "ADD";
} else if (node->num_index == -int(kuiper_infer::TokenType::TokenMul)) {
LOG(INFO) << "MUL";
}
} else {
LOG(INFO) << "NUM: " << node->num_index;
}
ShowNodes(node->right);
}
TEST(test_expression, expression1) {
using namespace kuiper_infer;
const std::string &statement = "add(mul(@0,@1),@2)";
ExpressionParser parser(statement);
const auto &node_tokens = parser.Generate();
ShowNodes(node_tokens);
}
最后会打印抽象语法树的中序遍历:
Could not create logging file: No such file or directory
COULD NOT CREATE A LOGGINGFILE 20230115-223854.21496!I20230115 22:38:54.863226 21496 test_main.cpp:13] Start test...
I20230115 22:38:54.863480 21496 test_expression.cpp:23] NUM: 0
I20230115 22:38:54.863488 21496 test_expression.cpp:20] MUL
I20230115 22:38:54.863492 21496 test_expression.cpp:23] NUM: 1
I20230115 22:38:54.863497 21496 test_expression.cpp:18] ADD
I20230115 22:38:54.863502 21496 test_expression.cpp:23] NUM: 2
如果语句是一个更复杂的表达式 add(mul(@0,@1),mul(@2,@3))
image-20230115224350088
我们的单元测试输出为:
I20230115 22:48:22.086627 23767 test_expression.cpp:23] NUM: 0
I20230115 22:48:22.086635 23767 test_expression.cpp:20] MUL
I20230115 22:48:22.086639 23767 test_expression.cpp:23] NUM: 1
I20230115 22:48:22.086644 23767 test_expression.cpp:18] ADD
I20230115 22:48:22.086649 23767 test_expression.cpp:23] NUM: 2
I20230115 22:48:22.086653 23767 test_expression.cpp:20] MUL
I20230115 22:48:22.086658 23767 test_expression.cpp:23] NUM: 3专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
电子元件培训教材
WTC-AI太阳能热水器电路图
AI 驱动估值飙升:光通信半导体企业市值暴涨
瑞萨电子AI单元解决方案成功提高GE医疗(日本)日野工厂的生产力
CSR8670CSR8675智能语音Alexa蓝牙方案开发
EEPW2018年3月刊(工业物联网)
PowiGaN for AI Data Centers: Unmatched Power Density and Reliability
赋能边缘端对话式人工智能
海联达(Aigale)Ai-HD1 无线全高清套件拆解
EEPW2018年6月刊(5G)
基于Microchip MCU的AI/ML培训教程2
基于Ai-WB2-12F与Rd-04的雷达检测系统
GPU:面临工作负载转变的高吞吐架构
爱立信携手 Net Feasa 布局海事网络 融合公网级通信与智能体 AI 赋能航运
WTC-AI型太阳能热水器电路图
基于Microchip MCU的AI/ML培训教程3
英伟达CFO:我们早就知道内存大涨价要来了
尼吉康的事业介绍
研华 COMPUTEX 首度整合全球伙伴大会 强化全球边缘 AI 生态系统联结
iCAN-4017 AI功能模块
AI竞争进入下半场:从“卷参数”到“卷单价”
AI热潮引发多层陶瓷电容MLCC供应短缺
基于Microchip MCU的AI/ML培训教程1
紧凑型集成连接器模块抑制噪声 为人工智能应用实现以太网供电
继上次海联达Ai-ap100拆机之电源改造
人工智能是如何帮助阻止造假者的?
Nigel AI赋能LabVIEW,NI用AI重塑测试新边界
万家乐JSYZ5-AI燃气热水器电路图
释说芯语16:硬科技:构建企业未来之路(附PPT)
基于VisitionX制造智能眼镜