Compiler construction 决定一个错误的程序是否可以有一个正确的延续

Compiler construction 决定一个错误的程序是否可以有一个正确的延续,compiler-construction,programming-languages,ocaml,compiler-theory,Compiler Construction,Programming Languages,Ocaml,Compiler Theory,(下面的问题涉及OCaml语言,并且有OCaml中的示例,但是这个问题非常笼统,可能任何其他计算机语言的正确答案也能解决我的问题。因此,假设这个问题使用您最喜欢的语言。) 我想编写一个函数,它将OCaml中的任意程序作为字符串,并决定该程序是否正确,在后一种情况下,是否可以通过在末尾连接适当的字符将其转换为正确的程序 我假设某个地方有一个该语言的编译器,我可以应用它,并得到一个回答,说“Compiles”或“notcompile--error在X行,字符Y”(无论如何,大多数语言都是这样)。总之

(下面的问题涉及OCaml语言,并且有OCaml中的示例,但是这个问题非常笼统,可能任何其他计算机语言的正确答案也能解决我的问题。因此,假设这个问题使用您最喜欢的语言。)

我想编写一个函数,它将OCaml中的任意程序作为字符串,并决定该程序是否正确,在后一种情况下,是否可以通过在末尾连接适当的字符将其转换为正确的程序

我假设某个地方有一个该语言的编译器,我可以应用它,并得到一个回答,说“Compiles”或“notcompile--error在X行,字符Y”(无论如何,大多数语言都是这样)。总之,我想要一个函数,它接受一个程序并返回:

  • 正确——如果字符串包含正确的程序
  • 错误——如果字符串包含不正确的程序,无论您如何将字符连接到该字符串,该程序都永远不会正确
  • 不完整——如果字符串包含不正确的程序,而该程序不是错误的
例如,OCaml程序
let x=f
不正确,因为在使用时未定义
f
。它不能继续,因为无论你在f之后写什么,都会是一些以前没有定义过的标识符。程序
let x=
也不正确;但是如果我们扩展到
让x=5
,那么我们就有了一个完全有效的程序。因此,我的函数在第一种情况下返回错误,在第二种情况下返回不完整

如果我们有这个计划,事情可能会变得棘手

let ans = 5
let x = a
因为我的函数必须看到,如果我用
ns
继续程序,那么程序就会正确

我的问题是:你认为有可能编写这样的函数/算法吗?如果是,总体思路是什么?如果不是,试着说服我不是


(我对任何见解或部分答案都很满意,例如,暗示不完整的东西。例如,我相信如果语言编译器说第3行有错误,并且程序有100行,那么程序就不可能继续了。)

在您的第一个示例中,
让x=f
,如果我添加
un y->y

我认为你想要的是可能的,但用目前的工具是不行的。如果您只对语法正确性感兴趣,那么基本的想法是运行解析器/词法分析器,如果出现错误则返回“error”,如果没有返回完整的AST但没有错误则返回“complete”(因此它仍在等待更多的输入)

注意:仍然存在一个小的不匹配,因为lexer将在EOF之前返回一个令牌,这可能会继续。你不必把这个标记看作一个完整的标记,并在这点上做一些更精细的推理。更一般地说,输入的极值需要专门的推理,我在这里没有介绍

在词法分析/解析阶段容易实现的特性是,词法分析程序是由解析器按需驱动的——它只读取解析器对令牌流进行推理所需的数据——并且解析器是“严格的”,或者很早就失败了,而不是在故障站点询问更多信息

程序正确性的后一个主要阶段是标识符解析(这个变量名指的是什么?)和类型系统——还有其他标准,比如检查构造函数和类型名的算术性,但它们不是很有趣。你有问题。它们通常不是以需求驱动的方式编写的,或者更一般地说,它们不会试图对部分信息进行推理。以这种方式重新设计它们应该是可能的,但这可能需要很多努力

一个好的方向是“增量解析器”。许多人已经认识到,在与编辑器相关的程序工具中(程序是以增量方式编写的)需要增量。它们处理更一般的问题,即在源代码发生具体更改后更新抽象信息;不仅是一种“添加在末尾”的更改,更是一种更一般的更改。他们的工具可能也能解决你的问题


编辑:啊,我终于找到了我要找的东西。你应该看看奥列格的

该死!为什么我选择了
f
?好的是的,我基本上对语法正确性感兴趣。我如何检查它是否返回完整的AST?(如果有一个具体的案例有帮助,请使用OCaml编译工具的特定案例。)