first steps towards a bad dbc parser

This commit is contained in:
Hubert Denkmair 2015-12-25 22:17:21 +01:00
parent c2c6b38258
commit adb658f6f9
6 changed files with 310 additions and 0 deletions

3
.gitignore vendored
View File

@ -32,3 +32,6 @@ Makefile*
#QtCtreator Qml
*.qmlproject.user
*.qmlproject.user.*
test.dbc

View File

@ -22,3 +22,4 @@ FORMS += mainwindow.ui
include($$PWD/model/model.pri)
include($$PWD/drivers/drivers.pri)
include($$PWD/views/views.pri)
include($$PWD/parser/dbc/dbc.pri)

View File

@ -10,12 +10,18 @@
#include "drivers/socketcan/SocketCanInterfaceProvider.h"
#include "drivers/CanListener.h"
#include "parser/dbc/DbcParser.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
DbcParser parser;
QFile *dbc = new QFile("test.dbc");
parser.parseFile(dbc);
trace = new CanTrace(this, 100);
//model = new LinearTraceViewModel(trace);

223
parser/dbc/DbcParser.cpp Normal file
View File

@ -0,0 +1,223 @@
#include "DbcParser.h"
#include <QTextStream>
#include <stdint.h>
#include <iostream>
DbcParser::DbcParser()
: _pos(0)
{
}
void DbcParser::parseFile(QFile *file)
{
if (!file->open(QIODevice::ReadOnly)) {
// TODO raise cannot open file exception
}
QTextStream in(file);
_str = in.readAll();
parse();
file->close();
}
void DbcParser::parse()
{
_pos = 0;
while (_pos<_str.length()) {
parseSection();
}
}
void DbcParser::skipWhiteSpace()
{
while ((_pos<_str.length()) && (_str[_pos].isSpace())) {
_pos++;
}
}
bool DbcParser::isAtSectionEnding()
{
int mypos = _pos;
while (true) {
if (mypos >= _str.length()) {
return true;
} else if (_str[mypos]==';') {
return true;
} else if (_str.midRef(mypos,4)=="\r\n\r\n") {
return true;
} else if (_str[mypos].isSpace()) {
mypos++;
continue;
} else {
return false;
}
}
}
void DbcParser::skipSectionEnding()
{
while ((_pos<_str.length())) {
if (_str[_pos]==';') {
_pos++;
return;
} else if (_str.midRef(_pos,4)=="\r\n\r\n") {
_pos+=4;
return;
} else if (_str[_pos].isSpace()) {
_pos++;
continue;
} else {
// TODO throw no section ending
return;
}
}
}
void DbcParser::skipColon()
{
skipWhiteSpace();
if (_pos<_str.length()) {
if (_str[_pos] == ':') {
_pos++;
} else {
// TODO throw colon expected
}
}
}
QString DbcParser::readRegExp(const QRegExp &re)
{
if (re.indexIn(_str, _pos)==_pos) {
QString result = re.cap(1);
_pos += result.length();
return result;
} else {
return "";
}
}
QString DbcParser::readString()
{
QRegExp rx("(\".*\")");
rx.setMinimal(true);
skipWhiteSpace();
QString s = readRegExp(rx);
if (s.length()>1) {
return s.mid(1, s.length()-2);
} else {
// TODO throw could not read string exception
return "";
}
}
QString DbcParser::readSectionName()
{
static const QRegExp rx("([A-Z_]+)");
skipWhiteSpace();
return readRegExp(rx);
}
QString DbcParser::readIdentifier()
{
static const QRegExp rx("([A-Za-z_][A-Za-z0-9_]+)");
skipWhiteSpace();
return readRegExp(rx);
}
qlonglong DbcParser::readInteger()
{
static const QRegExp rx("([0-9]+)");
skipWhiteSpace();
QString s = readRegExp(rx);
bool ok;
qlonglong result = s.toLongLong(&ok, 10);
if (ok) {
return result;
} else {
// TODO throw could not read integer exception
return 0;
}
}
void DbcParser::parseSection() {
QString sectionName = readSectionName();
if (sectionName == "VERSION") {
parseSectionVersion();
} else if (sectionName == "NS_") {
parseSectionNs();
} else if (sectionName == "BS_") {
parseSectionBs();
} else if (sectionName == "BU_") {
parseSectionBu();
} else if (sectionName == "BO_") {
parseSectionBo();
} else {
// skip till next section...
while (!isAtSectionEnding()) { _pos++; }
}
/*
if (sectionName == "CM_") { return tokSectionCm; }
if (sectionName == "BA_") { return tokSectionBa; }
if (sectionName == "BA_REL_") { return tokSectionBaRel; }
if (sectionName == "BA_DEF_") { return tokSectionBaDef; }
if (sectionName == "BA_DEF_DEF_") { return tokSectionBaDefDef; }
if (sectionName == "BA_DEF_DEF_REL_") { return tokSectionBaDefDefRel; }
if (sectionName == "VAL_") { return tokSectionVal; }
*/
}
void DbcParser::parseSectionVersion()
{
/*_dbcVersion =*/ readString();
skipSectionEnding();
}
void DbcParser::parseSectionNs()
{
skipColon();
while (!isAtSectionEnding()) {
readIdentifier();
}
}
void DbcParser::parseSectionBs()
{
skipColon();
while (!isAtSectionEnding()) {
_pos++;
}
}
void DbcParser::parseSectionBu()
{
skipColon();
while (!isAtSectionEnding()) {
readIdentifier();
}
}
void DbcParser::parseSectionBo()
{
skipWhiteSpace();
qlonglong can_id = readInteger();
QString msg_name = readIdentifier();
skipColon();
qlonglong dlc = readInteger();
QString sender = readIdentifier();
while (!isAtSectionEnding()) {
_pos++;
}
}

72
parser/dbc/DbcParser.h Normal file
View File

@ -0,0 +1,72 @@
#ifndef DBCPARSER_H
#define DBCPARSER_H
#include <QFile>
#include <QRegExp>
class DbcParser
{
public:
DbcParser();
void parseFile(QFile *file);
private:
typedef enum {
tokInvalid,
tokSectionVersion,
tokSectionNs,
tokSectionBs,
tokSectionBu,
tokSectionBo,
tokSectionSg,
tokSectionBoTxBu,
tokSectionCm,
tokSectionBaDef,
tokSectionBaDefDef,
tokSectionBaDefDefRel,
tokSectionBa,
tokSectionBaRel,
tokSectionVal,
tokIdentifier,
tokInteger,
tokFloat,
tokString,
tokColon,
tokPipe,
tokAt,
tokPlus,
tokComma,
tokParentOpen,
tokParentClose,
tokBracketOpen,
tokBracketClose,
} token_t;
QString _str;
int _pos;
bool isAtSectionEnding();
void skipWhiteSpace();
void skipSectionEnding();
void skipColon();
QString readRegExp(const QRegExp &re);
QString readSectionName();
QString readIdentifier();
QString readString();
qlonglong readInteger();
void parse();
void parseSection();
void parseSectionVersion();
void parseSectionNs();
void parseSectionBs();
void parseSectionBu();
void parseSectionBo();
};
#endif // DBCPARSER_H

5
parser/dbc/dbc.pri Normal file
View File

@ -0,0 +1,5 @@
HEADERS += \
$$PWD/DbcParser.h
SOURCES += \
$$PWD/DbcParser.cpp