【问题标题】:How to implement a computer language translator using two separate grammars如何使用两个独立的语法实现计算机语言翻译器
【发布时间】:2012-12-14 09:20:50
【问题描述】:

我想在两种语言 LANG1 和 LANG2 之间创建一个计算机语言翻译器。更具体地说,我想将用 LANG1 编写的代码翻译成 LANG2 中的源代码。

我有 LANG1 和 LANG2 的 BNF 语法。

LANG1 是我自己编写的一个小型 DSL,本质上是 LANG2 的“更简单”版本。

我希望能够从用 LANG1 编写的输入语句生成 LANG2 中的语句。

我正在为 LANG1 编译编译器,但我不知道下一步该做什么(以便将 LANG1 语句转换为 LANG2 语句)。

我对所涉及的步骤的理解如下:

1. BNF for my DSL (LANG1)                                  DONE
2. Reverse engineered the BNF for LANG2                    DONE
3. Learning how to generate a compiler for LANG1           TODO
4. Translate LANG1 statements to LANG2 statements          ???

从 LANG1 语句生成 LANG2 语句涉及哪些步骤?

我的代码库是 C++,所以我可以使用 C 或 C++ 生成的 Parser。

PS:我将使用 ANTLR3 为 LANG1 生成编译器

【问题讨论】:

  • 如果你想用两种语法来驱动这个过程,你应该看看我公司的程序转换引擎,DMS。 DMS 将让你以“如果你在 LANG1 中看到这个,用 LANG2 中的那个替换”的形式编写源到源的转换规则。有关详细信息,请参阅semdesigns.com/Products/DMS/DMSRewriteRules.html

标签: c++ compiler-construction antlr antlr3 translate


【解决方案1】:

在最一般的情况下,您必须将语法的每个可能部分从 LANG1 翻译成适合 LANG2 的内容,或者您​​必须简化为两种语言的最简单的原语,例如汇编或组合子。这有点费时,而且不是很有趣。

但是,如果语法是等价的或有很多共同点,您可能只需将两种语法解析到同一个树中并拥有可以获取标准化树并将其转换回来的输出函数即可进入 LANG1 或 LANG2 源(这与一般情况基本相同,但需要更多的捷径)。

编辑:由于我刚刚重读了您的问题,意识到您只想翻译一种方式,您只需要担心使树适合 LANG1 的形式,只需为 LANG2 提供翻译功能。但我希望我的例子对你有所帮助。

示例树构造:

这里有两种不同的 ANTLR 语法,它们产生相同的极其简单的 AST:

语法 1

第一种是加法的标准表达方式:

grammar simpleAdd;

options {output=AST;}

tokens {
    PLUS = '+';
}

expression : addition EOF!;
addition   : NUMBER (PLUS NUMBER)+ -> ^(PLUS NUMBER*);

NUMBER     :'0'..'9'+;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n')+    { $channel = HIDDEN; } ;

这将接受两个或多个整数并生成一棵带有 PLUS 节点的树,并将列表中的所有数字加在一起。例如,

1 + 1 + 2 + 3 + 5

语法 2

第二种语法的形式不太优雅:

grammar horribleAdd;

options {output=AST;}

tokens {
    PLUS = '+';
    PLUS_FUNC = 'plus';
    COMMA = ',';
    LEFT_PARENS ='(';
    RIGHT_PARENS=')';
} 

expression : addition EOF!;
addition   : PLUS_FUNC LEFT_PARENS NUMBER (COMMA NUMBER)+ RIGHT_PARENS -> ^(PLUS NUMBER*);

NUMBER     :'0'..'9'+;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n')+    { $channel = HIDDEN; } ;

这个语法需要给一个函数提供数字(是的,我知道函数并不是这样工作的,我只是想让这个例子尽可能清晰)。例如,

plus(1, 1, 2, 3, 5)

它产生与第一个语法完全相同的树(一个以数字作为子节点的 PLUS 节点)。

现在您不必担心您的指令来自什么语言,您可以以您喜欢的任何形式输出它。您需要做的就是编写一个可以将此 AST 转换回您选择的语言的函数。

【讨论】:

  • +1 获取详细说明。您能否详细说明如何从 AST 生成语言语句(我是编写编译器的新手)。谢谢
猜你喜欢
  • 1970-01-01
  • 2014-09-26
  • 1970-01-01
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
相关资源
最近更新 更多