解析输入文本并输出到文件

时间:2016-05-01 20:22:42

标签: c++ parsing char

我正在编写一个小程序来解析Sony Cell SPU指令的输入文件,并将指令的二进制格式输出到文本。

基本理念是:

输入文本格式是指令rt / ra / rb

a r3,r2,r1
ah r6,r5,r4

输出文本格式为:opcode / rb / ra / rt

00011000000000000100000100000011
00011001000000010000001010000110

基本上,我正在解析命令语法(a,ah等等)并确定操作码。该信息还提供了指令的格式(寄存器格式)。一旦我知道正在访问的寄存器,我将这些值转换为7位值(r3 = 0000011等)。然后,我将32位转换的指令写入输出文本。

我遇到的问题是如何解析指令语法。

特别是,我想到的是将输入文本文件的每一行读入char array并检查索引的低位并将其与每个指令的字符串进行比较,但是我认为这不是一个好方法。

执行此类解析和比较的好方法是什么?

1 个答案:

答案 0 :(得分:0)

如果我理解你,你想避免一连串的

if(strcmp(array, "cmd1") == 0)
else if(strcmp(array, "cmd2") == 0)
//...

然后你可以尝试这样的事情:

switch(array[0])
{
case 'a':
    switch(array[1])
    {
        case ' ':
            // end of command!
            break;
        case 'a':
            // ...
            break;
        default:
            // unknown command
        break;
    }
    break;
case 'b':
    // analogously
    break;
default:
    // unknown command
    break;
}

根据命令的数量及其长度,这很容易变得不可读,但是......

另一种方法:使用::std::unordered_map(或:: std :: tr1 :: unordered_map,如果使用旧的C ++标准)。如果更合适,将字符串映射到适当的处理函数(指向)或(多态!)类。确保通过find(而不是索引运算符[]检索处理程序,因为这会添加一个新元素)并简单地调用它...如果你有一个相当大的指令集,这种方法很有意思。

也许是这样的:

void a(char* cmd) {/*...*/}
void ah(char* cmd) {/*...*/}
/* ... */

typedef ::std::unordered_map<char const*, void(*)(char*)> Handlers
void main(int, char*[])
{
    Handlers handlers;
    handlers["a"] = &a;
    handlers["ah"] = &ah;
    /* open file */
    char array[128];
    char* arguments;
    /* for each line: */
    {
        /*
         *read into array;
         * you need to separate the command from the
         * parameters e. g. by setting the first space following
         * to 0 ('\0'), and setting arguments to the first
         * non-whitespace afterwards
         */      

        Handlers::iterator handler = handlers.find(array);
        if(handler == handlers.end())
        {
            // unknown command
        }
        else
        {
            (*handler)(arguments);
        }
    }
    return 0;
}