Skip to content
Permalink
Browse files

first steps towards a bad dbc parser

  • Loading branch information...
HubertD committed Dec 25, 2015
1 parent c2c6b38 commit adb658f6f94a18be77f17c7c0d4d6eb9ce7568a1
Showing with 310 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +1 −0 cannelloni.pro
  3. +6 −0 mainwindow.cpp
  4. +223 −0 parser/dbc/DbcParser.cpp
  5. +72 −0 parser/dbc/DbcParser.h
  6. +5 −0 parser/dbc/dbc.pri
@@ -32,3 +32,6 @@ Makefile*
#QtCtreator Qml
*.qmlproject.user
*.qmlproject.user.*


test.dbc
@@ -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)
@@ -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);
@@ -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++;
}
}

@@ -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
@@ -0,0 +1,5 @@
HEADERS += \
$$PWD/DbcParser.h

SOURCES += \
$$PWD/DbcParser.cpp

0 comments on commit adb658f

Please sign in to comment.
You can’t perform that action at this time.