ace 编辑器语法荧光笔中行尾的退出状态
Exit state at end of line in ace editor syntax highlighter
我正在为 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
中的 /(?:\)|(?=$))/
似乎只有在前一个状态 不是 字符串时才匹配。不管怎样我怎样才能让它匹配,所以我的词法分析器即使使用冒号式函数调用也存在函数调用?
更令人困惑的是,如果我将正则表达式更改为 /(?:|(?=$))/
,它会正确突出显示所有行,即使我不明白为什么。这是怎么回事?
主要问题是在行尾的 ace 只允许一个状态转换 https://github.com/ajaxorg/ace/blob/master/lib/ace/tokenizer.js#L317。所以在行尾匹配 "
并切换到函数状态后,它不会再次调用 regexp 所以 $
不会匹配任何东西。您可能可以在 github.
上报告此问题
第二个问题是您的代码中 variable_name 变量名拼写错误。
这是您的荧光笔的修改版本,除了 $
之外,它还使用 ^
来获得与您想要的类似的突出显示效果。
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 : 'paren',
regex : /(?:[:(])/,
},
{
token : 'paren',
regex : /(?:\)|$|^)/,
next : 'pop'
},
{ include : 'commaList' },
],
// A series of arguments, separated by commas
'commaList' : [
{
token : 'text',
regex : /\s+/,
}, {
token : 'string.start',
regex : /"/,
push : 'string',
}, {
include : "variableName"
}
],
'variableName' : [
{
token : 'variable.parameter',
regex : /[a-z][a-zA-Z0-9_.]*/
},
],
'string': [
{
token : 'string.end',
regex : /"/,
next : 'pop'
},
{ defaultToken : 'string.quoted' }
],
};
this.normalizeRules();
};
oop.inherits(MyHighlightRules, TextHighlightRules);
exports.MyHighlightRules = MyHighlightRules;
});
我正在为 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
中的 /(?:\)|(?=$))/
似乎只有在前一个状态 不是 字符串时才匹配。不管怎样我怎样才能让它匹配,所以我的词法分析器即使使用冒号式函数调用也存在函数调用?
更令人困惑的是,如果我将正则表达式更改为 /(?:|(?=$))/
,它会正确突出显示所有行,即使我不明白为什么。这是怎么回事?
主要问题是在行尾的 ace 只允许一个状态转换 https://github.com/ajaxorg/ace/blob/master/lib/ace/tokenizer.js#L317。所以在行尾匹配 "
并切换到函数状态后,它不会再次调用 regexp 所以 $
不会匹配任何东西。您可能可以在 github.
第二个问题是您的代码中 variable_name 变量名拼写错误。
这是您的荧光笔的修改版本,除了 $
之外,它还使用 ^
来获得与您想要的类似的突出显示效果。
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 : 'paren',
regex : /(?:[:(])/,
},
{
token : 'paren',
regex : /(?:\)|$|^)/,
next : 'pop'
},
{ include : 'commaList' },
],
// A series of arguments, separated by commas
'commaList' : [
{
token : 'text',
regex : /\s+/,
}, {
token : 'string.start',
regex : /"/,
push : 'string',
}, {
include : "variableName"
}
],
'variableName' : [
{
token : 'variable.parameter',
regex : /[a-z][a-zA-Z0-9_.]*/
},
],
'string': [
{
token : 'string.end',
regex : /"/,
next : 'pop'
},
{ defaultToken : 'string.quoted' }
],
};
this.normalizeRules();
};
oop.inherits(MyHighlightRules, TextHighlightRules);
exports.MyHighlightRules = MyHighlightRules;
});