编译原理之美
宫文学
北京物演科技CEO
立即订阅
8171 人已学习
课程目录
已完结 43 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 为什么你要学习编译原理?
免费
实现一门脚本语言 · 原理篇 (13讲)
01 | 理解代码:编译器的前端技术
02 | 正则文法和有限自动机:纯手工打造词法分析器
03 | 语法分析(一):纯手工打造公式计算器
04 | 语法分析(二):解决二元表达式中的难点
05 | 语法分析(三):实现一门简单的脚本语言
06 | 编译器前端工具(一):用Antlr生成词法、语法分析器
07 | 编译器前端工具(二):用Antlr重构脚本语言
08 | 作用域和生存期:实现块作用域和函数
09 | 面向对象:实现数据和方法的封装
10 | 闭包: 理解了原理,它就不反直觉了
11 | 语义分析(上):如何建立一个完善的类型系统?
12 | 语义分析(下):如何做上下文相关情况的处理?
13 | 继承和多态:面向对象运行期的动态特性
实现一门脚本语言 · 应用篇 (2讲)
14 | 前端技术应用(一):如何透明地支持数据库分库分表?
15 | 前端技术应用(二):如何设计一个报表工具?
实现一门脚本语言 · 算法篇 (3讲)
16 | NFA和DFA:如何自己实现一个正则表达式工具?
17 | First和Follow集合:用LL算法推演一个实例
18 | 移进和规约:用LR算法推演一个实例
实现一门脚本语言 · 热点答疑与用户故事 (2讲)
19 | 案例总结与热点问题答疑:对于左递归的语法,为什么我的推导不是左递归的?
用户故事 | 因为热爱,所以坚持
编译原理 · 期中考试周 (1讲)
期中考试 | 来赴一场100分的约定吧!
免费
实现一门编译型语言 · 原理篇 (12讲)
20 | 高效运行:编译器的后端技术
21 | 运行时机制:突破现象看本质,透过语法看运行时
22 | 生成汇编代码(一):汇编语言其实不难学
加餐 | 汇编代码编程与栈帧管理
23 | 生成汇编代码(二):把脚本编译成可执行文件
24 | 中间代码:兼容不同的语言和硬件
25 | 后端技术的重用:LLVM不仅仅让你高效
26 | 生成IR:实现静态编译的语言
27 | 代码优化:为什么你的代码比他的更高效?
28 | 数据流分析:你写的程序,它更懂
29 | 目标代码的生成和优化(一):如何适应各种硬件架构?
30 | 目标代码的生成和优化(二):如何适应各种硬件架构?
实现一门编译型语言 · 应用篇 (2讲)
31 | 内存计算:对海量数据做计算,到底可以有多快?
32 | 字节码生成:为什么Spring技术很强大?
实现一门编译型语言 · 扩展篇 (3讲)
33 | 垃圾收集:能否不停下整个世界?
34 | 运行时优化:即时编译的原理和作用
35 | 案例总结与热点问题答疑:后端部分真的比前端部分难吗?
面向未来的编程语言 (3讲)
36 | 当前技术的发展趋势以及其对编译技术的影响
37 | 云编程:云计算会如何改变编程模式?
38 | 元编程:一边写程序,一边写语言
结束语 (1讲)
结束语 | 用程序语言,推动这个世界的演化
编译原理之美
登录|注册

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

宫文学 2019-08-26
前面的课程中,我重点讲解了词法分析和语法分析,在例子中提到的词法和语法规则也是高度简化的。虽然这些内容便于理解原理,也能实现一个简单的原型,在实际应用中却远远不够。实际应用中,一个完善的编译程序还要在词法方面以及语法方面实现很多工作,我这里特意画了一张图,你可以直观地看一下。
如果让编译程序实现上面这么多工作,完全手写效率会有点儿低,那么我们有什么方法可以提升效率呢?答案是借助工具。
编译器前端工具有很多,比如 Lex(以及 GNU 的版本 Flex)、Yacc(以及 GNU 的版本 Bison)、JavaCC 等等。你可能会问了:“那为什么我们这节课只讲 Antlr,不选别的工具呢?”主要有两个原因。
第一个原因是 Antlr 能支持更广泛的目标语言,包括 Java、C#、JavaScript、Python、Go、C++、Swift。无论你用上面哪种语言,都可以用它生成词法和语法分析的功能。而我们就使用它生成了 Java 语言和 C++ 语言两个版本的代码。
第二个原因是 Antlr 的语法更加简单。它能把类似左递归的一些常见难点在工具中解决,对提升工作效率有很大的帮助。这一点,你会在后面的课程中直观地感受到。
而我们今天的目标就是了解 Antlr,然后能够使用 Antlr 生成词法分析器与语法分析器。在这个过程中,我还会带你借鉴成熟的词法和语法规则,让你快速成长。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《编译原理之美》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(28)

  • 京京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
    1
    4
  • 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
    2
  • 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
    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
    1
    1
  • 沉淀的梦想
    老师,为什么我用antlr生成的AdditiveExpressionContext就没有示例程序中的ADD() SUB()这些直接以token名字命名的方法呢?

    作者回复: 再检查一下规则文件。
    你看看你的词法规则里是否给加号和减号起了ADD和SUB这样的名字,就像下面这样。
    ADD : '+';
    SUB : '-';
    只要有这样的定义,在语法里无论用ADD还是用'+',都会生成ADD()这样的方法。

    2019-08-29
    1
    1
  • 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
    1
  • 火火
    Hello.java:2: 错误: 程序包org.antlr.v4.runtime不存在
    import org.antlr.v4.runtime.Lexer;
                               ^
    Hello.java:3: 错误: 程序包org.antlr.v4.runtime不存在
    import org.antlr.v4.runtime.CharStream;
                               ^
    Hello.java:4: 错误: 程序包org.antlr.v4.runtime不存在
    import org.antlr.v4.runtime.Token;
                               ^
    Hello.java:5: 错误: 程序包org.antlr.v4.runtime不存在
    import org.antlr.v4.runtime.TokenStream;
                               ^
    Hello.java:8: 错误: 程序包org.antlr.v4.runtime.dfa不存在
    import org.antlr.v4.runtime.dfa.DFA;
                                   ^
    Hello.java:12: 错误: 找不到符号
    2019-11-28
  • 小乙哥
    mac下面按照antlr的命令:: brew install Antlr
    按照完成Antlr之后,需要配置一下CLASSPATH,不然使用antlr命令的时候会提示找不到antlr相关类

    export ANTLR_HOME=/usr/local/Cellar/antlr/4.7.2
    export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/jre/lib:$ANTLR_HOME/antlr-4.7.2-com plete.jar

    作者回复: 感谢经验分享!
    还有一个同学建议用maven管理项目,pom里面加上对antlr的依赖就行了,这样开发环境的维护会比较简单。
    但是要用命令行工具的话,还是要像你一样做一下环境变量的配置。

    2019-11-10
  • Sudouble
    按着顺序操作下来,词法分析这块的理解清晰很多。中文编程,在词法分析下,和英文编程几乎等价。感谢留言中筒靴的配置指南。

    一个小Tip:windows下配置好环境变量,记得注销或重启,让环境变量生效。

    作者回复: 也感谢你留的小Tip!

    2019-10-18
  • 庆霖
    哎呀,稀碎一个ANTLR4配了两天超低效率一顿踩坑最后终于在这个教程找到了坑在哪https://blog.csdn.net/shine_journey/article/details/17952163,那两个bat要放到C盘的system和system32才会生效(* ̄m ̄),我一直以为是我环境变量设置的有问题我寻思着复制粘贴都有问题可咋整。另,宫老师我解决了vscode输出提示的COLON,目测是其中有些字符中文输入法输入了,找其他一样的地方复制粘一下就好了😁

    作者回复: 太好了,其他同学可以参考你这篇文章!
    分号的问题,原来是输入法导致的....也好,又增长了一个经验!

    2019-10-12
    1
  • 庆霖
    vscode的插件输出是这样的
    error(50): f:\antlr4test\Hello.g4:36:26: syntax error: missing COLON at '[ \t]' while matching a lexer rule
    老师请问我是在哪里缺了符号
    2019-10-11
  • 庆霖
    宫老师,我在写hello.g4的时候空白字符抛弃里[ \t]这里vscode的输出说这里缺少COLON这是为什么呢,求解答

    作者回复: Antlr语法规则,每行后面都要有分号。是不是有哪句忘了写分号呢?

    2019-10-10
  • 阿尔伯特
    This is really COOL!

    作者回复: 看来你真的比较喜欢编译技术:-)

    2019-09-30
  • wj
    请教老师, Abstract Tree Matching 有已经实现的算法可以用吗? 网上我只找到相关的论文, 我在想比较两个 java 文件的结构, 可能比较 AST 树会更直接一些?

    作者回复: 据我所知,Tree Pattern Matching这类问题,从上世纪80年代就有研究,所以有很多这样的算撒。我们后端的指令选择问题,本质上也是树匹配。

    有人用树的匹配去分析源代码。这样的话,源代码会变成结构化的信息,因此能带来额外的优势。

    我相信,把源代码先变成结构化的数据(AST),然后再分析,也会用于人工智能编程领域。

    2019-09-19
  • 曾经瘦过
    今晚回去后跟着操练操练,感觉很酷

    作者回复: 多动手才会有感觉!

    2019-09-18
  • 长方体混凝土移动工程师
    Letter LetterOrDigit* 这个中间加个空格 是什么意思?

    作者回复: 意思是:第一个字符必须是字母,之后的字符可以是字母或数字。

    2019-09-09
  • 夜行观星
    学到很多,期待后续的课程

    作者回复: 一起努力!

    2019-08-29
  • moob
    nice

    作者回复: :-D

    2019-08-29
  • 沉淀的梦想
    https://github.com/DQinYuan/antlr_maven_plugin_example 将老师本课中的代码整理成了基于maven的antlr4-maven-plugin的形式,需要的可以自取

    作者回复: 谢谢帮忙!

    2019-08-29
  • Change
    Mac系统版本10.15 Beta。Antlr 好像不支持。提示:
    You are using macOS 10.15.
    We do not provide support for this pre-release version.
    You will encounter build failures with some formulae.
    Please create pull requests instead of asking for help on Homebrew's GitHub,
    Discourse, Twitter or IRC. You are responsible for resolving any issues you
    experience while you are running this pre-release version.
    运行 javac *.java ,提示 程序包org.antlr.v4.runtime不存在

    作者回复: 可能是homebrew的问题。
    可以从Antlr官网上下载并做配置,不用homebrew。

    2019-08-28
收起评论
28
返回
顶部