antlr v4 使用指南连载1——简介
antlr v4简介
antlr是一个强大语言解析工具,可以用于处理结构化文本、二进制文件。说白了,其实可以这么认为,antlr是一个更强大的正则表达式工具。它可以完成更多正则表达式无法完成的工作。正则表达式更适合于做一些文本匹配、拆分、替换的工作,也就是说,正则表达式关注的是文本大区块。相对于antlr这类语言解析工具来说,正则表达式是一个粗粒度的工具,antlr则侧重于细粒度。antlr可以具体到每一个语法、词法。熟知Java api的猿粪们都知道,java的正则api会有栈溢出的bug,这也正是正则表达式难以处理复杂文本结构的一个例证。
通常情况下,在平常的编程过程中,正则表达式可以解决绝大部分的问题。我曾经在职业生涯的第一年,就接触过只使用正则表达式来完成文本解析入库的一套数据采集框架。而要解析的文本是从通信设备中采集回来的数据。当然这些数据是很规则的,行、列都遵照既定的数据格式。
那么antlr可以做什么呢?可以举这么一个例子,如何将java源码转换成字节码呢?对于这样的需求,antlr就可以派上用场了。实现这个需求,需要按照java规范,将源码中的每个词法(如public、class、package)、类名、包名等转换成对应的字节码。那么如何取得这些词、类名、包名、变量名呢? 正则表达式在这里可能就显得力不从心了。因为除了要寻找这些词法外,还需要处理复杂的上下文关系(如变量的作用范围)。这些正是antlr擅长的地方。
当然,antlr也不是唯一的,它的鼻祖级工具是lex、yacc。Java语言则是JavaCC。有兴趣的朋友,可以搜索一下这方面的资料。
antlr的作者自称有二十几年的语言解析方面的研究经验,做出来的这个东西也确实很强大,很好用。而且提供的开发工具也相当给力,主流IDE都有对应的插件可用。另外,antlr的学习曲线也相对较低,如果有正则表达式的基础,学习起antlr来可以事半功倍。没有也不要紧,学会了antlr,等于正则表达式也学会了一半。
好了,先瞅一眼antlr的庐山真面目吧。antlr由两个东西组成,一个叫词法,一个叫语法,语法是由一个个词法堆积而成的。在antlr中,英文的说法是Lexer、Parser,分别对应词法、语法。通俗地说,词法就是:
- 标识符,即各类编程语言中所说的以下划线、字母开头的字符串
- 字面量,英文叫Literal,其实就是可以当作值的东西,放在操作符两边。如数字、单引号字符串、双引号字符串、各个进制写法等
- 字符,单字符(!、~、=、>等)、双字符(>=、<=)等
- 关键字,如Java中的class、package、import、public等
语法就很容易理解了,比如变量定义、类定义,这些都是语法。所以antlr就是由这两个东西组成的,分别放在两个文件里,一个叫xxxLexer.g4,一个叫xxxParser.g4。当然名字是否包含Lexer、Parser不是强制的,看各人喜好。不过两个文件内容的第一行可以看出来是lexer还是parser。此外antlr也提供一个combine模式,即把lexer、parser写在同一个文件里。为求简便,下面的例子先用这个方法写一个例子吧。
grammar Hello; //Definea grammar called Hello
r :'hello' ID; //match key word hello followed by an identifier
ID : [a-z]+; //match lower-case identifiers
WS : [\t\r\n ]+->skip; //skip spaces,tabs,newlines,\r(Windows)
这是一个完整的antlr例子。
- 第一行是语法文件名Hello,保存之后文件要按这个名字取,即Hello.g4
- 第二行以小写字母开头,是一个语法规则。hello后面跟着一个ID标识符。ID标识符的定义在第三行定义
- 第三行以大写字母开头,是一个词法规则。ID由a-z这26个英文小写字母的一个或多个组成
- 第四行以大写字母开头,是一个词法规则。WS由制表符、换行符的一个或多个组成。->skip是action,表示当处理这个词法规则时采取的处理方法。skip表示跳过,不处理制表符、换行符,直接处理下一个词法规则。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App