2012-09-07 44 views
3

我是汇编程序设计领域的新手。我正在为一台机器设计我自己的汇编程序。目前,我的汇编程序接受第一个标记(假定它是一条指令),然后尝试生成相应的目标代码。现在我需要将该令牌与一组助记符进行匹配,然后生成相应的obj代码。问题是我目前使用if-else结构,即如何在解析器中避免大量if-else语句

if(strcmp(mnemonic_read, "mov")==0) 
// generate code for mov instr 
else if(strcmp(mnemonic_read,"cmp")==0) 
// generate code for cmp 

我可以在不使用大量if-else语句的情况下做到这一切吗?我可以通过mnemonic_read字符串变量调用函数吗?

+0

为什么不使用真正的解析器?那么这个问题首先不存在。 – harold

+0

有一些称为元汇编程序的工具可将助记符转换为目标代码。 – 2012-09-08 16:53:48

回答

2

这是一个常见的问题,有一个共同的解决方案(哈罗德建议)。

您可能想要查看在* nix环境中工作良好的lex/yacc或flex/bison。 Antlr做类似的事情,但使用Java。

例如,可以使用的lex(来自http://dinosaur.compilertools.net/):

莱克斯源是正则表达式和对应的节目片段的表。该表被翻译成一个程序,该程序读取输入流,将其复制到输出流并将输入分区成与给定表达式匹配的字符串。随着每个这样的字符串被识别,相应的程序片段被执行。

因此,在lex中,您可以指定令牌(通过正则表达式匹配)以及要生成的相应代码。您也可以将这些令牌提供给yacc(又一个编译器编译器),您可以使用它来为您的新语言生成一个编译器。

这里是一个例子一个有用的指南:http://ds9a.nl/lex-yacc/cvs/lex-yacc-howto.html

2

你应该使用一种散列表而不是几十个if-else语句甚至是switch-construct。

另外一定要从简单的解析器逻辑中分离出你的“汇编逻辑”。

1

你可能需要某种形式的哈希表的associative array用于存储你的关键字。这基本上是一个由任何类型索引的数组(对于你的问题有用的将是一个字符串),它包含的值可以是一个函数指针。然后,您会为解析的每个命令调用一个不同的函数。

假设你使用的是C++,从您的代码段,你可以写

// map strings to function pointers 
// which take a string (maybe the operands) as parameter 
map<string, void (*)(string)> commands; 

在构造函数,或者你需要设置散列映射(这基本上是作为一个跳转表)类似的初始化程序:

init() {   
    commands["mov"] = cmd_mov; 
    commands["cmp"] = cmd_cmp; 
    ... 
} 

void cmd_mov(string operands) { 
    // generate move instruction 
} 
void cmd_cmp(string operands) { 
    // generate cmp instruction 
} 

您只需通过

string mnemonic = mnemonic_read_cmd(); 
string operands = mnemonic_read_op(); 
*(commands[mnemonic])(operands); 

如果DIF调用函数每个功能需要不同数量的参数,functionoidboost::function可能是正确的选择,而不是简单的函数指针。