PEG.js
实现。您需要通过一些宽松的解析规则扩展语法,以便在上一个语句出错时提供建议。这些宽松规则需要有条件地处理,否则您需要两个单独的语法——一个用于解析源代码,另一个用于代码完成。您可以使用Javascript谓词(在PEG.js
中可用)来维护一个语法。它看起来像&{return laxParsing}
,并且当laxParsing
标志为true
时,会导致整个规则被处理。您可以通过设置解析器的内部标志轻松地在宽松和严格解析之间切换。PEG.js
解析器(版本0.5),以在解析错误结构中接收位置(除列和行之外)和期望列表(除错误消息之外)。您可以从https://gist.github.com/1281239复制准备好的片段。VariableName
)时,您可以触发搜索这些建议。您可以通过在不同的宽松解析模式下解析相同的源代码(仅过滤变量名)来提供列表。PEG.js在生成SyntaxError时会提供相当多的上下文信息。例如,如果您有一个针对SQL的语法,并将以下内容输入:
FOO > 10 A
{
"message": "Expected \"AND\", \"ORDER BY\" or end of input but \"A\" found.",
"expected": [
{
"type": "literal",
"value": "AND",
"description": "\"AND\""
},
{
"type": "literal",
"value": "ORDER BY",
"description": "\"ORDER BY\""
},
{
"type": "end",
"description": "end of input"
}
],
"found": "A",
"offset": 9,
"line": 1,
"column": 10,
"name": "SyntaxError"
}
FOO > 10 AND
、FOO > 10 ORDER BY
、FOO > 10
。如果你将这些附加到查询的有效部分,你将得到一组可能的完整性:function getCompletions(pegParse, text) {
var parsedText = pegParse(text);
var completions = [];
if (parsedText.expected) {
var start = text.substr(0, parsedText.offset);
parsedText.expected.forEach(function(expected) {
if (expected.type != 'literal') return;
var completion = start + expected.value;
if (completion.substr(0, text.length) == text) {
completions.push(completion);
}
});
}
return completions;
}
这很简单 -- 真正的自动完成需要匹配更多内容,而且需要一种方法来利用语法无法获取的上下文信息,例如用户正在调用的函数参数列表。
.parse
之外的任何公共 API。 - Ray Wutry { p.parse(...); } catch (e) { console.log(e); }
获取它。 - Ray Wu