异度部落格

学习是一种生活态度。

0%

QT学习笔记之十五 BooleanParser 基于Qt4的逻辑表达式分析工具

貌似好久没写了,最近比较忙的说,这个主要练习 Model 的设计,部分代码是参考别人的,大牛们不要鄙视啊....

源码最后附上。

部分核心代码如下:

booleanmodel.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef BOOLEANMODEL_H
#define BOOLEANMODEL_H
#include <QAbstractItemModel>
class Node;
class BooleanModel : public QAbstractItemModel
{
Q_OBJECT
public:
BooleanModel(QObject *parent = 0);
~BooleanModel();
void setRootNode(Node *node);
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section,Qt::Orientation orientation, int role) const;
private:
Node *nodeFromIndex(const QModelIndex &index) const;
Node *rootNode;
};
#endif // BOOLEANMODEL_H

booleanmodel.cpp

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
#include <QtCore>
#include "booleanmodel.h"
#include "booleanparser.h"
/**
构造函数,初始化根结点为空
*/
BooleanModel::BooleanModel(QObject *parent) :QAbstractItemModel(parent)
{
rootNode = 0;
}
/**
析构函数,删除根结点
*/
BooleanModel::~BooleanModel()
{
delete rootNode;
}
/**
设置根结点,删除原来根结点,重新设置根结点
*/
void BooleanModel::setRootNode(Node *node)
{
delete rootNode;
rootNode = node;
reset(); //刷新表格数据
}
/**
返回索引,这个是virtual函数所以一定要重载
*/
QModelIndex BooleanModel::index(int row,int column,const QModelIndex &parent) const
{
if (!rootNode || row < 0 || column < 0)
return QModelIndex(); //非法情况
Node *parentNode = nodeFromIndex(parent);
Node *childNode = parentNode->children.value(row);
if (!childNode)
return QModelIndex();
return createIndex(row,column, childNode);
}
/**
返回父亲结点
*/
QModelIndex BooleanModel::parent(const QModelIndex &child) const
{
Node *node = nodeFromIndex(child);
if (!node)
return QModelIndex(); //结点无效
Node *parentNode = node->parent;
if (!parentNode)
return QModelIndex(); //父结点无效
Node *grandparentNode = parentNode->parent;
if(!grandparentNode)
return QModelIndex(); //父结点的父结点无效
int row = grandparentNode->children.indexOf(parentNode);
return createIndex(row,0,parentNode);
}
/**
返回行数,这个也是virtual函数,要重载
*/
int BooleanModel::rowCount(const QModelIndex &parent) const
{
if (parent.column() > 0)
return 0;
Node *parentNode = nodeFromIndex(parent);
if(!parentNode)
return 0;
return parentNode->children.count();
}
/**
返回列数,固定只有2,这个也是virtual函数,要重载
*/
int BooleanModel::columnCount(const QModelIndex & /*parent*/) const
{
return 2;
}
/**
返回数据,这个也是virtual函数,要重载
*/
QVariant BooleanModel::data(const QModelIndex &index, int role) const
{
if (role != Qt::DisplayRole)
return QVariant(); //不是显示角色,认为是无效数据
Node *node = nodeFromIndex(index);
if (!node)
return QVariant(); //结点无效
if(index.column() == 0) {
switch (node->type) {
case Node::Root:
return tr("Root");
case Node::OrExpression:
return tr("OR Expression");
case Node::AndExpression:
return tr("AND Expression");
case Node::NotExpression:
return tr("NOT Expression");
case Node::Atom:
return tr("Atom");
case Node::Identifier:
return tr("Identifier");
case Node::Operator:
return tr("Operator");
case Node::Punctuator:
return tr("Punctuator");
default:
return tr("Unknown"); //默认为未知
}
} else if(index.column() == 1) {
return node->str;
}
return QVariant();
}
/**
返回表头
*/
QVariant BooleanModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
if (section == 0) {
return tr("Node");
} else if (section == 1) {
return tr("Value");
}
}
return QVariant();
}
/**
从索引返回结点
*/
Node *BooleanModel::nodeFromIndex(const QModelIndex &index) const
{
if (index.isValid()) {
return static_cast<Node *>(index.internalPointer());
} else {
return rootNode;
}
}

booleanparser.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef BOOLEANPARSER_H
#define BOOLEANPARSER_H
#include "node.h"
class BooleanParser
{
public:
BooleanParser();
Node *parse(const QString &expr);
private:
Node *parseOrExpression();
Node *parseAndExpression();
Node *parseNotExpression();
Node *parseAtom();
Node *parseIdentifier();
void addChild(Node *parent, Node *child);
void addToken(Node *parent, const QString &str, Node::Type type);
bool matchToken(const QString &str) const;
QString in;
int pos;
};
#endif // BOOLEANPARSER_H

booleanparser.cpp

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
#include <QtCore>
#include "booleanparser.h"
#include "node.h"
BooleanParser::BooleanParser()
{
}
Node *BooleanParser::parse(const QString &expr)
{
in = expr;
in.replace(" ", "");
pos = 0;
Node *node = new Node(Node::Root);
addChild(node, parseOrExpression());
return node;
}
/**
解析或表达式
*/
Node *BooleanParser::parseOrExpression()
{
Node *childNode = parseAndExpression();
if (matchToken("||")) {
Node *node = new Node(Node::OrExpression);
addChild(node,childNode);
while (matchToken("||")) {
addToken(node,"||", Node::Operator);
addChild(node, parseAndExpression());
}
return node;
} else {
return childNode;
}
}
/**
解析与表达式
*/
Node *BooleanParser::parseAndExpression()
{
Node *childNode = parseNotExpression();
if (matchToken("&&")) {
Node *node = new Node(Node::AndExpression);
addChild(node, childNode);
while (matchToken("&&")) {
addToken(node, "&&", Node::Operator);
addChild(node, parseNotExpression());
}
return node;
} else {
return childNode;
}
}
/**
解析非表达式
*/
Node *BooleanParser::parseNotExpression()
{
if (matchToken("!")) {
Node *node = new Node(Node::NotExpression);
while (matchToken("!"))
addToken(node, "!", Node::Operator);
addChild(node, parseAtom());
return node;
} else {
return parseAtom();
}
}
/**
解析一个项
*/
Node *BooleanParser::parseAtom()
{
if (matchToken("(")) {
Node *node = new Node(Node::Atom);
addToken(node, "(", Node::Punctuator);
addChild(node, parseOrExpression());
addToken(node, ")", Node::Punctuator);
return node;
} else {
return parseIdentifier();
}
}
/**
解析标识符
*/
Node *BooleanParser::parseIdentifier()
{
int startPos = pos;
while (pos < in.length() && in[pos].isLetterOrNumber())
++pos;
if (pos > startPos) {
return new Node(Node::Identifier,
in.mid(startPos, pos - startPos));
} else {
return 0;
}
}
/**
添加子结点
*/
void BooleanParser::addChild(Node *parent, Node *child)
{
if (child) {
parent->children += child;
parent->str += child->str;
child->parent = parent;
}
}
/**
添加token
*/
void BooleanParser::addToken(Node *parent, const QString &str,
Node::Type type)
{
if (in.mid(pos, str.length()) == str) {
addChild(parent, new Node(type, str));
pos += str.length();
}
}
/**
token匹配
*/
bool BooleanParser::matchToken(const QString &str) const
{
return in.mid(pos, str.length()) == str;
}

booleanwindow.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef BOOLEANWINDOW_H
#define BOOLEANWINDOW_H
#include <QWidget>
class QLabel;
class QLineEdit;
class QTreeView;
class BooleanModel;
class BooleanWindow : public QWidget
{
Q_OBJECT
public:
BooleanWindow();
private slots:private slots:
void booleanExpressionChanged(const QString &expr);
private:
QLabel *label;
QLineEdit *lineEdit;
BooleanModel *booleanModel;
QTreeView *treeView;
};
#endif // BOOLEANWINDOW_H

booleanwindow.cpp

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
#include <QtGui>
#include "booleanwindow.h"
#include "booleanmodel.h"
#include "booleanparser.h"
BooleanWindow::BooleanWindow()
{
//Label
label = new QLabel(tr("Boolean expression:"));
//LineEdit
lineEdit = new QLineEdit;
//BooleanModel
booleanModel = new BooleanModel(this);
//TreeView
treeView = new QTreeView;
treeView->setModel(booleanModel);
//signal and slot
connect(lineEdit, SIGNAL(textChanged(QString)), this,SLOT(booleanExpressionChanged(QString)));
//Layout
QGridLayout *layout = new QGridLayout;
layout->addWidget(label, 0 ,0);
layout->addWidget(lineEdit, 0 , 1);
layout->addWidget(treeView, 1, 0, 1, 2);
setLayout(layout);
setWindowTitle(tr("Boolean Parser"));
}
void BooleanWindow::booleanExpressionChanged(const QString &expr)
{
BooleanParser parser;
Node *rootNode = parser.parse(expr);
booleanModel->setRootNode(rootNode);
}

其他的可以去下载

下载地址:http://download.csdn.net/source/1529790">http://download.csdn.net/source/1529790

软件截图:

image

PS:最近比较郁闷.....