//我的初心是想用纯jdk的代码尽可能的实现文本编辑器,所以逻辑上不想用lex等外部工具。就写一个Editor.java类文件,看能实现多少功能点。
因为目的是写编辑器,所以词法的划分与编译器目的有点儿区别,我习惯划分为
- 标识符
- 数字
- 空白字符
- 符号(我没采纳运算符和界符的二级细分,感觉它会把语言限制在特定的java之流,这样不好)
- 运算符
- 单目
- 双目
- 三目
- 界符
- 其它
public
像注释即不会丢弃,但也不在词法分析环节解析。
- 单行//
- 多行//
- javadoc /***/
所我周末写了3版的草稿,但都不满意。
- 草稿一用了状态机来写,但是没有把预测分析的变量管理好,于是offset变量到处飞;
- 草稿二直接用过程写,但仍然用 StringReader 类来读取,用变量来存预测字符,结果仍然把代码搞得很脏。
- 第三版也就是最终方案,用 PushbackReader 类来管理提前预测字符和撤回字符到流的逻辑,于是干净了,最后没有回到状态的类,而是用状态过程来写。
核心方法readNextToken()
private
这样就把代码写得很优雅,其中预测字符的方法
private
预测不对,返回到前状态的方法
private
每个if-else里的for()其实就类似正则的[_|a-z|A-Z]*,所以我没有用lex,但绕不开lex的方法,原理还是正则逻辑。不过日志能跑通,界面上的词法单元着色也OK,计划在很后面的章节会美化界面。目前先不管。
0
解析日志是正确的,但着色显示有错位问题。
原因: CRLF 的系统判断没有处理,它分为 Window/Unix/MacOS三种(r n rn),但这个跟词法分析关系不大,我把它归到新需求,另一章节再分析和吃掉。方案就是参考其它编辑器或IDE的偏好设置
现在的情况是每写一个小功能,就产生10倍的BUG,不过开始都是这样的,先抓主干,不要被分支问题影响,否则无法推进主干前进。我也想过单元测试等稳定推进方案,但觉得单元测试会让精力分散到主干之外,我试图把方法写得短小,尽量少的定义成员变量。至于边界的情况也不需要测试,我知道哪些BUG存在,以及原因,只是暂不case它们。
另外周六把dot语法温习一轮,结果反而没有在本篇派上用场。所以写了笔记,以后肯定要画各种图的,仅凭文字,还是有歧义。
digraph
下一篇就把语法解析写完,GUI会用树型控件显示,但肯定是丑萌丑萌的树。