Форум программистов, компьютерный форум CyberForum.ru

Дайте совет по написанному парсеру - C++

Восстановить пароль Регистрация
 
FakeMoNey
1 / 1 / 1
Регистрация: 27.11.2012
Сообщений: 23
06.07.2013, 18:28     Дайте совет по написанному парсеру #1
Написал небольшой парсер для BSDL файлов, но получилось как-то функционально что ли, я не смог выделить абстракции, к тому же приходится создавать объект парсера, затем вызвать функцию и передавать ему имя файла и объект для того что он разобрал(jtagDevice), мне кажется можно проще или более гибко но не могу придумать как, плюс зачемто унаследовал его от QObject что было лишним это я уберу, с помощью него разбираю отдельно файлы или папки вызывая для каждого файла parse(), еще вопрос как обрабатывать ситуации когда он не нашел чегото, можно ли использовать исключения или они не подходят и это будет избыточным, пока что просто вывожу в консоль если чтото не так, еще не встречал файла с ошибкой.
Вот класс:
Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#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
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#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();
}

И еще вопрос
Допустим есть два класса
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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) или переменные.
Спасибо всем ответившим и прочитавшим до конца.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.07.2013, 18:28     Дайте совет по написанному парсеру
Посмотрите здесь:

C++ Дайте совет :)
C++ Дайте совет по изучению программирования
Дайте совет по оптимизации C++
Разрженные матрицы дайте совет C++
Среда разработки. Дайте совет C++
C++ Профессионалы программирования дайте совет
Дайте совет C++
Дайте совет по продолжению обучения C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

Текущее время: 12:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru