标签: compiler-theory

装配性能调整

我正在编写一个编译器(更多的是为了娱乐而不是其他任何东西),但我想尽量使它尽可能高效.例如,有人告诉我,在英特尔架构中,使用除EAX执行数学之外的任何寄存器都会产生成本(大概是因为它转换成EAX实际的数学运算).这里至少有一个说明可能性的来源(http://www.swansontec.com/sregisters.html).

我想验证和衡量这些性能特征的差异.因此,我用C++编写了这个程序:

#include "stdafx.h"
#include <intrin.h>
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    __int64 startval;
    __int64 stopval;
    unsigned int value; // Keep the value to keep from it being optomized out

    startval = __rdtsc(); // Get the CPU Tick Counter using assembly RDTSC opcode

    // Simple Math: a = (a << 3) + 0x0054E9
    _asm {
        mov ebx, 0x1E532 // Seed
        shl ebx, 3
        add ebx, 0x0054E9
        mov value, ebx
    }

    stopval …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-construction assembly compiler-theory

9
推荐指数
4
解决办法
587
查看次数

编程语言需要哪些语言功能才能生成编译器?

编程语言似乎经历了几个阶段.首先,有人想出了一种新语言Foo Language.编译器/解释器是用另一种语言编写的,通常是C语言或其他一些低级语言.在某些时候,FooL会成熟并逐渐成长,最终某人会在FooL本身为FooL编写编译器和/或解释器.

我的问题是:语言功能的最小子集是什么,有人可以自己实现该语言?

language-agnostic compiler-theory

8
推荐指数
1
解决办法
442
查看次数

示例编译器

我正在寻找能够用编程语言从输入程序创建Win32程序的编译器的源代码(哪个更好,也许更简单更好)

然而,我找不到任何适合我的东西,像GCC这样的大型编译器让我非常困惑,因为它们有很多功能,我不知道从哪里开始.

  • 是否有一个OpenSource Win32微编译器用于某些编程语言我可以看看?

compiler-construction open-source compiler-theory

8
推荐指数
1
解决办法
578
查看次数

删除ANTLR中的左递归

正如在删除左递归中所解释的,有两种方法可以删除左递归.

  • 修改原始语法以使用某些过程删除左递归
  • 最初编写语法不要有左递归

人们通常用什么来移除(没有)ANTLR的左递归?我使用flex/bison进行解析器,但我需要使用ANTLR.我唯一担心的是使用ANTLR(或普通的LL解析器)是去除递归.

  • 实际上,在ANTLR中删除左递归有多严重?这是使用ANTLR的一个显示器吗?或者,在ANTLR社区中没有人关心它?
  • 我喜欢AN生成AST的想法.在获得AST快速简便的方法方面,哪种方法(2中删除左递归方法)更可取?

添加

我用以下语法做了一些实验.

E -> E + T|T
T -> T * F|F
F -> INT | ( E )

离开递归后,我得到以下一个

E -> TE'
E' -> null | + TE'
T -> FT'
T' -> null | * FT'

我可以提出以下ANTLR表示.尽管如此,它相对简单明了,似乎没有左递归的语法应该是更好的方法.

grammar T;

options {
    language=Python;
}

start returns [value]
   : e {$value = $e.value};
e returns [value]
   : t ep  
     {
       $value = $t.value
       if $ep.value != None:
         $value += $ep.value
     }
   ; …

antlr compiler-theory

8
推荐指数
2
解决办法
6786
查看次数

什么是抽象语法树/它需要吗?

我一直对编程/解释器设计/实现感兴趣,只要我编程(现在只有5年),它总是看起来像幕后的"魔术",没有人真正谈论过(我至少知道) 2个用于操作系统开发的论坛,但我不知道编译器/解释器/语言开发的任何社区).无论如何,最近我决定开始自己的工作,希望扩展我对整个编程的知识(嘿,这很有趣:).因此,基于我所拥有的有限数量的阅读材料和维基百科,我已经为编译器/解释器开发了这个组件的概念:

源代码 - >词法分析 - >抽象语法树 - >句法分析 - >语义分析 - >代码生成 - >可执行代码.

(我知道代码生成和可执行代码还有更多,但我还没有那么远:)

有了这些知识,我创建了一个非常基本的词法分析器(在Java中)从源文件中获取输入,并将标记输出到另一个文件中.示例输入/输出如下所示:

输入:

int a := 2
if(a = 3) then
    print "Yay!"
endif
Run Code Online (Sandbox Code Playgroud)

输出(来自词法分析器):

INTEGER
A
ASSIGN
2
IF
L_PAR
A
COMP
3
R_PAR
THEN
PRINT
YAY!
ENDIF
Run Code Online (Sandbox Code Playgroud)

就个人而言,我认为从那里进行语法/语义分析,甚至可能甚至是代码生成都会非常容易,这让我有一个问题:为什么使用AST,当我的词法分析员看起来做得同样好的时候呢?但是,我用来研究这个主题的100%的资源似乎都坚持认为这是任何编译器/解释器的必要部分.我是否错过了AST的真正含义(显示程序逻辑流程的树)?

TL; DR:目前正在开发编译器,完成词法分析器,在我看来,输出将使得简单的句法分析/语义分析,而不是做AST.那为什么要用一个?我错过了一点吗?

谢谢!

language-agnostic compiler-theory abstract-syntax-tree

8
推荐指数
2
解决办法
3457
查看次数

具有固定/预分配寄存器的表达式的代码生成

我正在使用这个(见下文)算法(从这个答案的想法)到树的代码生成.我的目标是x86 arch,现在我需要处理使用寄存器eax/ebx作为参数的mul/div指令.

我的问题是:

如何修改它以加载某个指令的操作数以加载到固定寄存器?比如,对于mul指令加载左右子树eaxebx寄存器.我当前的实现是:传递当前节点开始评估为参数,如果它是MULDIV设置regR0R1根据树的一侧,如果它LEFTRIGHT分别.如果regin_use,则推送reg堆栈并将其标记为开始免费(尚未实现).当前的实现不起作用,因为它assert(r1 != r2)emit_load()函数中断言(意味着作为参数传递的两个寄存器都等于r1 = REG_R0r2 = REG_R0)

      void gen(AST *ast, RegSet in_use, AST *root) {
            if(ast->left != 0 && ast->right != 0) {
                Reg spill = NoRegister; /* no spill yet */
                AST *do1st, *do2nd;     /* what order to generate children …
Run Code Online (Sandbox Code Playgroud)

c compiler-construction algorithm code-generation compiler-theory

8
推荐指数
1
解决办法
458
查看次数

以下常规语言的最小抽水长度

以下语言的最小抽水长度是多少?

  1. 空语
  2. (01)*
  3. 10(11*0)*0
  4. 1011
  5. 011 ü 0*1*

这是我的解决方案.如果我错了,请纠正我.

  1. p = 0,因为该语言没有可泵送的字符串
  2. p = 2因为01是可以泵送的最短字符串
  3. p = 5因为10100是可以泵送的最短字符串
  4. p = 0,因为不能抽出字符串
  5. p = 1,因为0可以泵送字符串

我不确定我的答案,所以任何帮助都表示赞赏.非常感谢!

computer-science compiler-theory computation-theory regular-language

8
推荐指数
2
解决办法
7053
查看次数

哪种编程语言有常规语法?

我很好奇哪些(如果有的话)现实世界的编程语言都有常规语法(即所有语法正确的程序集是常规的).

另请参阅此问题:哪些编程语言不受上下文限制?.

programming-languages compiler-theory regular-language

7
推荐指数
1
解决办法
1553
查看次数

将节点放入不应该存在的解析树中

我正在编写一种语言解析器,扫描仪的设计目的是为了

  1. 要么也返回不需要的终端(例如whitespacing)OR
  2. 不要这样做

基于布尔标志.

现在,在解析器中,我不想用所有这些终端混淆语法,它们应该被我正在构建的解析树以某种方式"自动地"吞噬.

要做到这一点"神奇",我想我会链接终端(简单地链接循环列表)所以我可以迭代它们并"填充空白",因为减少发生(我正在使用LALR(1)解析器生成器) .

这听起来像一个理智的想法,虽然有一个问题.记得我说"要么退还......要不"?在场景(2)中,我会释放终端,因为谁知道接下来会发生什么?而且我不希望任何内存泄漏.

但是在方案(1)中,我无法释放终端,因为基于它们,我将决定进一步减少哪些"填空"过程应该停止.

由于同样的原因,我无法有条件地释放它:我不知道接下来会发生什么.如果没有任何"填空"流程被触发怎么办?如果根本没有进一步减少怎么办?

你有类似的问题吗?你是怎么解决的?

注意:这完全在我的脑海中,我可能没有足够清楚地解释,请询问,我将编辑我的问题.这个场景实际上有点复杂,我不是从头开始写这个,我可以用我的想象力,我把它整合到其他东西中,所以很可能我会回答"我做不到因为环境的限制".


附录

我想到的唯一非常好的想法是分叉和改进解析器生成器,我已经在这里和那里的一些小地方做了,以克服我上面提到的一些限制.

c parsing programming-languages lalr compiler-theory

7
推荐指数
1
解决办法
159
查看次数

实现公共子表达式消除

我正在研究对应于大数学表达式(数百万个节点)的表达式图实现公共子表达式消除(CSE).

什么算法适合执行此操作?我在互联网上搜索一个易于实现的算法,但我找不到任何东西.如果可能,算法应该具有完整表达图的节点数的线性复杂度.

compiler-theory compiler-optimization graph-algorithm

7
推荐指数
1
解决办法
3803
查看次数