编译原理之美
宫文学
北京原点代码 CEO
46197 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
编译原理 · 期中考试周 (1讲)
编译原理之美
15
15
1.0x
00:00/00:00
登录|注册

06 | 编译器前端工具(一):用Antlr生成词法、语法分析器

PlayScript.java
ASTEvaluator.java
PlayScript.g4
CommonLexer.g4
Hello.g4
分享经验和问题
后续课程展望
借鉴成熟规则
工具的支持提升工作效率
测试生成的语法分析器
编译语法规则文件
创建语法规则文件PlayScript.g4
用Antlr生成词法分析器
词法规则中对Token归类的问题
完善词法规则
编译词法规则文件
创建词法规则文件Hello.g4
用Java实现
支持根据规则文件生成词法分析器和语法分析器
Antlr是一个开源的工具
示例代码
一课一思
课程小结
用Antlr生成语法分析器
用Antlr生成词法分析器
初识Antlr
善用Antlr生成词法、语法分析器,提高工作效率

该思维导图由 AI 生成,仅供参考

前面的课程中,我重点讲解了词法分析和语法分析,在例子中提到的词法和语法规则也是高度简化的。虽然这些内容便于理解原理,也能实现一个简单的原型,在实际应用中却远远不够。实际应用中,一个完善的编译程序还要在词法方面以及语法方面实现很多工作,我这里特意画了一张图,你可以直观地看一下。
如果让编译程序实现上面这么多工作,完全手写效率会有点儿低,那么我们有什么方法可以提升效率呢?答案是借助工具。
编译器前端工具有很多,比如 Lex(以及 GNU 的版本 Flex)、Yacc(以及 GNU 的版本 Bison)、JavaCC 等等。你可能会问了:“那为什么我们这节课只讲 Antlr,不选别的工具呢?”主要有两个原因。
第一个原因是 Antlr 能支持更广泛的目标语言,包括 Java、C#、JavaScript、Python、Go、C++、Swift。无论你用上面哪种语言,都可以用它生成词法和语法分析的功能。而我们就使用它生成了 Java 语言和 C++ 语言两个版本的代码。
第二个原因是 Antlr 的语法更加简单。它能把类似左递归的一些常见难点在工具中解决,对提升工作效率有很大的帮助。这一点,你会在后面的课程中直观地感受到。
而我们今天的目标就是了解 Antlr,然后能够使用 Antlr 生成词法分析器与语法分析器。在这个过程中,我还会带你借鉴成熟的词法和语法规则,让你快速成长。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Antlr是一个开源工具,用于生成词法分析器和语法分析器,支持多种目标语言。相比其他工具,Antlr的语法更简单,能解决常见难点,提升工作效率。本文介绍了Antlr的初步了解和安装方法,并提供了一些供参考的语法规则。通过使用Antlr,读者可以更轻松地生成词法分析器和语法分析器,提高工作效率。 Antlr通过解析规则文件生成编译器,规则文件以.g4结尾,词法规则和语法规则可以放在同一个文件里。文章示范了如何编写词法规则、编译规则文件,并生成词法分析器。读者还可以学习如何编写更严密的词法规则,参考成熟的规则文件,以及在词法规则中对Token归类的问题。 此外,文章提到了解决词法冲突的方法,即通过声明顺序解决优先级问题。还介绍了有趣的“中文编程语言”概念,鼓励读者尝试支持中文关键字的词法规则。整体而言,本文通过实例和技术讲解,帮助读者快速了解Antlr的基本使用和优化词法规则的方法。 通过本文,读者可以了解如何使用Antlr生成词法分析器和语法分析器,以及如何优化词法规则,提高工作效率。同时,还可以学习如何解决词法冲突以及支持中文关键字的词法规则,为语言设计和编译器实现提供了有益的参考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《编译原理之美》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(60)

  • 最新
  • 精选
  • 京京beaver
    1. windows环境下配置 可执行文件,放在D:\tools\antlr\antlr-4.7.2-complete.jar下面 2.配置环境文件 CLASSPATH=%CLASSPATH%;D:\tools\antlr\antlr-4.7.2-complete.jar PATH=%PATH%n;D:\tools\antlr 3.手写文件antlr4.bat和grun.bat antlr4.bat java org.antlr.v4.Tool %* grun.bat @ECHO OFF SET TEST_CURRENT_DIR=%CLASSPATH:.;=% if "%TEST_CURRENT_DIR%" == "%CLASSPATH%" ( SET CLASSPATH=.;%CLASSPATH% ) @ECHO ON java org.antlr.v4.gui.TestRig %* 4.然后就可以执行antlr4和grun命令了 比如antlr4 Hello.g4, javac Hello*.java, $ grun Hello r -gui hello parrt ^Z (windows) 5.java执行路径要注意事项 在命令行执行java命令,记得把目录设置到src/main/java这里,然后输入包名.类名,才能找到。 这是java执行的基本规则,一般IDE里面替你做了路径转换,在命令行要自己敲入。切记。 例如 F:\study_repo\mygeek_time\myclang-03-grammar-analysis\src\main\java> grun com.babayetu.myclang03gramm aranalysis.antlrtest.PlayScript expression -gui

    作者回复: 非常感谢你的整理! 其他同学可以参考你的配置方法!

    2019-09-10
    4
    21
  • Smallfly
    这一讲走的有点艰难,记录一下: 1、 开始执行下面的命令,报找不到 CommonLexer。 antlr PlayScript.g4 看了下 Github 才发现有这个文件。 import CommonLexer, 在语法规则文件 PlayScript.g4 中导入词法规则。 2、 antlr PlayScript.g4 上面的命令后应该先 cd .. 回退一级目录,再执行: javac antlrtest/*.java 或者,直接: javac ./*java 3、 grun antlrtest.PlayScript expression -gui 文中说执行这条命令结果会以图形化界面显示,我执行之后什么都没有输出,以为前面步骤有什么问题,重新来了一次,还是这样,往下看才意识到没输出才是正常的。。。 —— 看到最后弹出的 AST 树还是蛮有意思的。 我写了一版简单的 Swfit 规则文件: https://github.com/iostalks/PlayWithCompiler/tree/lecture-6/PlayWithCompiler/Antlr

    作者回复: 哇,练习自己写规则,太帮了! 自己动手所获得的感觉是难以替代的。 中间过程遇到的每个坑,都是自己的积累! 另外,这里也有几个swift的规则文件可以参考: https://github.com/antlr/grammars-v4

    2019-09-05
    6
  • kaixiao7
    在Windows下需要用 ^z 即Ctrl+z 来弹出AST窗口 That ^D means EOF on unix; it's ^Z in Windows.

    作者回复: windows下用^Z?我都没注意到这点。 好的,一个有用的知识,应该加到文稿中去。 谢谢你的提醒! 20年前开始学unix命令的时候,就一直用^D,完全没注意到在windows下的用法:-D

    2019-08-26
    4
  • 七月有风
    macOS下,需要将把 Antlr 的 JAR 文件设置到 CLASSPATH 环境变量中: 如果是用Homebrew 安装的 Antlr,安装路径是:/usr/local/Cellar/antlr/4.7.2/antlr-4.7.2-complete.jar; 可以使用vi ~/.bash_profile命令打开bash_profile文件,将export CLASSPATH=".:/usr/local/Cellar/antlr/4.7.2/antlr-4.7.2-complete.jar:$CLASSPATH"这段代码复制到里面。 然后就可以运行javac *.java了

    作者回复: 感谢分享! 我这两天整理了Antlr使用的要点,可以参见这里: https://github.com/RichardGong/PlayWithCompiler/blob/master/antlr_install.md

    2019-12-23
    3
  • PythonAI
    ➜ antlr grun antlrtest.PlayScriptexpression -gui Can't load antlrtest.PlayScriptexpression as lexer or parser

    作者回复: expression前要有空格,前面没有antlr。 grun antlrtest.PlayScript expression -gui 我请编辑把那个空格加上。

    2019-08-26
    3
    3
  • 江世民
    遇到了一个大坑。 Windows环境下,添加jar包到CLASSPATH中时,最好写在前面。如果是追加在后面,系统很可能不识别。

    作者回复: 感谢分享你的经验! 你遇到的坑,会让其他同学少走弯路!

    2020-06-28
    2
  • 七月有风
    不知道是什么问题? $ grun Hello tokens -tokens Hello.play Exception in thread "main" java.lang.NoClassDefFoundError: antlrtest/Hello (wrong name: Hello) at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174) at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802) at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700) at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623) at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) at org.antlr.v4.gui.TestRig.process(TestRig.java:135) at org.antlr.v4.gui.TestRig.main(TestRig.java:119)

    作者回复: 可能是CLASSPATH设置的问题,或者是运行grun命令的目录不对。参见我整理的一篇文字,梳理了antlr使用的要点: https://github.com/RichardGong/PlayWithCompiler/blob/master/antlr_install.md

    2019-12-25
    2
    2
  • mudfrog
    老师,我的程序能编译通过,也能正常运行,能正常的解析和运算出来,但就是想看看语法树直观一些。我使用grun的时候总是提示Can't load CalExpr as lexer or parser,这里CalExpr到底是G4文件还是tokens文件呢,我把这两个文件都拷贝到src目录下了。我用的是win7底下的eclipse,

    作者回复: 1.grun是用的Class文件,是java类。 2.但运行grun的时候,最好就在CLASSPATH的目录下。 假设,class和g4文件位于: playscript-java/src/main/play 其中play是包名,而CLASSPATH设置的是: playscript-java/src/main 那么你就在main这个目录下运行grun。 如果都不带包,就更简单一些,让grun就在带有class和.g4的目录中运行就好。 如果还有问题的话,请继续再问!

    2019-09-01
    2
    2
  • minghu6
    ANTLR的使用一定要有 “The Definitive ANTLR 4 Reference” 推荐电子版 https://github.com/antlr/antlr4/blob/master/doc/index.md 可以做关键字搜索,查点儿语法概念性的东西比较方便,用一位网友说的话: If you do not already have "The Definitive ANTLR 4 Reference" book I recommend getting hold of it. Will save you a lot of time. 话说极客时间的内容还不错,没有那么多花里胡哨的噱头,但是这个书签笔记和评论的体验太差! 书签笔记甚至没有结构,留言也不支持markdown 一定要ommonLexer.g4

    作者回复: 谢谢推荐Antlr4电子书! 以及提出的建议!

    2021-03-18
    1
  • englefly
    宫老师,Antlr的性能怎样?我们用antlr做了一个sql解析,当遇到比较长的sql语句是,antlr解析花了100ms,而mysql 只用了9ms。不知道是我们用法的问题,还是antlr本身为了使用简单牺牲了一些性能。

    作者回复: 我要了解更多一点信息:你用Antlr生成的是C++代码还是Java代码?这两个不太一样。因为JVM只对热点代码做优化编译。如果只是解释执行或者用C1编译器编译,就会比较慢。详细你可以参考《编译原理实战课》中Java JIT编译器的部分。 另外,在实战课中,我也介绍了MySQL的编译器。MySQL的语法分析器也是用工具生成的,用的是Bison,生成的是C++代码。我估计,同样都使用C++代码的情况下,性能可能不会差很多。但具体也要测试一下。 或者,你就像MySQL一样,用Bison生成就好了,并且可以参考MySQL的源代码。 另外补充一下,MySQL Workbench这个客户端工具采用了Antlr来生成语法解析器,也是基于C++的,你也可以参考。

    2020-06-16
    1
收起评论
显示
设置
留言
60
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部