您可以从 LR(k) 语法中读取前瞻集(即后面可接受的标记类型),但此类语法往往很大。压缩语法的各种形式(其中 LALR(1) 可能仍然是最常见的)使前瞻集不太精确(它将始终包括有效的标记类型,但也可能包含无效的标记类型)。前瞻集中的无效标记类型也可以通过表压缩和故意包含错误产生(包括以改进错误消息)来引入。
从递归下降解析器读取前瞻集可能会比较棘手,部分原因是此类解析器通常是开放编码的,而不是依赖于转换表。然而,至少在理论上,一个 LL(k) 文法也有可能计算一个前瞻集,尽管它也可能被证明是不精确的。
然而,最有趣的自动补全不是标点符号,而是符号。语法不足以告诉您哪些名称在给定点的范围内,尽管它可能能够告诉您哪些类型的名称是可行的。您需要连接到符号表才能获得准确的自动完成信息。在可以在声明之前使用标识符的语言中,这可能会更加棘手,尽管解析器可能确实在某处保留了未解析名称的列表。
使用解析器生成自动补全信息的另一个困难是解析器倾向于针对语法正确的程序进行优化,并且在检测到语法错误后可能根本无法工作。对于 IDE 用户来说,这真的很烦人。轻微的标点错误会禁用自动完成,直到错误被追踪并修复。(就个人而言,我发现这样的系统太分散了编码的注意力;我宁愿专注于我目前正在编写的内容,也不愿关注代码其他部分中缺少括号的内容。)
IM(H)O,最好使用类似于 Packrat 解析的东西来在插入点挑选出足够的上下文,以便对可能发生的事情有一个合理的概念。如果您可以访问完整的正确数据类型声明,请使用它们,但总会有将文本中看起来像符号的任何内容放入前瞻集中的后备方式(尽管这也可能令人恼火)。
无论如何,祝你好运。