伪代码翻译?

问题描述 投票:16回答:8

像你们这些人一样,我经常用几种语言写作。当涉及到规划的东西,(甚至回答一些SO问题)时,我实际上是用一些未指明的混合语言来思考和写作。虽然我曾经被教过使用流程图或类似UML的图表,但回想起来,我发现“我的”伪代码语言包含CPythonJavabashMatlabperlBasic的组件。我似乎无意识地选择了最适合表达概念/算法的成语。

常见的习语可能包括范围类似Java的括号,pythonic列表推导或缩进,继承C ++,C#-style lambdas,类似matlab的切片和矩阵运算。

我注意到,人们很容易认识到我正在试图做什么,并且人们很容易智能地翻译成其他语言。当然,这一步涉及考虑角落案例,以及每种语言特殊行为的时刻。

但实际上,大多数这些语言共享一个关键字和库函数的子集,这些函数通常表现相同 - 数学函数,类型名称,while / for / if等。显然,我必须排除许多“奇怪”语言,如lisp,APL衍生品,但......

所以我的问题是,

  1. 是否已存在识别文本文件编程语言的代码? (当然,这必须是比eclipse的语法树更简单的任务,或者比谷歌翻译的语言猜测功能,对吧?)事实上,SO语法荧光笔是否做了这样的事情?
  2. 从理论上讲,创建单个解释器或编译器是否可以识别您在任何时刻使用的语言习惯用语(可能是“智能地”)执行或转换为可运行的表单。并标记我的语法在行为方面不明确的极端情况。我看到的直接困难包括:知道何时在缩进依赖和支撑依赖模式之间切换,识别有趣的运算符(如*pointer vs *kwargs)以及知道何时使用列表与数组类似的表示。
  3. 是否存在可以管理这种灵活口译的语言或口译?
  4. 我是否错过了明显的障碍?

编辑

谢谢大家的回答和想法。我打算编写一个基于约束的启发式转换器,它可以“解决”代码以达到预期的含义并转换为真正的python代码。它将注意到来自许多常用语言的关键词,并将使用句法线索来消除人类意图的歧义 - 如间距,括号,可选辅助词如letthen,变量以前如何使用的上下文等,以及常见约定的知识(如资本)名称,i用于迭代,以及对变量/方法命名的一些简单有限的理解,例如包含单词getasynchronouscountlastpreviousmy等)。在真正的伪代码中,变量命名与操作本身一样丰富!

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

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

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

algorithm language-agnostic artificial-intelligence interpreter pseudocode
8个回答
3
投票
  1. 要检测使用的编程语言:Detecting programming language from a snippet
  2. 我认为这应该是可能的。我认为,可以利用1.中的方法来做到这一点。我会尝试迭代地执行:检测代码的第一行/子句中使用的语法,基于该检测将其“编译”为中间形式,以及任何重要的语法(例如开始/结束包装器)。然后是下一行/子句等。基本上写一个尝试识别每个“块”的解析器。可以通过相同的算法标记模糊度。
  3. 我怀疑这已经完成了...似乎是学习写作的认知负担,例如与尝试调试解释器失败的情况相比,python兼容的伪代码要容易得多。
  4. 一个。我认为最大的问题是大多数伪代码在任何语言中都是无效的。例如,我可能完全跳过伪代码块中的对象初始化,因为对于人类读者来说,推断它几乎总是直截了当的。但对于您的情况,它可能在选择的语言语法中完全无效,并且可能无法自动确定例如对象的类(它甚至可能不存在)。等等。 湾我认为你能想到的最好的是一个解释器,只为你的伪代码“工作”(受制于4a),没有其他的。

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


3
投票

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

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

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

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

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

Edit:

Besides, the whole purpose of pseudocode is that it does not need to compile in any way. The reason you write pseudocode is to create a "sketch", however sloppy you like.
foreach c in ImportantCustomers{== OrderValue >=$1M}
    SendMailInviteToSpecialEvent(c)

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


2
投票

认识到一个程序所使用的语言真的不是什么大不了的事。认识到代码片段的语言更加困难,并且识别没有明确分隔的片段(如果四行是Python,下一个是C或Java,你会怎么做?)真的很难。

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

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

而且,假设你克服了所有这些障碍,那么伪代码是如何被解释的,就像你在想的那样?

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

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


2
投票

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

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


1
投票

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


1
投票

一种有趣的方法是“类似你去”伪代码解释器。也就是说,您可以将语言设置为预先使用,然后在您键入时实时将伪代码转换为实际代码。可以使用交互式设施来澄清含糊不清的内容并允许更正。该机制的一部分可能是转换器试图匹配的代码库。随着时间的推移,它可以根据特定用户的习惯来学习和调整其翻译。

在大多数情况下,一直编程的人可能更愿意只使用该语言。但是,我可以看到上述内容对于学习者,“非程序员程序员”,如科学家,以及与各种语言和技能水平的程序员进行头脑风暴会议,都是一个很大的好处。

-Neil


1
投票

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

是的,Unix file命令。

(当然,这必须是比eclipse的语法树更简单的任务,或者比谷歌翻译的语言猜测功能,对吧?)事实上,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中的按位XOR?
  • ||在C中是逻辑OR,还是像SQL一样串联?
  • 什么是1 + "2"?是将数字转换为字符串(给出“12”),还是将字符串转换为数字(给出3)?

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

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

= Y + Z

编译器会识别出一个变量丢失并自动将语句转换为X = Y + Z,无论你的程序中是否有X

这个程序员有一个用一串连字符开始注释块的约定,如下所示:

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

但是有一天,他们忘记了领先的C,并且编译器窒息试图在它认为是减法运算符之间添加几十个变量。

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


1
投票

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

Coq programming language允许“syntax extensions”,因此可以扩展语言来解析新的运算符:

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

类似地,可以扩展Seed7编程语言以使用“structured syntax definitions”解析“伪代码”。 Seed7中的while循环以这种方式定义:

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

或者,有可能“训练”statistical machine translation系统将伪代码转换为真正的编程语言,尽管这需要大量的parallel texts语料库。

© www.soinside.com 2019 - 2024. All rights reserved.