crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Дайте совет, Написал парсер получилось не ООП
FakeMoNEy
  опции профиля:
сообщение 6.7.2013, 15:34
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 7
Регистрация: 27.11.2012
Пользователь №: 3612

Спасибо сказали: 0 раз(а)




Репутация:   0  


Написал небольшой парсер для BSDL файлов, но получилось как-то функционально что ли, я не смог выделить абстракции, к тому же приходится создавать объект парсера, затем вызвать функцию и передавать ему имя файла и объект для того что он разобрал(jtagDevice), мне кажется можно проще или более гибко но не могу придумать как, плюс зачемто унаследовал его от QObject что было лишним это я уберу, с помощью него разбираю отдельно файлы или папки вызывая для каждого файла parse(), еще вопрос как обрабатывать ситуации когда он не нашел чегото, можно ли использовать исключения или они не подходят и это будет избыточным, пока что просто вывожу в консоль если чтото не так, еще не встречал файла с ошибкой.
Вот класс:
Раскрывающийся текст

#include <QFile>
#include <QDir>
#include <QDebug>
#include <QStringList>
#include <QRegExp>
#include "jtagdevice.h"

class parser : public QObject
{
    Q_OBJECT
public:
    explicit parser(QObject *parent = 0);
    bool parse(QString filename,jtagDevice* device);
private:
    QFile* File;
    QString* fileStr;
    jtagDevice* dev;
    bool openFile(QString file);
    void removeGarbage();
    QString extractName();
    QString extractID();
    int extractDRLength();
    int extractIRLength();
signals:
    
public slots:
    
};

#endif
#include "parser.h"
parser::parser(QObject *parent) :
    QObject(parent){
}

bool parser::parse(QString filename, jtagDevice *device){
    File=new QFile(filename);
    File->open(QIODevice::ReadOnly);
    if(!File->exists()){
        qDebug()<<"File not exist"<<filename;
        return false;}

    QString name,ID;
    int IRL,DRL;
    QMap < QString,QString > commands;
    fileStr =  new QString(File->readAll());
    removeGarbage();
    name=extractName();
    ID=extractID();
    IRL=extractIRLength();
    DRL=extractDRLength();
    commands=extractInstructions();
    if(name.isEmpty()||ID.isEmpty()){
        qDebug()<<"name or ID is empty";
        return false;}
    device->setName(name);
    device->setIDBIN(ID);
    device->setDRLength(DRL);
    device->setIRLength(IRL);
    device->setInstructions(commands);

    delete File;
    delete fileStr;

    return true;
}

void parser::removeGarbage(){
    qDebug()<<"garbage";
    QRegExp rx;
    int pos = 0;

    rx.setPattern("(\\-\\-.+\\n)");
    rx.setMinimal(true);
    while ((pos = rx.indexIn(*fileStr, pos)) != -1) { // Убираем комментарии
        fileStr->remove(rx);
        pos += rx.matchedLength();
    }

    pos=0;
    rx.setMinimal(false);
    rx.setPattern("\\s+");
    while ((pos = rx.indexIn(*fileStr, pos)) != -1) { // Убираем повторяющиеся пробелы
        fileStr->replace(pos,rx.matchedLength()," ");
        pos += (rx.matchedLength()-(rx.matchedLength()-1));
    }

    pos=0;
    rx.setPattern("\\r|\\n");
    rx.setMinimal(true);
    while ((pos = rx.indexIn(*fileStr, pos)) != -1) { // приводим все к одной строке
        fileStr->remove(rx);
        pos += rx.matchedLength();
    }
    pos=0;
    rx.setMinimal(false);
    rx.setPattern("\\s*([,:;\"\\)\\]\\(\\[])\\s*");
    while ((pos = rx.indexIn(*fileStr, pos)) != -1) {   // убираем пробелы у разделительных(,.:) знаков
        fileStr->replace(pos,rx.matchedLength(),rx.cap(1));
        pos += (rx.matchedLength()-(rx.matchedLength()-1));
    }

}

QString parser::extractName(){

    QString name;
    int index=fileStr->indexOf(";end ");
    if(index==-1){
        qDebug()<<"Can't find ID. 1";
        return name;}
    index+=5;
    if(fileStr->endsWith(";")){
        while(index!=fileStr->length()-1){
            name.push_back(fileStr->at(index));
            index++;
        }
        return name;}
    else{
        qDebug()<<"Can't find ID. 2";
        return name;
    }


}

QString parser::extractID(){
    QString ID,temp;
    int end;
    int index = fileStr->indexOf("IDCODE_REGISTER",0,Qt::CaseInsensitive);
    if(index==-1){
        qDebug()<<"IDCODE_REGISTER not found. 1";
        return ID;}
    index+=15;
    index=fileStr->indexOf("\"",index,Qt::CaseInsensitive);
    if(index==-1){
        qDebug()<<"IDCODE_REGISTER start not found. 2";
        return ID;}
    end=fileStr->indexOf(";",index,Qt::CaseInsensitive);
    if(index==-1){
        qDebug()<<"IDCODE_REGISTER end not found. 3";
        return ID;}
    while(index!=end){
        temp=fileStr->at(index);
        if(temp=="0"||temp=="1"||temp=="X")
            ID.push_back(temp);
        temp.clear();
        index++;
    }
    return ID;
}

int parser::extractIRLength(){
    QString result;
    int index=fileStr->indexOf("instruction_length",0,Qt::CaseInsensitive);
    if(index==-1){
        qDebug()<<"Can't extract IRLength";
        return -1;
    }
    index+=18;
    index=fileStr->indexOf(";",index,Qt::CaseInsensitive);
    if(index==-1){
        qDebug()<<"Can't extract IRLength";
        return -1;
    }
    index--;
    while(fileStr->at(index).isDigit()){
        result.push_front(fileStr->at(index));
        index--;
    }
    return result.toInt();
}

QMap<QString,QString> parser::extractInstructions(){
    QMap<QString,QString> result;
    QString command,code1;
    int end;
    int index=fileStr->indexOf("instruction_opcode",0,Qt::CaseInsensitive);
    index+=18;
    index=fileStr->indexOf("\"",index,Qt::CaseInsensitive);
    end=fileStr->indexOf(";",index,Qt::CaseInsensitive);
    while(index<end){
        index++;
        while(fileStr->at(index)!='('){
            command.push_back(fileStr->at(index));
            index++;
        }

        index++;
        while(fileStr->at(index)!=')'){
            code1.push_back(fileStr->at(index));
            index++;
        }
        result[code1]=command;
        command.clear();
        code1.clear();
        index=fileStr->indexOf("&",index,Qt::CaseInsensitive);
        index=fileStr->indexOf("\"",index,Qt::CaseInsensitive);
    }
    return result;

}

int parser::extractDRLength(){
    QString result;
    int index=fileStr->indexOf("boundary_length",0,Qt::CaseInsensitive);
    if(index==-1){
        qDebug()<<"Can't extract DRLength";
        return -1;
    }
    index+=15;
    index=fileStr->indexOf(";",index,Qt::CaseInsensitive);
    if(index==-1){
        qDebug()<<"Can't extract DRLength";
        return -1;
    }
    index--;
    while(fileStr->at(index).isDigit()){
        result.push_front(fileStr->at(index));
        index--;
    }
    return result.toInt();
}

И еще вопрос
Допустим есть два класса
class Obj1{
public:
    Obj2(string str, int num);
    int getNumBase();
    string getStrBase();
    virtual int getNumChild();
    virtual string getStrChild();
private:
    string strBase;
    int numBase
};

class Obj2 : public Obj1
{
public:
    Obj2(string str, int num, string str_cild, int num_chuld);
    int getNumChild();
    string getStrChild();
private:
    int numChild;
    string strChild;
};


Мне нужно хранить много экземпляров этих класов, я создал класс хранилище который хранит указатели на базовый класс в векторе, дает доступ к желементам и еще какойто функционал.
Я передаю в вектор указатели на объект так push(new Obj1()) push(new Obj2()).
Соответственно обратно тоже указатель на базовый класс.
Удаляю обьекты в деструкторе хранилища
for(;;)
delete vector[i];

Если комуто не лень скажите пожалуйста
1)Это хорошее решение хранить указатели а не объекты, и удалять их в деструкторе вышеописанным образом
2)Можно ли так использовать наследование как в Obj1 Obj2 или стоит определить виртуальный класс и два наследника(или вобще хранить все в одном и определять тип как пустая строка Str_Child или нет, что в принципе я и собираюсь делать с классами Obj1 Obj2 тк нужно определять тип)
3) Как выбрать хранить указатель на данные (str_Base,str_child) или переменные.
Спасибо всем ответившим и прочитавшим до конца.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 6.7.2013, 19:44
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Правило создания тем:
одна проблема - одна тема

У тебя намешано две две совершенно не связанные проблемы в одной теме.
Создавай для второй проблемы отдельную тему.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 8.7.2013, 9:37
Сообщение #3


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


от QObject наследовать в данном случае не нужно, как мне показалось ))

у Obj1 у тебя странный конструктор - Obj2

1 - хранить указатели в массиве - нормально, главное не забыть подчищать в деструкторе, ну и при удалении отдельного объекта во время работы

2 - не совсем понятен вопрос. Но каскадное наследование возможно, в том числе и виртуальное

3 - зависит от конкретного случая
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 8.7.2013, 13:34
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(FakeMoNEy @ 6.7.2013, 18:34) *
Удаляю обьекты в деструкторе хранилища

для этого деструктор базового класса должен быть виртуальным.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 20.4.2024, 17:42