21

像 SO 上的许多人一样,我经常用几种语言写作。当涉及到计划的东西时,(甚至回答一些 SO 问题),我实际上是用一些未指定的混合语言思考和写作的。尽管我曾经被教导使用流程图或类似 UML 的图表来做到这一点,但回想起来,我发现“我的”伪代码语言具有C, Python, Java, bash, Matlab, perl,的组件Basic。我似乎无意识地选择了最适合表达概念/算法的成语。

常见的习惯用法可能包括类似 Java 的范围大括号、pythonic 列表推导或缩进、C++ 类继承、C# 样式 lambda、matlab 类切片和矩阵运算。

我注意到人们实际上很容易准确地识别出我正在尝试做什么,而且人们很容易智能地翻译成其他语言。当然,这一步涉及考虑极端情况,以及每种语言表现出特殊行为的时刻。

但实际上,这些语言中的大多数共享一个关键字和库函数的子集,它们的行为通常相同——数学函数、类型名称等while。显然,我必须排除许多“奇怪”的语言,如 lisp、APL 衍生物,但是...forif

所以我的问题是,

  1. 识别文本文件的编程语言的代码是否已经存在?(与 eclipse 的语法树或 google translate 的语言猜测功能相比,这肯定是一个更简单的任务,对吧?)事实上,SO 语法高亮器会做这样的事情吗?

  2. 理论上是否有可能创建一个单一的解释器或编译器来识别您在任何时候使用的语言习语并(可能“智能地”)执行或转换为可运行的形式。并标记我的语法在行为方面模棱两可的极端情况。我看到的直接困难包括:知道何时在缩进相关模式和大括号相关模式之间切换,识别有趣的运算符(如*pointervs *kwargs)以及知道何时使用列表和类似数组的表示。

  3. 是否存在可以管理这种灵活口译的语言或口译员?

  4. 我是否错过了实现这一目标的明显障碍?

编辑

感谢大家的回答和想法。我计划编写一个基于约束的启发式翻译器,它可能会解决”预期含义的代码并翻译成真正的 python 代码。它会注意到来自许多常用语言的关键字,并将使用句法线索来消除人类意图的歧义——比如空格、括号、可选的辅助词(如letor then)、变量先前使用方式的上下文等,以及常用约定的知识(如大写名称、 i 用于迭代,以及对变量/方法命名的一些简单的有限理解,例如包含单词get, asynchronous, count, last,previousmy)。在真正的伪代码中,变量命名与操作本身一样具有信息量!

使用这些线索,它将创建关于每个操作的实现的假设(如基于 0/1 的索引、何时应捕获或忽略异常、哪些变量应该是 const/global/local、从哪里开始和结束执行以及什么位应该在单独的线程中,注意数字单位何时匹配/需要转换)。每个假设都有一个给定的确定性 - 程序将列出每个语句的假设,因为它会将您编写的内容哄骗成可执行的东西!

对于每个假设,如果您不喜欢最初的解释,您可以“澄清”您的代码。图书馆问题非常有趣。我的翻译器,就像一些 IDE 一样,会读取所有模块中可用的所有定义,使用一些关于哪些类/方法最常使用以及在什么上下文中使用的统计数据,然后猜测!(在程序中添加一个注释来说明它为什么会这样猜测......)我想它应该尝试执行所有内容,并警告你它不喜欢什么。它应该允许任何事情,但如果您模棱两可,请让您知道几种替代解释是什么。

它肯定需要一段时间才能管理像@Albin Sunnanbo 的例子这样不寻常的ImportantCustomer例子。但我会让你知道我是怎么过的!

4

8 回答 8

4

我认为这对除了玩具示例和严格的数学算法之外的所有东西都毫无用处。对于其他一切,语言不仅仅是语言。围绕这些语言有很多标准库和整个环境。我认为我编写的库调用行数几乎与编写“实际代码”一样多。

在 C# 中有 .NET Framework,在 C++ 中有 STL,在 Java 中有一些 Java 库,等等。

这些库之间的差异太大而不仅仅是语法上的细微差别。

<subjective>
已经尝试将不同语言的语言结构统一为“统一的语法”。这被称为4GL语言,但从未真正采用过。
</主观>

作为旁注,我看到了一个关于页面长的代码示例,它可以作为 c#、Java 和 Java 脚本代码有效。这可以作为无法确定实际使用的语言的示例。

编辑:

此外,伪代码的全部目的是它不需要以任何方式编译。您编写伪代码的原因是创建一个“草图”,无论您喜欢多么草率。

foreach c in ImportantCustomers{== OrderValue >=$1M}
    SendMailInviteToSpecialEvent(c)

现在告诉我它是什么语言并为此编写一个解释器。

于 2010-09-13T21:05:31.867 回答
3
  1. 检测使用了什么编程语言:Detecting Programming Language from a snippet
  2. 我认为这应该是可能的。我认为,可以利用 1. 中的方法来做到这一点。我会尝试迭代地执行它:检测代码的第一行/子句中使用的语法,根据该检测将其“编译”为中间形式,以及任何重要的语法(例如开始/结束包装器)。然后是下一行/子句等。基本上编写一个解析器来尝试识别每个“块”。歧义可以通过相同的算法进行标记。
  3. 我怀疑这是否已经完成......似乎学习编写例如python兼容的伪代码的认知负荷比尝试调试解释器失败的情况要容易得多。
  4. 一种。我认为最大的问题是大多数伪代码在任何语言中都是无效的。例如,我可能会在一段伪代码中完全跳过对象初始化,因为对于人类读者来说,推断几乎总是很简单。但是对于您的情况,它可能在选择的语言语法中完全无效,并且可能无法自动确定例如对象的类(它甚至可能不存在)。等等
    我认为你能期望的最好的解释器是一个只为你的伪代码“工作”(受 4a 限制)的解释器,没有其他人的。

请注意,我认为 4a,4b 不一定是它成为可能的障碍。我只是认为它对任何实际目的都没有用。

于 2010-09-13T21:25:50.160 回答
2

识别一个程序是什么语言真的没什么大不了的。识别片段的语言更加困难,识别没有明确分隔的片段(如果四行是 Python,下一行是 C 或 Java,你会怎么做?)将非常困难。

假设您将行分配给正确的语言,那么进行任何类型的编译都需要针对所有可以合作的语言的专门编译器。这本身就是一项巨大的工作。

此外,当您编写伪代码时,您不必担心语法。(如果你是,你做错了。)你会得到根本无法编译的代码,因为它不完整甚至是矛盾的。

而且,假设你克服了所有这些障碍,你能确定伪代码会按照你的想法被解释吗?

您将拥有一种新的计算机语言,您必须用它编写正确的程序。这将是一种庞大且模棱两可的语言,很难正确使用。使用时需要非常小心。这几乎正​​是您在伪代码中不想要的。伪代码的价值在于你可以快速勾勒出你的算法,而不用担心细节。那将完全丢失。

如果您想要一种易于编写的语言,请学习一种。Python 是一个不错的选择。使用伪代码勾勒出应该如何进行处理,而不是作为一种可编译的语言。

于 2010-09-13T21:45:16.147 回答
2

一种有趣的方法是“即用型”伪代码解释器。也就是说,您可以预先设置要使用的语言,然后它会在您键入时尝试将伪代码实时转换为真实代码。交互式工具可用于澄清模棱两可的内容并允许更正。该机制的一部分可能是转换器试图匹配的代码库。随着时间的推移,它可以根据特定用户的习惯学习和调整其翻译。

在大多数情况下,一直在编程的人可能更喜欢只使用该语言。但是,我可以看到以上内容对学习者、“非程序员程序员”(例如科学家)来说是一个巨大的福音,并且可以用于与各种语言和技能水平的程序员进行头脑风暴会议。

-尼尔

于 2010-09-14T17:08:10.107 回答
2

解释人工输入的程序需要选择说“我不知道”。语言 PL/I 是一个著名的系统示例,该系统旨在找到对任何类似于计算机程序的事物的合理解释,当它猜错时可能会造成严重破坏:请参阅http://horningtales.blogspot.com/2006/10/my-第一个pli-program.html

请注意,在后来的 C++ 语言中,当它解决可能的歧义时,它会限制它尝试的类型强制的范围,并且如果没有唯一的最佳解释,它将标记错误。

于 2010-09-14T18:27:54.467 回答
1

我感觉 2. 的答案是否定的。我需要证明它是错误的只是一个代码片段,可以由一个称职的程序员以多种方式解释。

于 2010-09-13T23:52:27.427 回答
1

识别文本文件的编程语言的代码是否已经存在?

是的,Unixfile命令。

(与 eclipse 的语法树或 google translate 的语言猜测功能相比,这肯定是一个更简单的任务,对吧?)事实上,SO 语法高亮器会做这样的事情吗?

据我所知,SO 有一个千篇一律的语法高亮器,它试图结合每种主要语言的关键字和注释语法。有时它会出错:

def median(seq):
    """Returns the median of a list."""
    seq_sorted = sorted(seq)
    if len(seq) & 1:
        # For an odd-length list, return the middle item
        return seq_sorted[len(seq) // 2]
    else:
        # For an even-length list, return the mean of the 2 middle items
        return (seq_sorted[len(seq) // 2 - 1] + seq_sorted[len(seq) // 2]) / 2

请注意,SO 的荧光笔假定//启动 C++ 样式的注释,但在 Python 中它是整数除法运算符。

如果您尝试将多种语言组合成一种语言,这将是一个主要问题。如果同一个标记在不同语言中具有不同的含义,你会怎么做?类似的情况有:

  • ^像 BASIC 中的求幂,还是像 C 中的按位异或?
  • ||像 C 中的逻辑 OR,还是像 SQL 中的字符串连接?
  • 是什么1 + "2"?是数字转换为字符串(给出“12”),还是字符串转换为数字(给出 3)?

是否存在可以管理这种灵活口译的语言或口译员?

在另一个论坛上,我听说了一个编译器(IIRC,for FORTRAN)的故事,它可以编译任何程序而不管语法错误。如果你有这条线

= Y + Z

编译器会识别出缺少变量并自动将语句转换为X = Y + Z,无论X您的程序中是否有 。

这个程序员有一个惯例,用一行连字符开始注释块,如下所示:

C ----------------------------------------

但是有一天,他们忘记了前导C,编译器在它认为是减法运算符之间添加几十个变量时感到窒息。

“灵活解析”并不总是一件好事。

于 2010-09-17T04:15:44.967 回答
1

要创建“伪代码解释器”,可能需要设计一种允许用户对其语法进行自定义扩展的编程语言。已经有几种编程语言具有此功能,例如CoqSeed7AgdaLever。一个特别有趣的例子是Inform编程语言,因为它的语法本质上是“结构化英语”。

Coq 编程语言允许“语法扩展”,因此可以扩展该语言以解析新的运算符:

Notation "A /\ B" := (and A B).

类似地,Seed7 编程语言可以扩展为使用“结构化语法定义”解析“伪代码” 。whileSeed7 中的循环是这样定义的:

syntax expr: .while.().do.().end.while is -> 25;

或者,也许可以“训练”一个统计机器翻译系统将伪代码翻译成真正的编程语言,尽管这需要大量的并行文本语料库。

于 2019-04-03T16:14:57.873 回答