文章目录
Antlr笔记
由于工作内容涉及较广,对 编译技术
的需求从来都是有增无减.
一直在尝试完成更复杂的编译器.但技术上没有达到满足实战需求地步.
直到我碰到它:
https://www.zhihu.com/question/315313590/answer/626705164
这个作者也是一个编译小白,通过一系列的操作和社区互动达到了他希望的目的.
路径图真是一个宝藏图,对我来说.
所以推荐使用Antlr而不是yacc之类的东西,如果你决定要搞Antlr,
推荐<Antlr4权威指南>
接下来看看我希望Antlr帮助我完成的需求,N年的想法啊:)
需求
为执行的过的地址绘图
我想到了通过遍历汇编执行的CPU地址,来分析出其结构,并生成调用图?
似乎Antlr能协助我们完成这个梦想.
疑难:如何优化这种代码?中间变量
int a,b,c
b = getData()
a = b
c = a
return c
某一个变量只使用了一次,且它只作为一个中间变量来表示.
对变量引用进行计数.对于赋值的
去除中间变量的过程:
- 定义什么是 简单赋值
- 假想步骤
对于所有的变量:如果它被简单赋值
语句,在相邻居的语句中: 一次在左,一次在右, 则将右边的其他结构和第二次左边的结构进行合并.
将 其右边getData()
和第二次左边的b
进行合并:
a = getData()
b = a
-----
b = getData()
技能
优先级是怎么体现出来的?
你是否写过四则运算
的语法
呢?对于我这个小白还是真不容易呀.
我认真学习过轮子哥 的文章:
http://www.cppblog.com/vczh/archive/2008/06/15/53373.html
那么关键是什么呢? <Antlr4权威入门> 一书在开头就接受了如何用Antlr实现正则,以下记录了我的思考:
- 语法规则顺序
规则中 越靠前的被分析的 优先级 越低
因为它们周围是一些可以继续被分解的内容,如 计算器中的+-
规则周围有multi
,这样 规则越靠前 优先级就能实现越低:
eg:
括号或数字->乘除->加减
加减
的优先级低,所以在语法中第一条规则就出现了:
expr: multi (+|- multi)*
乘除比加减高
,所以在第二条规则出现:
multi: atom (*|/ atom)*
- 最高的原子级别的内容,括号 和 数字:
atom: '('expr')'|Number
其他
测试参数
-tokens
展示tokens流-tree
LISP风格的语法分析树-gui
展示语法图形分析界面,如下图:
错误提示
运行测试错误
第一步生成成功后运行测试指令:
java org.antlr.v4.gui.TestRig Calc FirstRule -tokens
报以下错误:
Can't load Calc as lexer or parser
解决方案:
原因是还没有编译成Java的class程序,只需要一步:
javac -g *.java
终结符要大写(词法分析)
终结符规则要大写开头,否则会提示:
eg:
number: [0-9]+
提示:
syntax error: '0-9' came as a complete surprise to me while matching alternative
解决方案:
number->Number
测试时No method for rule xxx or it has arguments
原因是测试命令错误:
测试命令规则:
org.antlr.v4.gui.TestRig 语法名字 规则名字 其他参数
具体测试以下语法规则为例:
org.antlr.v4.gui.TestRig Calc expr -tokens
grammar Calc;
expr: multi(('+'|'-') multi)*;
multi: atom(('*'|'/') atom)*;
atom: '('expr')'
| Number;
Number: [0-9]+;
WD : [ \t\r\n]+ -> skip ;//skip these
参考资料
使用 Antlr 开发领域语言
https://www.ibm.com/developerworks/cn/java/j-lo-antlr/index.html
如何用 ANTLR 4 实现自己的脚本语言?
http://blog.oneapm.com/apm-tech/589.html