• 重拾《 两周自制脚本语言 》- 支持中文标识符


    前文将《 两周自制脚本语言 》测试中使用的接口中文化. 在将此脚本语言改为中文关键字之前, 需要先让它支持中文标识符.

    首先添加一个词法分析器测试:

      @Test
      public void test读中文() throws 分析例外 {
        词法分析器类 词法分析器 = 词法分析功用.新建词法分析器("中文变量1名 = 中文ok值");
        词类 词1 = 词法分析器.读();
        词类 词2 = 词法分析器.读();
        词类 词3 = 词法分析器.读();
    
        词法分析功用.词为标识符("中文变量1名", 词1);
        词法分析功用.词为标识符("=", 词2);
        词法分析功用.词为标识符("中文ok值", 词3);
      }
    

    预期的应该不能通过测试, 结果的确不成功, 但是"卡"住了而非报错. 调试后看到问题出在这段:

            int lineNo = reader.getLineNumber();
            Matcher matcher = pattern.matcher(line);
            matcher.useTransparentBounds(true).useAnchoringBounds(false);
            int pos = 0;
            int endPos = line.length();
            while (pos < endPos) {
                matcher.region(pos, endPos);
                if (matcher.lookingAt()) {
                    addToken(lineNo, matcher);
                    pos = matcher.end();
                }
                else
                    throw new 分析例外("bad token at line " + lineNo);
            }
    

    改为中文命名以更易于理解:

            int 行数 = reader.getLineNumber();
            Matcher 匹配器 = 模式.matcher(行);
            匹配器.useTransparentBounds(true).useAnchoringBounds(false);
            int 头 = 0;
            int 尾 = 行.length();
            while (头 < 尾) {
                匹配器.region(头, 尾);
                if (匹配器.lookingAt()) {
                    添加词(行数, 匹配器);
                    头 = 匹配器.end();
                }
                else
                    throw new 分析例外("bad token at line " + 行数);
            }
    

    看到进入死循环的直接原因是匹配器.lookingAt()虽然为true, 但始终为0. 更深原因可自行研究原正则表达式.

    为了添加中文标识符支持, 需要使正则表达式能够匹配中文字符, 参考Detecting if NSString contains chinese characters

    将原模式中的[A-Z_a-z][A-Z_a-z0-9]*改为[\p{script=Han}A-Z_a-z][\p{script=Han}A-Z_a-z0-9]*. 之后开头的词法分析器测试通过.

    为检验更复杂一些的源码, 对第九章的原本测试用源码使用中文命名:

    class 位置类 {
        经 = 纬 = 0
        def 到达 (经度, 纬度) {
            经 = 经度; 纬 = 纬度;
        }
    }
    位置 = 位置类.new
    位置.到达(3, 4)
    位置.经 = 10
    和 = 位置.经 + 位置.纬
    

    测试通过~ 源码提交在

  • 相关阅读:
    Apache的443端口被占用解决方法
    关于变量初始化问题
    浏览无法加载控件
    关于网络数据传输
    java 对象是在什么时候创建的?
    HTML HTTP
    2020 年计划
    Docker 学习
    [腾讯 TMQ] 接口测试用例设计
    pytest + request
  • 原文地址:https://www.cnblogs.com/program-in-chinese/p/10545285.html
Copyright © 2020-2023  润新知