2016-05-01 14 views
0

Ich schreibe ein kleines Programm, um eine Eingabedatei von Sony Cell SPU-Anweisungen zu analysieren und gibt ein Textformat an das binäre Format der Anweisung aus.Eingangstext analysieren und in eine Datei ausgeben

Der Grundgedanke ist folgender:

Eingabetextformat ist Instruktion rt/ra/rb

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

Ausgabetextformat ist: Opcode/rb/ra/rt

00011000000000000100000100000011 
00011001000000010000001010000110 

Also im Grunde parsiere ich die Befehlssyntax (a, ah, etc ...) und ermittle den Opcode. Diese Information gibt mir auch das Format der Anweisung (die Registerformate). Sobald ich weiß, auf welche Register zugegriffen wird, wandle ich diese Werte in 7-Bit-Werte um (r3 = 0000011, etc ..). Dann schreibe ich die 32-Bit-Konvertierung in einen Ausgabetext.

Wo ich stecken bleibe, ist, wie man das Parsing der Befehlssyntax macht.

Insbesondere, was ich im Sinn hatte war in jeder Zeile der Eingabe Textdatei in eine char array lesen und überprüfen Sie die niedrigen Bits des Index und vergleichen Sie es mit einer Zeichenfolge für jede meiner Anweisungen, aber ich nicht denke, das ist eine gute Methode.

Was ist eine gute Methode, um diese Art von Analyse und Vergleich durchzuführen?

Antwort

0

Wenn ich Sie recht verstehe, wollen Sie eine Kette von

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

Dann vermeiden Sie so etwas wie dies versuchen könnte:

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; 
} 

Abhängig von der Anzahl der Befehle und deren Länge, dies kann leicht unlesbar werden, obwohl ...

Ein anderer Ansatz: Verwenden ::std::unordered_map (oder :: std :: tr1 :: unordered_map, wenn ältere C++ verwenden Standard). Ordnen Sie Ihre Strings geeigneten Handlerfunktionen (Pointern auf) oder (polymorphen!) Klassen zu, wenn dies sinnvoller ist. Stellen Sie sicher, dass Sie den Handler über find (nicht den Indexoperator [], da dies ein neues Element hinzufügen würde) abrufen und einfach aufrufen ... Dieser Ansatz ist interessant, wenn Sie einen ziemlich großen Befehlssatz haben.

Vielleicht so etwas wie dieses:

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; 
} 
Verwandte Themen