编译原理中的右递归文法不会死循环吗?

发布时间:2026/9/28 19:52:39
编译原理中的右递归文法不会死循环吗? 语法规则pri - Id | Num add - pri | add pri当存在一个表达式为: 2 3 4, 通过递归下降算法对表达式进行解析会出现左递归问题左递归与结合性问题234表达式 -先匹配add表达式再是号再是pri -先匹配add表达式再是号再是pri -先匹配add表达式再是号再是pri -无限递归...为了解决这个左递归问题可以先修改语法规则尝试倒着写add - pri | pri add那么就会先计算 3 4再跟 2 相加。会得到如下ASTadd pri 2 add pri 3 pri 4这样计算也不是不行但违背了加法运算的结合性的规定。为了彻底解决这个问题需要再对文法规则进行改造消除左递归问题原始文法规则add - mul | add mul mul - pri | mul * pri pri - Id | Num | (add)右递归文法add - mul | mul add mul - pri | pri * mul pri - Id | Num | (add)这个右递归文法这样的情况就不会存在死循环但会出现结合性问题再改造文法add - mul add add - mul add | ε mul - pri | mul * pri pri - Id | Num | (add)由于 add’的规则也是右递归的如果用标准的递归下降算又会出现运算符结合性的错误所以在第一步通过add推导之后按add’规则推导具体代码// 解决左递归 // 1. 先计算add规则 // 2. 接着计算add 规则 SimpleASTNode* SimpleCalculator::additive2(TokenReader *tokens) { SimpleASTNode *child1 multiplicative(tokens); // 应用add规则 SimpleASTNode *node child1; if (child1 ! NULL) { while (true) { Token *token tokens-peek(); // 循环应用add if (token ! NULL (token-getType() TokenType::Plus || token-getType() TokenType::Minus)) { token tokens-read(); // 读出加号 SimpleASTNode *child2 multiplicative(tokens); // 计算下级节点 node new SimpleASTNode(ASTNodeType::Additive, token-getText()); node-addChild(child1); node-addChild(child2); child1 node; } else { break; } } } return node; } // mul 规则 SimpleASTNode* SimpleCalculator::multiplicative(TokenReader *tokens) { SimpleASTNode *child1 primary(tokens); SimpleASTNode *node child1; Token *token tokens-peek(); if (child1 ! NULL token ! NULL) { if (token-getType() TokenType::Star || token-getType() TokenType::Slash) { token tokens-read(); SimpleASTNode *child2 multiplicative(tokens); if (child2 ! NULL) { node new SimpleASTNode(ASTNodeType::Multiplicative, token-getText()); node-addChild(child1); node-addChild(child2); } else { throw invalid mutiplicative expression, expecting the right part.; } } } return node; } // pri 规则 SimpleASTNode* SimpleCalculator::primary(TokenReader *tokens) { SimpleASTNode *node NULL; Token *token tokens-peek(); if (token ! NULL) { if (token-getType() TokenType::IntLiteral) { // 整型字面量 token tokens-read(); node new SimpleASTNode(ASTNodeType::IntLiteral, token-getText()); } else if (token-getType() TokenType::Identifier) { // 标识符 token tokens-read(); node new SimpleASTNode(ASTNodeType::Identifier, token-getText()); } else if (token-getType() TokenType::LeftParen) { // ( tokens-read(); node additive(tokens); if (node ! NULL) { token tokens-peek(); if (token ! NULL token-getType() TokenType::RightParen) { // ) tokens-read(); } else { throw expecting right parenthesis; } } else { throw expecting an additive expression inside parenthesis; } } } return node; // 这个方法也做了AST简化就是不用构造一个primary节点直接返回子节点。因为它只有一个节点 }最后得到的ASTadd add pri 2 pri 3

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询