Questions tagged «compiler»

编译器是一种计算机程序,可以将以一种编程语言编写的源代码转换为另一种计算机语言。

2
编译器应如何报告错误和警告?
我不打算在不久的将来编写编译器。仍然,我对编译器技术以及如何改进这些东西很感兴趣。 从编译语言开始,大多数编译器有两个错误级别:警告和错误,第一个是大多数情况下应修复的非致命性错误,以及表示大多数时间无法生成机器(或字节)的错误。输入的代码。 虽然,这是一个很弱的定义。在某些语言(例如Java)中,如果不使用该@SuppressWarning指令,就无法消除某些警告。而且,Java将某些非致命性问题视为错误(例如,由于我想知道的原因,Java中无法访问的代码会触发错误)。 C#没有相同的问题,但是确实有一些问题。似乎编译是在多个过程中进行的,并且过程失败会阻止进一步的过程继续执行。因此,通常会严重低估构建失败时获得的错误计数。在一次运行中,它可能表明您有两个错误,但是一旦解决它们,您可能会得到26个新错误。 深入研究C和C ++只是显示了Java和C#的编译诊断弱点的不良组合(尽管说Java和C#只是解决了一半的问题可能更准确)。有些警告确实应该是错误的(例如,当并非所有代码路径都返回一个值时),但它们仍然是警告,因为我想,当他们编写标准时,编译器技术还不足以使它们成为此类错误。强制检查。同样,编译器经常检查的内容超出标准所规定的范围,但仍将“标准”警告错误级别用于其他发现。通常,编译器不会立即报告他们可能发现的所有错误;可能需要一些编译才能删除所有这些编译器。更不用说C ++编译器喜欢吐出的隐秘错误, 现在添加了许多构建系统,它们可配置为在编译器发出警告时报告失败,我们只是得到了一个奇怪的组合:并非所有错误都是致命的,但有些警告应该;并非所有警告都是应有的,但有些警告已被明确地压制而没有进一步提及它们的存在;有时所有警告都会变成错误。 非编译语言仍然有糟糕的错误报告。在实际运行代码之前,不会报告Python中的Typos,而且您一次也不会真正引发多个错误,因为脚本在遇到一个错误后便会停止执行。 PHP本身具有许多或多或少的重要错误级别和异常。解析错误一次报告一次,警告通常非常严重,以至于中止您的脚本(但默认情况下不是),通知确实经常显示出严重的逻辑问题,某些错误确实还不足以阻止您的脚本,但仍然这样做,并且像往常一样,在PHP中还有一些很奇怪的东西(为什么我们要为不是真正致命的致命错误需要一个错误级别?E_RECOVERABLE_E_ERROR,我是在和您聊天)。 在我看来,我能想到的编译器错误报告的每个实现都被破坏了。真是太遗憾了,因为所有优秀的程序员都坚持认为正确处理错误非常重要,但却无法获得自己的工具来这样做。 您认为什么是报告编译器错误的正确方法?

2
为什么Forth的灵活性使语法不适合它?
我最近承担了编写基于堆栈的编程语言的任务。但是,在开始设计语言之前,我认为阅读和尝试现有的基于堆栈的语言是一个好主意。 这把我带到了这篇文章的主题。我正在阅读有关Forth的Wikipedia文章,Forth是一种使用后缀样式表达式的基于堆栈的语言。在文章中,我看到了以下语句: Forth的灵活性使静态BNF语法不合适,并且它没有整体编译器。扩展编译器只需要写一个新词,而不需要修改语法和更改基础实现。 据我了解,在Forth术语中,“单词”一词基本上与“子例程”同义。鉴于此,上述说法似乎很奇怪。为什么在Forth中创建新功能的能力会导致Forth的正式语法不合适?为什么需要为定义的每个新子例程重新编写语法?在环境中写一个新单词如何构成扩展编译器?上面的陈述似乎类似于说正式语法不适合Python,因为您可以定义新函数。 实际上,我决定尝试为下面的Forth的一个简单子集编写BNF样式语法: program ::= stmt+ stmt ::= func | expr func ::= ':' expr+ ';' expr ::= INTEGER | word word ::= ('+' | '-' | '*' | '/' ) 上面的语法似乎涵盖了Forth语句的有效子集,并且似乎很难扩展到涵盖Forth语言中的所有有效语句。此外,如果编译器的解析器实现了上述语法,我将看不到如何扩展该编译器。编译器只会在其环境中添加任何新词。仅环境被更改。似乎以上来自Wikipedia的摘录似乎正在将构成编译器(不会更改)的下划线代码与编译器的环境(确实会更改)进行混合。 总而言之,为什么福斯(Forth)定义新词(子例程)的敏捷性不适合书面语法?

1
为什么GCC从Bison切换到C ++和C的递归下降解析器?
是否有需要的语言更改或某种实际的原因,使得Bison不再合适或不理想? 我在Wikipedia上看到它们切换了,参考了GCC 3.4和GCC 4.1发行说明。 这些发行说明指出: 手写递归下降C ++解析器已替换了以前的GCC版本中的YACC派生的C ++解析器。新的解析器包含改进的基础结构,这些基础结构可用于更好地解析C ++源代码,扩展的处理以及适当语义分析和解析之间的清晰分隔(如果可能)。新的解析器修复了旧解析器中发现的许多错误。 和: 旧的基于Bison的C和Objective-C解析器已被新的更快的手写递归下降解析器取代 我想知道的是他们遇到了什么实际问题,以及为什么使用Bison不可能/不切实际解决问题
10 c++  c  parsing  compiler 

5
编译器作者实际上是否需要“理解”机器代码?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 6年前关闭。 可能是一个奇怪的问题。 一个编写C ++编译器(或任何非VM语言)的人:是否需要能够读写原始机器语言?这是如何运作的? 编辑:我专门指的是编译为机器代码的编译器,而不是其他某种编程语言。

3
编写编译器编译器-使用和功能简介
这是一系列问题的一部分,这些问题的重点是抽象项目的姐妹项目,该项目旨在以框架的形式抽象语言设计中使用的概念。姊妹项目称为OILexer,旨在从语法文件构造解析器,而不在匹配项上使用代码注入。 与这些问题相关的其他一些页面,与结构类型相关,可以在这里查看,以及在这里找到易用性。可以在此处找到与有关框架和适当发布位置的查询相关的元主题。 我现在要开始从给定的语法中提取解析树,然后是递归下降解析器,该解析器使用DFA识别前向路径(类似于ANTLR 4的LL(*)),所以我想我会打开它来获得洞察力。 在解析器编译器中,哪种功能比较理想? 到目前为止,这里是实现的简要概述: 范本 提前预测,知道在给定点上什么是有效的。 规则“非文字化”将规则中的文字取下来,并解析它们来自哪个标记。 非确定自动机 确定性自动机 简单的词法状态机,用于令牌识别 令牌自动化方法: 扫描-用于注释:注释:=“ / *” Scan(“ * /”); 减-对标识符有用:标识符:=减(IdentifierBody,关键字); 确保标识符不接受关键字。 编码-将自动化编码为基数N转换的X系列计数。 UnicodeEscape:=“ \\ u” BaseEncode(IdentifierCharNoEscape,16,4); 使用十六进制4转换以十六进制形式对Unicode进行转义。此与:[0-9A-Fa-f] {4}之间的区别是使用Encode进行的自动化将所允许的十六进制值集限制为IdentifierCharNoEscape的范围。因此,如果给它\ u005c,则编码版本将不接受该值。这样的事情有一个严重的警告:谨慎使用。最终的自动化可能非常复杂。 没有实现的是CST生成,我需要调整确定性自动化以继承适当的上下文才能使此工作正常进行。 对于感兴趣的人,我已经上传了T *y♯项目原始形式的漂亮印刷品。每个文件都应该链接到其他文件,我开始链接各个规则来遵循它们,但是这花了太长时间(自动化起来会更简单!) 如果需要更多上下文,请相应地发布。 编辑5-14-2013:我已经编写了代码,可以在给定语言下为状态机创建GraphViz图。 这是AssemblyPart的GraphViz有向图。语言描述中链接的成员在其相对文件夹中应具有rulename.txt,以及该规则的图。自从我发布示例以来,某些语言描述已更改,这是由于简化了语法。这是一个有趣的graphviz图像。

3
如何实现if()的惰性求值
我目前正在根据以下条件实现表达式评估器(单行表达式,如公式): 输入的表达式被标记化以分隔文字布尔值,整数,小数,字符串,函数,标识符(变量) 我实现了Shunting-yard算法(经过微调以处理具有可变数量的参数的函数)以消除括号并以后缀顺序将运算符以适当的优先级排序 我的调车场只是产生了一个(模拟的)令牌队列(通过数组,我的Powerbuilder Classic语言可以定义对象,但只有动态数组作为本机存储-不是真实列表,没有字典),我使用简单堆垛机 我的评估人员工作得很好,但我仍然缺少if(),我想知道如何进行。 使用分流后缀和基于堆栈的评估,如果我添加if()具有真假部分的另一个函数,则单个if(true, msgbox("ok"), msgbox("not ok"))消息将显示两条消息,而我只希望显示一条消息。这是因为当我需要评估一个函数时,它的所有参数都已经被评估并放置在堆栈中。 您能给我一些if()偷懒实现的方法吗? 我虽然将它们作为一种宏进行处理,但是在早期我还没有条件评估。也许我需要使用队列以外的其他结构来分别保存条件和true / false表达式?目前,表达式在评估之前已被解析,但我还计划将中间表示形式存储为一种预编译的表达式,以供将来评估之用。 编辑:经过一些问题后,我认为我可以构建表达式的树表示形式(AST而不是线性令牌流),从中我可以轻松地忽略自己的一个或另一个分支if()。

7
需要哪些计算机科学学科的人员来学习编译器入门课程?[关闭]
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,以使它成为软件工程堆栈交换的主题。 4年前关闭。 我不是计算机科学专业的本科生,并且是专业的网络开发人员(java,python,AS3等)。我每学期在当地大学修一门课程。我上学期参加了人工智能(包括逻辑,上下文无关语法,CYK解析,入门级NLP,马尔可夫链,HMM等)。 我计划在即将到来的semster中学习编译器入门课程,内容涵盖以下课程: 词法分析,语法分析,语义分析,运行时环境,中间表示,代码生成,寄存器分配,指令选择和调度,局部和全局代码优化简介,数据流分析 我的问题是,在学习这门课程之前,我是否应该了解计算机科学专业?如果是,那么请列出这些课程将是很棒的。

6
了解和理解编译器构造的优点是什么?
我是软件工程专业三年级的本科生。从今年开始,我的大学推出了一门名为“编译器构造”的新课程,该课程向您教授构建编译器理论的基础知识。 对于学习编译器构造的软件工程师来说,现实世界的优势是什么?
10 tools  compiler 

3
为什么编译器通常只为安装它们的平台生成可执行文件?
我是C ++开发人员,为了更好地理解跨平台开发,我试图更好地了解编译器的一些实现细节以及它们如何精确创建OS特定的二进制文件。在研究过程中,我意识到,至少有一段时间,您为特定平台下载的大多数编译器仅针对该平台编译了二进制文件。因此,如果您下载了Windows编译器exe附带的IDE,则该编译器将只能针对x86-x64 Windows应用程序而非Linux或Mac应用程序编译程序。 现在,我了解到不同的平台需要不同的二进制格式,但是为什么说Windows上的可视C ++编译器很难生成Linux二进制可执行文件呢?只要您具有运行CPU的汇编指令以及特定于OS的库,您是否不应该能够在任何计算机上为任何平台编译可执行文件?

2
因为GCC是用C ++本身编写的,所以没有鸡和蛋的问题吗?
从4.8版本开始,C ++编译器GCC(它的G ++部分)不再用C编写,而是用C ++本身编写。我对此有一个假设的问题。 我想知道如何在还没有C ++编译器的新平台上编译GCC的C ++代码。当然,您可以使用在其他计算机上编译的预构建二进制文件。或者,您可以使用用C编写的旧版GCC,然后使用它编译当前版本。 但是,如果没有预构建的二进制文件,而只有最新版本,您就会陷入困境,对吗?如果没有,那么从GCC项目的C转换为C ++会对这种情况产生其他影响吗?
10 c++  compiler  gcc 

3
Clang / LLVM准备好迎接黄金时间了吗?[关闭]
按照目前的情况,这个问题并不适合我们的问答形式。我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 6年前关闭。 可以使用Clang代替gcc吗?您对此有何经验?还有哪些不利条件? 编译的性能比gcc好得多,但是关于执行它时生成的代码的性能呢? 有没有好的工具可以在Linux或Windows上运行作为前端(IDE)? 编辑:我的意思是C编译器。C ++还不是很好。

5
为什么不允许使用返回类型进行重载?(至少使用常用语言)
我不了解所有编程语言,但很明显,通常不支持考虑到方法的返回类型(假设其参数具有相同的数字和类型)而重载方法的可能性。 我的意思是这样的: int method1 (int num) { } long method1 (int num) { } 这并不是编程的大问题,但在某些情况下,我会对此表示欢迎。 显然,如果没有区分所调用方法的方法,这些语言将无法支持它,但是其语法可能像[int] method1(num)或[long] method1(num)这样简单。这样,编译器将知道哪个将被调用。 我不知道编译器是如何工作的,但这看起来并不难,所以我想知道为什么通常不会实现这样的事情。 为什么不支持类似的原因是什么?

3
为什么Python同时需要编译器和解释器?
我可以理解Java需要编译器和解释器的事实。它将源代码编译为字节码,然后虚拟机(在Windows,Linux,Android等上)将字节码转换为当前体系结构的机器码。 但是,为什么Python同时需要编译器和解释器?由于Python不是平台独立的,为什么不只使用解释?据我所知,未经修改,您将无法在任何Windows或Linux计算机上执行Python程序(编译为字节码)。还是我错了?

8
是什么阻止了C的编译/解释/ JIT处理?
Java经常以其惊人的可移植性而受到赞誉,我认为这是因为JVM。我的问题是阻止C进行编译/解释/ JIT的原因是什么,如果是这样,C也可以编写一次并使其在您拥有的任何设备上工作。但这不是处理C程序的流行机制。 用这种方式处理C的缺点是什么,当然除了可移植性以外,用这种方式处理Java而不编译为机器代码的优点是什么?

3
在为动态类型的语言编写编译器时与类型相关的挑战是什么?
在本次演讲中,Guido van Rossum正在谈论(27:30)有关尝试为Python代码编写编译器的评论,并评论说: 事实证明,编写一个可以维护所有出色的动态键入属性并保持程序语义正确性的编译器并非易事,因此无论您在幕后的某个地方进行何种操作并实际运行,它实际上都可以执行相同的操作任何更快 在为像Python这样的动态类型语言编写编译器时,与类型相关的(可能)挑战是什么?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.