2012-09-20 56 views
4

解析器通常如何处理自动完成?解析器自动完成整合

如果我们举一个例子,在那里我通过以下的解析器:

"int i=2" 

那么对于这个自动完成选项可能包括:

"int i=2," 
"int i=2;" 

应自动完成是解析器的一部分?

如果没有,那么在基于事件的解析器的情况下,我猜解析器将发出包含在解析器的状态机的分支是可能的IDS的事件。然后自动完成模块将知道为每个这样的状态打印什么。

对于基于树的解析器,解析器会返回一个树形结构,其中包含以某种方式现有的那些分支。

这是如何完成的?当需要自动完成时,哪种类型的解析器最适合处理命令字符串?

回答

8

可以读取先行集(即,令牌类型的可接受如下)从LR(k)文法,但这样的文法往往是巨大的。压缩语法的各种形式(其中LALR(1)可能仍然是最常见的)使得lookahead集合不那么精确(它总是包含有效的标记类型,但也可能包含无效的标记)。表视图集中的无效标记类型也可以通过表压缩和故意包含错误生成(包含在内以改进错误消息)来引入。

读取先行从递归下降语法分析器设置可以是麻烦,部分原因是因为这样的解析器通常开编码,而不是依赖于转换表。然而,至少在理论上,一个LL(k)语法也有可能计算一个前瞻集,尽管它也可能变得不精确。

最有趣的自动完成,不过,是不是标点符号,而且符号。一个语法不足以告诉你在给定点上哪些名称在范围内,尽管它可能能够告诉你哪些类型的名称是可行的。您需要挂钩到符号表才能获得准确的自动填充信息。在标识符可以在声明之前使用的语言中,这可能更加棘手,尽管解析器很可能在某处保留了未解析名称的列表。

使用解析器生成自动完成信息的另一个困难是,解析器倾向于为语法正确的程序进行优化,并且可以不检测语法错误之后在所有工作。对于IDE用户来说,这可能会让人感到恼火;轻微的标点符号错误会禁用自动完成,直到错误被追踪并修复。 (就我个人而言,我发现这样的系统过于分散注意力;我宁愿把重点放在我现在写的东西上,而不是在代码的其他部分丢失括号。)

IM(H)O,it最好使用类似于packrat解析的东西来在插入点处选择足够的上下文以获得关于可能遵循的内容的合理概念。如果您有权访问完整的数据类型声明,请使用它们,但始终存在将文本中看起来像符号的任何内容放入预见集(尽管这也可能会让人恼火)的后备方法。

祝你好运,无论如何。