我正在用Java构建一个针对Windows的x86-32(IA32)处理器的编译器/汇编器/链接器。
高级概念(我没有任何“源代码”:没有语法或词汇翻译,并且所有语言都是常规的)被翻译成操作码,然后将其包装并输出到文件中。翻译过程有几个阶段,一个是常规语言之间的转换:最高级别的代码被翻译成中级代码,然后被转换为最低级别的代码( 超过3个级别。)
我的问题如下;如果我将更高级别的代码(X
和Y
)翻译为更低级代码(x
,y
,U
和V
),然后这种翻译的一个例子是伪代码:
x + U(f) // generated by X
+
V(f) + y // generated by Y
(一个简单示例)其中V
与U
相反(与作为U
的堆叠推送相比较,与V
相比较)。这需要“优化”为:
x + y
(基本上删除了“无用的”代码)
我的想法是使用正则表达式。对于上述情况,它将是一个正则表达式,如下所示:x:(U(x)+V(x)):null
,意味着所有x
查找U(x)
后跟V(x)
并替换为null
}。想象一下更复杂的正则表达式,用于更复杂的优化。这应该适用于所有级别。
你有什么建议?什么是优化和生产快速x86组件的好方法?
答案 0 :(得分:8)
你应该做的是建立一个 Abstract Syntax Tree (AST) 。
它以树的形式表示源代码,更容易使用,特别是进行转换和优化。
代表树的代码类似于:
(+
(+
x
(U f))
(+
(V f)
y))
然后你可以尝试进行一些转换:总和之和是所有术语的总和:
(+
x
(U f)
(V f)
y)
然后你可以扫描树,你可以有以下规则:
然后你会得到你想要的东西:
(+ x y)
关于编译器编写的任何好书都会在AST上讨论很多。函数式编程语言特别适合这项任务,因为通常很容易表示树并进行模式匹配来解析和转换树。
通常,对于此任务,应避免使用正则表达式。正则表达式定义了数学家称之为常规语言的内容。任何常规语言都可以通过一组正则表达式解析。但是,我认为您的语言不规则,因此无法通过正则表达式进行正确解析。
人们尝试并尝试使用正则表达式解析HTML等语言。这已在SO中进行了广泛讨论,您无法使用正则表达式解析HTML。总会有一个例外情况,你的正则表达式会失败,你必须适应它。
它可能与你的语言相同:如果它不规则,你应该避免很多麻烦,不要试图用正则表达式解析它(特别是“转换”它)。
答案 1 :(得分:5)
我在理解这个问题时遇到了很多麻烦,但我认为你会发现学习术语重写系统的一些内容很有用,这似乎是你提出的建议。机制是树重写(总是有效)还是正则表达式(某些时候某些语言都可以使用,其他语言一直有效)是次要的。
绝对可以通过术语重写来优化对象代码。你可能也会从学习窥视孔优化的知识中受益;一个好的起点,因为它在基本面上非常强大,是戴维森和弗雷泽在retargetable peephole optimizer上发表的一篇论文。贝尼特斯和戴维森也有excellent later work。