我正在为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
似乎只有在前一个状态为不字符串时才匹配。我怎么能让它匹配,所以我的词法分析器即使用冒号函数调用也存在函数调用?
为了使事情更加混乱,如果我将正则表达式更改为/(?:|(?=$))/
,它会正确地突出显示所有行,即使我无法理解为什么。这里发生了什么?
答案 0 :(得分:1)
主要问题是,在行尾,ace只允许一个状态转换https://github.com/ajaxorg/ace/blob/master/lib/ace/tokenizer.js#L317。因此,在行尾匹配default alias
并切换到功能状态后,它不会再次调用regexp,因此"
无法匹配任何内容。您可能可以在github上报告此问题。
第二个问题是代码中的variable_name变量名拼写错误。
以下是您的荧光笔的修改版本,除了$
之外还使用^
来突出显示您想要的内容。
$