我想知道是否可以直接使用CFG或PEG语法作为代码完成的基础而无需修改。我听说IDE中的代码完成有时会被操纵和按摩,甚至是硬编码,以便它能更好地运行。
我想在一个小型DSL上完成代码编写,因此我完全理解语法无法帮助具有库函数等知识的代码完成系统。
据我所知,解析器本身至少需要提供一个系统来查询接下来的内容。
答案 0 :(得分:13)
使用PEG语法完成代码完成构建Javascript编辑器相当容易。我将用PEG.js
描述如何做到这一点。您需要使用一些松散的解析规则来扩展您的语法,这些规则允许在先前的语句被破坏时提供建议。这些松散的规则需要有条件地处理,否则您将需要两个单独的语法 - 一个用于解析源,另一个用于代码完成。您可以使用Javascript谓词(PEG.js
中提供)来维护一个语法。看起来像&{return laxParsing}
,当laxParsing
标志为true
时,它会导致处理整个规则。您可以通过设置解析器的内部标志轻松地在松散和严格解析之间切换。
要轻松地向用户提供建议,您必须修改稍微生成的PEG.js
解析器(版本0.5),以便在解析错误结构位置(列和行旁边)和期望列表(错误消息旁边)中接收。您可以从https://gist.github.com/1281239复制准备好的片段。
当你有解析器时,你可以在编辑器中附加它,例如CTRL + SPACE keypress。当在文本源中按下这些时,您需要在光标位置放置一个特殊的不可解析符号(以导致解析错误)并在松弛模式下启动解析器。然后,您会收到建议列表中的错误。
一些建议不仅是语法,而且还定义了引用(例如实体,变量)。您可以在找到特定期望时触发搜索(例如VariableName
)。您可以通过在不同的松散解析模式下解析相同的源来提供列表(仅过滤变量名称)。
有关此方法的工作示例和来源,您可以查看https://github.com/mstefaniuk/Concrete-Freetext。
答案 1 :(得分:5)
PEG.js在生成SyntaxError时为您提供了相当多的上下文。例如,如果您有SQL语法并提供类似于:
的语法FOO > 10 A
然后PEG.js会返回:
{
"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"
}
它的含义是它解析了字符串的字符0-9(“FOO> 10”),但后来在字符10处遇到了意外的令牌。它为您提供了它所期望的下一个令牌的列表:{ {1}},FOO > 10 AND
,FOO > 10 ORDER BY
。如果您将这些添加到查询的有效部分,您将获得一组可能的完成:
FOO > 10
这非常简单 - 真正的自动完成功能不仅仅是文字匹配,还需要一些方法来利用语法不可用的上下文,例如:用户正在调用的函数的参数列表。