首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

ANTLR语法中的无限递归

无限递归(Infinite Recursion)是ANTLR(抽象语法树)语法中的一种错误,指的是一个文法在解析过程中反复调用自身,导致无限循环。ANTLR是一种用于构建语法分析器的高级语言,它提供了一种编程接口来定义文法及其相应的解析器。

无限递归的主要原因是解析器在解析过程中没有正确地处理递归调用,导致程序无法正常终止。在ANTLR语法中,无限递归通常是由于文法中的递归定义或者递归调用引起的。

为了解决无限递归的问题,可以采用以下几种方法:

  1. 消除递归:将文法中的递归定义或递归调用转换为迭代形式。这可以通过使用栈或者队列等数据结构来实现。
  2. 使用标记:在文法中添加标记,指示解析器何时停止递归。这可以通过使用ANTLR的@lexer::start@lexer::end标记来实现。
  3. 限制递归深度:在解析器中设置递归深度限制,当递归深度达到预设值时,解析器将停止递归。这可以通过使用栈或者队列等数据结构来实现。

以下是一个消除递归的ANTLR语法示例:

代码语言:txt
复制
grammar Exp;

expression
    :   term ( ( '+' | '-' ) term )*
    ;

term
    :   factor ( ( '*' | '/' ) factor )*
    ;

factor
    :   Number
    |   '(' expression ')'
    |   ( Number | '(' expression ')' ) '+'
    |   ( Number | '(' expression ')' ) '-'
    |   ( Number | '(' expression ')' ) '*'
    |   ( Number | '(' expression ')' ) '/'
    ;

Number
    :   ( '+' | '-' ) ( Digit | '.' )+
    ;

Digit
    :   [0-9]
    ;

Space
    :   [ \t\n\r] +
    ;

在这个示例中,我们使用了@lexer::start@lexer::end标记来指示解析器何时停止递归。我们还使用了( Digit | '.' )+来定义一个数字序列。

通过使用这些标记,我们可以消除递归,从而避免出现无限递归的错误。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

使用antlr4构造我语法

一、编译原理 编译器前端和后端。前端指的是编译器对程序代码分析和理解。前端阶段只与语言语法有关,而和目标机器无关。后端则是生成目标机器目标代码有关。第一节说说编译器前端技术。...词法分析是识别一个个token,而语法分析是识别出程序语法树状结构。...image.png image.png 1.3、语义分析 语义分析目的是消除语义模棱两可“二义性”。比如一个变量同时定义在花括号外部和内部,那么到底该用哪一个。...监听者模式有点类似于XML解析语法,在这颗AST语法树(类似于DOM树),当解析到node,则调用listenerhook函数接口。...也可以自定义自己语法规则,拿来自动化生成代码。

8.7K332

无限递归引发堆栈溢出

今天在写strlen函数递归实现,当执行以下代码时,会出现段错误。...分析 return 1 + my_strlen(p++),当程序进行递归调用时候。由于传参为p++即传入p,相当于递归本身,并非移到指向当前字符串下一个字符位置。...递归函数会陷入无限递归状态,因为没有递归结束条件。当操作系统为进程分配虚拟地址空间当中栈空间被耗尽时,此时会发生堆栈溢出。因而产生段错误。...在linux操作系统下查看栈空间大小: ulimit -a可以查看所有默认空间大小。...查看栈空间默认大小 : 命令 ulimit -s 可以看到,在我操作系统下栈空间默认大小为10MB。 递归开销实际上是比较大,在使用时谨防堆栈溢出。注意递归调用结束条件。

65110

不用递归生成无限层级

偶然间,在技术群里聊到生成无限层级树老话题,故此记录下,n年前一次生成无限层级树解决方案 业务场景 处理国家行政区域树,省市区,最小颗粒到医院,后端回包平铺数据大小1M多,前端处理数据后再渲染...,卡顿明显 后端返回数据结构 [ { "id": 1, "name": "中华人民共和国", "parentId": 0, }, {...{ "id": 4001, "name": "杭州市第一人民医院", "parentId": 3001, }, // 其他略 ] 第一版:递归处理树...常规处理方式 // 略,网上一抓一把 第二版:非递归处理树 改进版处理方式 const buildTree = (itemArray, { id = 'id', parentId = 'parentId...topLevelId)) { topLevelResult.push(item) } } return topLevelResult; } 时间复杂度:O(n) x下篇分享不用递归无限层级树取交集

98520

PHP利用递归函数实现无限级分类方法

相信很多学php很多小伙伴都会尝试做一个网上商城作为提升自己技术一种途径。各种对商品分类,商品名之类操作应该是得心应手,那么就可以尝试下无限级分类列表制作了。 什么是无限级分类?...无限级分类是一种分类技巧,例如部门组织,文章分类,学科分类等常用到无限级分类,将其简单理解成分类就好了。...其实我们仔细想一下,生活分类简直太多了,衣服可以分为男装和女装,也可以分为上衣和裤子,也可以根据年龄段分类。分类无处不在,分类显得“无限”。我这里就不说无限分类必要性了。...无限级分类原理简介 无限分类看似”高大上”,实际上原理是非常简单无限分类不仅仅需要代码巧妙性,也要依托数据库设计合理性。要满足无限级分类,数据库需要有两个必须字段,id,pid。...php无限级分类是经常要用到,本人以前一直用是已经写好,所以没仔细去研究过,下面是一个使用递归实现简单php无限级分类函数;也许这不是最优方法,但对于一般应用也足够了。

97321

Milvus 向量数据库如何实现属性过滤

查询表达式文法规则 Milvus 支持查询表达式 底层操作服务及具体表达式 查询语法生成 开源工具 ANTLR 介绍 PlanAST generation 语法解释和执行 PlanAST &...也就是说,Milvus 支持表达式规则是可以无限递归嵌套。如果有很多属性需要过滤,就可以通过不同组合和嵌套,进而表示出需要过滤条件。 底层操作服务及具体表达式 上图是前文提到几种表达式。...查询语法生成 开源工具 ANTLR 介绍 ANTLR 可以理解为解析器或者生成器,它能够对结构化文本或者二进制文件做读处理,包括执行和翻译过程。...从右边列出 Parse-Tree 遍历 API 可以看出,ANTLR 从 根节点一直到最末端子节点,是按照一种深度遍历顺序来进行遍历,由此也不需要人为区分多叉树前序、序、后序,直接看API...在二叉树遍历过程,每个节点对应到定义 protobuf 语法结构,进而生成一个 protobuf 结构一个 plan AST (abstract syntax tree)。

1.4K30

JSTS 递归

什么是递归?根据维基百科定义,递归是这样描述:"递归通常用于描述以类似于已显示方式重复对象过程。例如,当两面镜子相互对着时,产生图像就是一个很好例子。"...在 JavaScript/TypeScript 呢?...在 JavaScript/TypeScript 递归是指函数或类型在满足特定条件之前重复调用自身,这可以出现在函数,即递归函数调用,也可以出现在类型。...示例假设我们有一个包含文件(File)和文件夹(Folder)数组,并且我们需要在控制台中显示每个文件(或文件夹)名称:首先,我们需要创建一个适用于我们递归函数类型:type Item = {...: Item[]}正如您所见,我们使用了递归,因为我们将 children 类型设置为 Item[],这意味着创建了一种递归、嵌套结构。

17310

java递归算法_java递归算法详解

大家好,又见面了,我是你们朋友全栈君。 Java递归算法虽然简单,但想要精通也是有着一定难度,本篇文章我们就来详细了解下递归算法。 什么是递归?...一般说, 递归算法是一种直接或间接地调用自身算法。在程序递归算法能够使算法描述简洁而且易于理解。 递归分几类? 递归通常分为两类,直接递归和间接递归: 1、直接递归称为方法自身调用自己。...2、间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。 递归怎么实现实现?...例://递归实现九九乘法表 public class diguidemo { public static void main(String[] args) { digui(9); } private...static int getSum(int num) { if (num == 1) { return 1; } return num + getSum(num – 1); } } 以上就是本篇文章所有内容

1.5K20

Python递归

递归递归原理:当编译器检测到一个函数调用是尾递归时候,它就覆盖当前活动记录而不是在栈中去创建一个新。...编译器可以做到这点,因为递归调用是当前活跃期内最后一条待执行语句,于是当这个调用返回时栈帧并没有其他事情可做,因此也就没有保存栈帧必要了。...这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出情况。..._getframe().f_back # 调用者帧 ---- tail_call_optimized实现尾递归优化原理: 当递归函数被该装饰器修饰后, 递归调用在装饰器while循环内部进行, 每当产生新递归调用栈帧时...所以递归过程始终只存在一个栈帧对象, 达到优化目的。

1.2K30

SQL递归查询

递归查询原理 SQL Server递归查询是通过CTE(表表达式)来实现。...至少包含两个查询,第一个查询为定点成员,定点成员只是一个返回有效表查询,用于递归基础或定位点;第二个查询被称为递归成员,使该查询称为递归成员是对CTE名称递归引用是触发。...在逻辑上可以将CTE名称内部应用理解为前一个查询结果集。 递归查询终止条件 递归查询没有显式递归终止条件,只有当第二个递归查询返回空结果集或是超出了递归次数最大限制时才停止递归。...在查询语句中调用CTE,而查询语句就是CTE组成部分,即 “自己调用自己”,这就是递归真谛所在。...具体结果如下: 以上就是递归查询一些知识介绍了,自己可以动手实验一下,这个一般在面试也经常会考察面试者,希望能帮助到大家~

9910

递归递归求n个数最大值

作者:每天都要记得刷题(●’◡’●) 时间:2022/04/04 本篇感悟:举一反三,由求 n阶乘联想到递归求n个数最大值,对递归有了更深了解。...文章目录 ⭐题目(代码在文末) ⭐递归思想 ⭐求前n个斐波那契数 ⭐具体代码(答案) ⭐题目(代码在文末) 使用递归求 55 ,22, 155, 77, 99这5个数最大值 ⭐递归思想 Q...:最后一次递归,此时函数值是可以直接算出,不需要递归求得,递归出口往往是边界时候 不断递归:每递归一次,下一次需要递归就会逐渐靠近这个递归出口 同时递归开始时候我们要把要递归的当成我们已知...1个数最大值进行比较(假设我们已知)** 3.然后就是求n-1个数最大值,也就是重复了以上步骤 4.知道我们到了递归出口,再归回去就可以了。...a[n - 1] : find_max(a, n - 1); } int main() { //递归求n个数最大值 int a[5] = { 55,22,155,77,99 }; int

1.2K20

java递归算法_java递归算法是什么怎么算

递归算法实质是把问题分解成规模缩小同类问题子问题,然后递归调用方法表示问题解。...递归往往能给我们带来非常简洁非常直观代码形式,从而使我们编码大大简化,然而递归思维确实跟我们常规思维相逆,通常都是从上而下思维问题,而递归趋势从下往上进行思维。...二、递归算法解决问题特点: 【1】递归就是方法里调用自身。 【2】在使用递归策略时,必须有一个明确递归结束条件,称为递归出口。 【3】递归算法代码显得很简洁,但递归算法解题运行效率较低。...所以不提倡用递归设计程序。 【4】在递归调用过程系统为每一层返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等,所以一般不提倡用递归算法设计程序。...factorial=new Factorial(); System.out.println(“factorial(5)=”+factorial.fact(5)); } } 代码执行流程图如下: 此程序n

1.3K30

java递归和迭代_Java迭代与递归

信息量随着算法输入呈线性增长递归称之为线性递归。计算n!(阶乘)就是线性递归。由于随着N增大,计算所需时间呈线性增长。另外一种信息量随着输入增长而进行指数增长称之为树形递归。...尤其是遇到一个比较复杂场景时候。但是,代码难以了解带来有点也比较显著。迭代效率比递归要高,并且在空间消耗上也比较小。 递归中肯定有迭代,但是迭代不肯定有递归,大部分可以相互转换。...能用迭代不要用递归递归调用函数不仅白费空间,假如递归太深的话还容易造成堆栈溢出。 数形递归 前面详情过,树递归随输入增长信息量呈指数级增长。...比较典型就是斐波那契数列: 用文字形容就是斐波那契数列前两个数字和等于第三个数字:0,1,1,2,3,5,8,13,21…… 递归实现代码如下: int fib (int n) { if (...== 0) { return 0; } else if (n == 1) { return 1; } else { return fib(n-1) + fib(n-2); } } 计算过程

2K40

周而复始,往复循环,递归、尾递归算法与无限极层级结构探究和使用(Golang1.18)

递归思想与实现     递归思想并非是鲜为人知高级概念,只不过是一种相对普遍逆向思维方式,这一点我们在:人理解迭代,神则体会递归,从电影艺术到Python代码实现神逆向思维模式已经探讨过,说白了就是一个函数直接或者间接调用自己...,就是递归,本文开篇和尚讲故事例子,和尚不停地把他自己和他所在庙和山调用在自己故事,因此形成了一个往复循环递归故事,但这个故事有个致命问题,那就是停不下来,只能不停地讲下去,所以一个正常递归必须得有一个递归边界条件...递归应用场景    在实际工作,我们当然不会使用递归讲故事或者只是为了计算高斯求和,大部分时间,递归算法会出现在迭代未知高度层级结构,即所谓无限极”分类问题: package main import...:使用Python3.7+Django2.0.4配合vue.js2.0组件递归来实现无限级分类(递归层级结构) 有异曲同工之处,但很显然,使用结构体Golang代码可读性更高。    ...结语     递归并非是刻板印象性能差又难懂算法,正相反,它反而可以让代码更加简洁易懂,在程序中使用递归,可以更通俗、更直观描述逻辑。

1.3K60

日常运维|语法分析解析工具之ANTLR4(一)

ANTLR实现数据加载器、语言解释器、语言翻译器。基于自动生成语法分析树解析文件。...简单来说就是,ANTLR根据用户自定义语法文件自动生成词法分析器和语法分析器,并将输入文本处理为语法分析树(可视化)。...ANTLR 是一款强大语法分析器生成工具,可用于读取、处理、执行和翻译结构化文本或二进制文件。...解析C++Hibernate对象-关系映射框架(ORM)处理HQL语言其他文件读取器、遗留代码转换器、维基文本渲染器、JSON解析器、DNA模式匹配、数据读取、语言解释、翻译器1.2、简单描述生成语法分析器自动建立语法分析树自动生成树遍历左递归...语法分析树监听器语法分析树访问器3.1 入门例子编写一个ArrayInit.g4文件// 定义文件,程序语言名称必须同文件名称一致,都为ArrayInitgrammar ArrayInit;// 规则

46720

Antlr4实战:统一SQL路由多引擎

它以树状形式表现编程语言语法结构,树上每个节点都表示源代码一种结构。...Antlr相关语法 ANTLR自动产生为递归下降语法分析器,实际上为若干递归方法集合,每个方法对应一条规则。...位于花括号文本块,识别器根据它们在语法位置,在不同时机触发它。...这些files.tokens是antlr自动生成词法语法分析等等过程中生成临时文件,也不会分布式到最终程序,大小可忽略不计。在生成过程也没必要消除它们。...visitXXX(),保证这些visitXXX()是根据语法分析树能递归下降调用,才能完全遍历访问一颗语法分析树(监听器不需要开发者手写遍历代码,一切是自动遍历)。

8.4K41

Antlr 重构脚本解释器

前言 在上一个版本实现脚本解释器 GScript 实现了基本四则运算以及 AST 生成。...Antlr Antlr 就是做帮我们解决这些问题常用工具,利用它我们只需要编写词法文件,然后就可以自动生成词法、语法解析器,并且可以生成不同语言代码。...而我们要实现具体语法逻辑时只需要实现相关接口,Antlr 会自动遍历 AST(当然也可以手动控制),同时在访问不同 AST 节点时会回调我们自己实现接口,这样我们就能编写自己语法规则了。...还有其他各种优势,比如可以解决: 左递归。...这里也推荐在 IDE 安装 Antlr 插件,这样就可以直观查看 AST 语法树,可以帮我们更好调试代码。

72910

主要执行流程

预备知识 先介绍在Spark SQL两个非常重要数据结构:Tree和Rule。...SparkSql第一件事就是把SQLText解析成语法树,这棵树包含了很多节点对象,节点可以有特定数据类型,同时可以有0个或者多个子节点,节点在SparkSQL表现形式为TreeNode对象。...Spark1版本使用是scala原生parser语法解析器,从2.x后改用是第三方语法解析工具ANTLR4,只需要定制好语法,可以通过插件自动生成对应解析代码。...然后通过AstBuilder配合antlrvisitor模式自主控制遍历Tree,将antlr里面的节点都替换成catalyst(优化器系统)里面的类型,所有的类型都继承了TreeNode特质,TreeNode...每个SparkPlan里面都有execute实现,一般都会递归调用childrenexecute()方法,最后便会触发整个Tree计算。 ---- 最后上个流程图 ?

1.7K10
领券