在ace编辑器语法高亮显示中,在行尾退出状态

时间:2015-08-28 11:15:02

标签: syntax-highlighting ace-editor lexical-analysis

我正在为Ace Editor编写语法高亮显示器,而且我在使用这种语言正确地调用函数调用时遇到了麻烦。函数调用有两种基本形式:

括号:

function(foo, "bar")

用冒号:

function: foo, "bar"

我可以检测两种形式,但是一旦我进入冒号式函数调用的状态,我就很难找回该状态的 out (这会弄乱以下几行)。特别是,当函数调用以字符串结尾时,就会出现此问题。

我已经制作了一个较小版本的荧光笔,只关注这个问题。结构可能看起来过于复杂,但请记住,这是较大词法分析器的一部分,我认为这保证了复杂性。

您可以使用以下代码段在mode creator中进行试用,其中第三行未正确突出显示。

function(a, "bar")
function: a, "bar"
function("bar", a)
function: "bar", a
function("bar")

这里是语法定义:

define(function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var MyHighlightRules = function() {

    var functions = [ "function" ];

    this.$rules = {
        "start" : [
            {
                token : 'keyword',
                regex : '\\b(?:' + functions.join('|') + ')(?=\\s*[:(])',
                push  : [
                    { include : 'function' },
                ]
            }
        ],
        // A function call
        'function' : [
            {
                token : 'text',
                regex : /(?:[:(])/,
                push  : [
                    { include : 'comma_list' },
                ]
            }, {
                token : 'keyword',
                regex : /(?:\)|(?=$))/,
                next  : 'pop'
            }
        ],
        // A series of arguments, separated by commas
        'comma_list' : [
            {
                token : 'text',
                regex : /\s+/,
            }, {
                token : 'string',
                regex : /"/,
                next : 'string',
            }, {
                include : "variable_name"
            }
        ],
        'variable-name' : [
            {
                token : 'keyword',
                regex : /[a-z][a-zA-Z0-9_.]*/,
                // This makes no difference
                next : 'pop'
            },
        ],
        'string': [
            {
                token : 'string.quoted',
                regex : /"/,
                next  : 'pop'
            },
            { defaultToken : 'string.quoted' }
        ],
    };

    this.normalizeRules();
};

oop.inherits(MyHighlightRules, TextHighlightRules);

exports.MyHighlightRules = MyHighlightRules;
});

具体来说:/(?:\)|(?=$))/中的function似乎只有在前一个状态为字符串时才匹配。我怎么能让它匹配,所以我的词法分析器即使用冒号函数调用也存在函数调用?

为了使事情更加混乱,如果我将正则表达式更改为/(?:|(?=$))/,它会正确地突出显示所有行,即使我无法理解为什么。这里发生了什么?

1 个答案:

答案 0 :(得分:1)

主要问题是,在行尾,ace只允许一个状态转换https://github.com/ajaxorg/ace/blob/master/lib/ace/tokenizer.js#L317。因此,在行尾匹配default alias并切换到功能状态后,它不会再次调用regexp,因此"无法匹配任何内容。您可能可以在github上报告此问题。

第二个问题是代码中的variable_name变量名拼写错误。

以下是您的荧光笔的修改版本,除了$之外还使用^来突出显示您想要的内容。

$