词法识别java_正则


//我的初心是想用纯jdk的代码尽可能的实现文本编辑器,所以逻辑上不想用lex等外部工具。就写一个Editor.java类文件,看能实现多少功能点。

因为目的是写编辑器,所以词法的划分与编译器目的有点儿区别,我习惯划分为

  1. 标识符
  2. 数字
  3. 空白字符
  4. 符号(我没采纳运算符和界符的二级细分,感觉它会把语言限制在特定的java之流,这样不好)
  1. 运算符
  1. 单目
  2. 双目
  3. 三目
  1. 界符
  1. 其它
public


像注释即不会丢弃,但也不在词法分析环节解析。

  1. 单行//
  2. 多行//
  3. javadoc /***/

所我周末写了3版的草稿,但都不满意。

  • 草稿一用了状态机来写,但是没有把预测分析的变量管理好,于是offset变量到处飞;
  • 草稿二直接用过程写,但仍然用 StringReader 类来读取,用变量来存预测字符,结果仍然把代码搞得很脏。
  • 第三版也就是最终方案,用 PushbackReader 类来管理提前预测字符和撤回字符到流的逻辑,于是干净了,最后没有回到状态的类,而是用状态过程来写。


词法识别java_运算符_02


核心方法readNextToken()


private


这样就把代码写得很优雅,其中预测字符的方法


private


预测不对,返回到前状态的方法


private


每个if-else里的for()其实就类似正则的[_|a-z|A-Z]*,所以我没有用lex,但绕不开lex的方法,原理还是正则逻辑。不过日志能跑通,界面上的词法单元着色也OK,计划在很后面的章节会美化界面。目前先不管。


词法识别java_正则_03


0


解析日志是正确的,但着色显示有错位问题。

原因: CRLF 的系统判断没有处理,它分为 Window/Unix/MacOS三种(r n rn),但这个跟词法分析关系不大,我把它归到新需求,另一章节再分析和吃掉。方案就是参考其它编辑器或IDE的偏好设置


词法识别java_词法_04


现在的情况是每写一个小功能,就产生10倍的BUG,不过开始都是这样的,先抓主干,不要被分支问题影响,否则无法推进主干前进。我也想过单元测试等稳定推进方案,但觉得单元测试会让精力分散到主干之外,我试图把方法写得短小,尽量少的定义成员变量。至于边界的情况也不需要测试,我知道哪些BUG存在,以及原因,只是暂不case它们。

另外周六把dot语法温习一轮,结果反而没有在本篇派上用场。所以写了笔记,以后肯定要画各种图的,仅凭文字,还是有歧义。


词法识别java_正则_05


词法识别java_词法识别java_06


digraph


下一篇就把语法解析写完,GUI会用树型控件显示,但肯定是丑萌丑萌的树。