使用SyntaxHighlightRules进行语法验证

时间:2019-01-23 18:01:15

标签: ace-editor

我已经使用复杂的状态机为自定义语言(JMS消息表示形式)构建了一些新的Ace编辑器模式。现在,重用该语法突出显示功能还可以创建错误,这将非常棒。有可能吗?

换句话说,假设我的语法高亮显示了“无效”令牌,并且我想使用该令牌的行号来标记错误,然后执行以下操作:https://github.com/ajaxorg/ace/wiki/Syntax-validation

最简单的格式是十六进制格式:

this.$rules = {
    "start": [
        { regex: /[!#].*$/, token: "comment" },
        { regex: /^0x[0-9a-f]+:/, token: "constant" }, // hex offset
        { regex: /(?:[0-9a-fA-F]{4} |[0-9a-fA-F]{2} )/, token: "constant.numeric" }, // hex value
        { regex: /[\S ]{1,16}$/, token: "string" }, // printable value
        { regex: "\\s+", token: "text" },
        { defaultToken: "invalid" }
    ]
};

假设编辑器在第4行中使用无效令牌创建了此状态:

enter image description here

是否有一种(最好是简单的)方法来获取无效令牌的行号?还是将我的$ rules状态机重新用于语法检查?

1 个答案:

答案 0 :(得分:1)

找到它-我必须是管理员,Ace Editor确实是好东西。始终按预期工作。

对我有用的是,在使用规则状态机计算了文档的令牌之后,我遍历所有令牌并找到“无效”的令牌,然后在这些行上设置注释。最初只是“语法错误”,但不同类型的“无效”在将来可能意味着不同的情况。这样,我只需要编写一次验证语法验证即可。

aceEditor.session.on('change', function(delta) {

  var sess = aceEditor.session;
  sess.clearAnnotations();

  var invalids = [];
  for( var row=0;row<sess.getLength();row++ ) {

    var tokens = sess.getTokens(row);
    if( !tokens ) continue;

    for( var t=0;t<tokens.length;t++ ) {

      if( tokens[t].type==="invalid" ) {

        invalids.push({ row: row, column: 0, text: "Syntax error", type: "error" });
      }
    }
  }
  sess.setAnnotations( invalids );
});

也许有一种更聪明的方法(也许在某个地方有onToken(type,row,column)函数?),但是上面对我有用。