2016-05-01 3 views
0

Я пишу небольшую программу для синтаксического анализа входного файла инструкций и выходов сотового ящика Sony Cell для текста в двоичном формате инструкции.Анализ текста ввода и вывода в файл

Основная идея заключается в следующем:

входной формат текста инструкция Rt/RA/RB

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

формат вывода текста: опкод/​​гь/га/к.т.

00011000000000000100000100000011 
00011001000000010000001010000110 

Таким образом, в основном, синтаксический анализ синтаксиса команды (a, ah и т. Д.) И определение кода операции. Эта информация также дает мне формат инструкции (форматы регистра). Как только я узнаю, что доступ к регистру, я преобразую эти значения в 7-битные значения, поэтому (r3 = 0000011 и т. Д.). Затем я пишу 32-битную преобразованную команду в выходной текст.

Где я застрял, это о том, как выполнить синтаксический разбор инструкции.

В частности, то, что я имел в виду, заключалось в том, чтобы читать в каждой строке входного текстового файла в char array и проверять низкие биты индекса и сравнивать его со строкой для каждой из моих инструкций, но я не думаю, что это хороший метод.

Что такое хороший метод для синтаксического анализа и сравнения?

ответ

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; 
} 
Смежные вопросы