【发布时间】:2011-01-24 13:07:39
【问题描述】:
解析技术在 CS 文献中有很好的描述。但是我知道的算法要求源在语法上是正确的。如果遇到语法错误,解析将立即中止。
但 IDE(如 Visual Studio)通常能够在键入时提供有意义的代码完成和其他提示,这意味着语法通常处于无效状态。例如。您在函数调用中键入左括号,IDE 会为函数提供参数提示,即使在键入右括号之前语法无效。
在我看来,这必须依赖某种猜测或容错解析器。任何人都知道为此使用了哪些技术或算法?
【问题讨论】:
解析技术在 CS 文献中有很好的描述。但是我知道的算法要求源在语法上是正确的。如果遇到语法错误,解析将立即中止。
但 IDE(如 Visual Studio)通常能够在键入时提供有意义的代码完成和其他提示,这意味着语法通常处于无效状态。例如。您在函数调用中键入左括号,IDE 会为函数提供参数提示,即使在键入右括号之前语法无效。
在我看来,这必须依赖某种猜测或容错解析器。任何人都知道为此使用了哪些技术或算法?
【问题讨论】:
标准技巧是使用解析机器进行某种错误修复以帮助进行预测。
对于基于表的解析器(例如 LALR 或 GLR),当发生语法错误时,解析器最近处于某种尚未发生错误的状态。可以记录解析堆栈以在每次班次之前记住这一点(或者在错误之前记录减少)。鉴于遇到错误,可以检查已保存堆栈的解析状态以确定下一个可能是哪些标记(这也是根据语法标记完成代码的方式)。一种更复杂的技术可以发明最小可能的标记序列,以允许错误标记的移位,或者可以替换错误标记并允许在下一个移位的最小可能的树。
这对于递归下降解析器来说并不那么容易,因为周围没有很多信息可以用来做谓词。对于错误恢复,一个俗气的技巧是定义错误恢复点(例如,可以接受“stmt”的位置)并继续扫描直到出现“;”找到并接受和“错误stmt”。如果您想要代码完成,这无济于事。
【讨论】:
Packrat 很有前景——它提供关键点解析尝试成功和失败的信息,这些信息可以恢复并用于智能错误报告、完成、提示等。例如,如果光标位于缓存中所有解析尝试都标记为失败的位置,则可以为完成选项提供尝试过的令牌列表。
【讨论】: