Forum: Digitale Signalverarbeitung / DSP / Machine Learning .map file parser


von Adam (Gast)


Lesenswert?

Hallo zusammen,

ich benötige einen Parser für .map files von dsp's. Nun wollte ich 
fragen, ob es hierfür bereits irgendwelche Bibliotheken gibt bevor ich 
damit beginne einen eigenen zu schreiben...

Hat jemand eine Idee?

von Kali (Gast)


Lesenswert?

Formate von map Files sind nicht standardisiert. Falls Du die Chance 
erhöhen willst, einen fertigen Parser dafür zu finden, solltest Du 
Compiler und DSP-Typ nennen.

Andererseits sind diese Formate in der Regel nicht sehr komplex so das 
man relativ schnell mal einen Perl-Script dafür hinschreiben kann. 
Ohnehin, ist die Auswertung der Inhalte dann das eigentlich umfangreiche 
Problem und nicht das parsen. Falls Du mal erklärst was Du auswerten 
willst, hast Du vielleicht Glück und jemand hat sowas schon gemacht.

von Adam (Gast)


Lesenswert?

Danke für deine Antwort,

Es geht um: Pro Audio Development Kit (TMDSPDK6727), 
Entwicklungsumgebund ist das Code Composer Studio 3.3.

Ist ein Parser in C / C++ viel aufwändiger als mit Perl?

von Adam (Gast)


Lesenswert?

Danke für deine Antwort,

Pro Audio Development Kit (TMDSPDK6727), Entwicklungsumgebung ist das 
Code Composer Studio 3.3.

Ist ein Parser in C / C++ viel aufwändiger als mit Perl?

von Entwickler (Gast)


Lesenswert?

Adam schrieb:
> Ist ein Parser in C / C++ viel aufwändiger als mit Perl?

um gefühlte 1000%

von Kali (Gast)


Lesenswert?

>Ist ein Parser in C / C++ viel aufwändiger als mit Perl?

Unter der Voraussetzung das ein map-File zu parsen ist, sehe ich Perl im 
Vorteil (etwa 80% weniger aufwendig), da wegen der geringen 
Kontextsensitivität und der geringen Anzahl von Alternativen und 
Verschachtelungsebenen (im Gegensatz zu z.B. der Programmiersprache C) 
das meiste mit ein paar regulären Ausdrücken zu erledigen ist.

Da ich meine zwischen den Zeilen zu lesen, das Du den Parser hier im 
Vergleich zu der Auswertung der geparsten Daten unterschätzt, noch eine 
Bemerkung: Die nötigen Datenstrukturen (Bäume, Hashes etc.) lassen sich 
mit Perl schneller verwenden als in purem C. (Andererseits gibt es auch 
für C Bibliotheken für solche Sachen). Ich würde für ein map-File 
jedenfalls spontan Perl wählen weil mit regulären Ausdrücken so ein 
Parser schnell hingeschrieben ist.

Wie üblich gibt es in solchen Fällen kein Schwarz-Weiss. In Perl muss 
man sich auch erst einarbeiten. Wenn man C kann, dann ist das sicherlich 
nicht ganz so schwierig, aber Perl hat so seine Eigenheiten, die einen 
auch ein paar Packungen Kaffee kosten können.

von Kali (Gast)


Lesenswert?

Schreibfehler:

Statt

>Da ich meine zwischen den Zeilen zu lesen, das Du den Parser hier im
>Vergleich zu der Auswertung der geparsten Daten unterschätzt ...

muss es heissen

Da ich meine zwischen den Zeilen zu lesen, das Du den Parser hier im
Vergleich zu der Auswertung der geparsten Daten überschätzt ...

von Kali (Gast)


Lesenswert?

Noch eine Ergänzung:

Ich würde für ein map-File jedenfalls spontan Perl wählen weil mit 
regulären Ausdrücken so ein Parser schnell hingeschrieben ist. Das 
eigentlich aufwendige, die Einordnung der Daten in eine sinnvolle 
Struktur (wie die erwähnten Bäume oder Hashes) lässt sich wesentlich 
schneller hinschreiben. Ausserdem ist Perl keine streng typisierte 
Sprache wie C, so das man in 98% der Fälle Typen einfach ignorieren 
kann.

von Adam (Gast)


Lesenswert?

Was für großen Aufwand in der Auswertung der geparsten Daten meinst du 
genau?
Also ich benötige von dem map file eigentlich nur die globalen Variablen 
geparst (in meinem mapfile sind sie alphabetisch und nach 
Speicheradresse sortiert). Zweiteres ist eigentlich sehr praktisch. 
Interessant wären dann noch Der Zeitpunkt wann es gelinkt wurde und 
Modulname etc..

Also im Prinzip möchte ich einfach die Variablennamen + dazugehörige 
Speicheradresse in ein Array parsen, alles weitere sollte dann 
eigentlich machbar sein, hoff ich doch :)

von Kali (Gast)


Lesenswert?

>Was für großen Aufwand in der Auswertung der geparsten Daten meinst du
>genau?

Etwas genaues konnte ich bisher ja nicht meinen, weil mir ja nicht 
bekannt war, auf was hin genau Du das map file untersuchen willst.

>Also ich benötige von dem map file eigentlich nur die globalen Variablen
>geparst (in meinem mapfile sind sie alphabetisch und nach
>Speicheradresse sortiert). Zweiteres ist eigentlich sehr praktisch.
>Interessant wären dann noch Der Zeitpunkt wann es gelinkt wurde und
>Modulname etc..

Aha.

>Also im Prinzip möchte ich einfach die Variablennamen + dazugehörige
>Speicheradresse in ein Array parsen, alles weitere sollte dann
>eigentlich machbar sein, hoff ich doch :)

Was ist denn das weitere nun genau? :-)

Kannst Du (zumindest in Grundlagen) Perl? Wenn ja, könnte man sich mal 
den Spass machen hier schnell was zu hacken und Du machst den Rest. 
Poste dazu mal ein Beispiel eines map file und beschreibe dazu was Du 
damit machen willst. Aber das ich (wir) Dir den kompletten Code machen 
kann ich nicht zusagen.

von Kali (Gast)


Lesenswert?

>>Was für großen Aufwand in der Auswertung der geparsten Daten meinst du
>>genau?

>Etwas genaues konnte ich bisher ja nicht meinen, weil mir ja nicht
>bekannt war, auf was hin genau Du das map file untersuchen willst.

Irgendwie ist das auch keine Antwort. Ob und wie kompliziert das ist, 
hängt natürlich schon davon ab, was Du mit dem Inhalt des Map-Files 
machen willst. Klar. Ich wollte eigentlich nur sagen, das in meiner 
Vorstellung, das parsen im Vergleich zu den Auswertungen fast simpel 
ist, wenn man jedenfalls nicht triviale Auswertungne annimmt.
Willst Du etwa nur die Symbole einlesen, nach Adresse sortieren und 
wieder ausgeben, dann ist das sicherlich einfach und bzgl. der 
Komplexität etwa mit dem Parsen vergleichbar. Willst Du aber etwa prüfen 
ob sich Bereiche überschneiden, oder, Lücken finden oder sowas, dann ist 
das schon etwas komplizierter weil diese Informationen oft nicht 
explizit im Map-File enthalten sind sondern erst berechnet werden 
müssen.

Andererseits werde ich vermutlich nie den Wunsch haben ein Map-File nur 
anders zu sortieren. Mein "Vorurteil", das man nur wegen komplizierter 
Dinge ein Map-File parst mag hier unzutreffend sein. Jeder empfindet ja 
etwas anderes als nötig/unnötig bzw. einfach/kompliziert.

von Adam (Gast)


Lesenswert?

Also ersteinmal danke für dein Engagement, natürlich möchte ich hier von 
niemandem verlangen, dass er mir den ganzen Code programmiert ;) ich 
suche lediglich nach einer Einstiegshilfe. Ich habe 0 Erfahrung mit 
Perl, das ist das Problem...

Also im Prinzip möchte ich einfach die ausgelesenen Globalen Variablen 
zur Laufzeit vom DSP System anfordern und in einer Gui darstellen, sowie 
dessen Werte ändern können. Die Kommunikation zum DSP steht im Prinzip 
schon, muss eventuell nur noch angepasst werden.

Auszug aus mapfile(Also die für mich relevanten Dinge):

************************************************************************ 
******
               blabla Linker PC v8.2.0
************************************************************************ 
******
>> Linked Mon Aug 09 13:48:37 2011

OUTPUT FILE NAME:   <./Debug/bla.out>
ENTRY POINT SYMBOL: 0


GLOBAL SYMBOLS: SORTED BY Symbol Address

address    name
--------   ----
00000008   a
10001c00   b
10001c00   c
10001c00   d
10001c00   e
10001c1c   f
10001c38   g
10001c54   h
........   ...

von Adam (Gast)


Lesenswert?

Würde man in C hauptsächlich scanf() zum parsen verwenden oder?

von Kali (Gast)


Lesenswert?

>Ich habe 0 Erfahrung mit Perl, das ist das Problem...

Hm. Das ist dann so ein Grenzfall weil es scheinbar doch ein einfacher 
Fall von "Auswertung" ist. Na schaun wir mal.

Ich gehe davon aus, das es eigentlich nur darum geht, die Zeilen


00000008   a
10001c00   b
10001c00   c
10001c00   d
...

in eine andere Datei zu extrahieren. Richtig? Das sollte genau 
beschrieben werden!

Schaun wir uns mal so eine Zeile an. Da stehen 8-stellige Zeichenfolgen 
die sich alle als Hex-Zahlen interpretieren lassen. Ist das korrekt? 
Dann eine Folge von drei Leerzeichen. Danach ein einzelnes Zeichen. 
Ungewöhnlich nur einstellige Variablennamen zu benutzen. Ist das ein 
Fake oder eine echte Datei? Ist der Quellcode in C? Ist wichtig für die 
Syntax von Variablennamen. Zeig mal das Gegenbeispiel für Funktionen in 
dem Map-File.

Wie soll dann die Ausgabe aussehen? So eine Liste? Oder umgeformt in 
z.B. eine C initialisierung für ein Array von Strukturen oder was?

So ein Code zum einlesen der Datei sieht dann etwas so aus.
1
open(MYINPUTFILE, "<xxx.map");
2
while(<MYINPUTFILE>)
3
 {
4
 my($line) = $_;
5
6
 chomp($line);
7
8
 if($line =~ /[a-fA-F0-9]+ \w+/) {
9
  print $line, "\n";
10
 }
11
}


Wenn Du Dir mal Perl installierst (ich empfehle ActivePerl) und den Code 
laufen lässt, wirst Du folgendes sehen: Es werden alle Zeilen 
ausgedruckt, die eine beiliebige Folge von Hexadezimalziffern, gefolgt 
von drei Leerzeichen gefolgt von einer beliebigen Folge von Zeichen die 
in Identifieiern erlaubt sind enthalten. "\w" ist eine sogenannte 
Zeichenklasse (die hier etwas oversized ist, aber vermutlich nicht 
wirklich falsch).

von Kali (Gast)


Lesenswert?

>Würde man in C hauptsächlich scanf() zum parsen verwenden oder?

Für sowas ja. Da Du kein Perl kannst wäre das vermutlich zu empfehlen, 
da Du nicht erst noch was neues lernen musst und ja eigentlich nur ein 
paar Infos extrahierst ohne da was kompliziertes auszuwerten.

Ein analoges Beispiel zu dem in Perl wäre etwa (ich lasse mal das 
Dateigedöns weg):
1
if (scanf (infile, "%x   %s", addr, identifier))
2
  printf (outfile, "%s bliblablu %s\n", addr, identifier;

von Kali (Gast)


Lesenswert?

Ich sehe gerade, das es fscanf anstelle von scanf heissen müsste. Ich 
erlaube mir mal schlampig zu sein und mich auf das essentielle zu 
beschränken.

von Kali (Gast)


Lesenswert?

Der Vergleich der Perl mit der C Lösung zeigt einen der Punkte die in 
Perl einfacher zu handhaben sind.

In dem C Beispiel wird vorausgesetzt, das addr und Identifier Datentypen 
sind, die gross genug sind, die grösste vorkommende Adresse und den 
längsten vorkommenden Variablennamen aufzunehmen. Genau dimensionieren 
kann man diese Typen aber streng genommen nur wenn man die 
Syntaxdefinition mit den Limits des Mapfiles kennt, was hier für mich 
und vermutlich auch für Dich nicht der Fall ist.

In Perl aber braucht man diese Grössen nicht anzugeben, weil die 
tatsächliche Speichergrösse während des Programmablaufs angepasst wird.

Deswegen sind so QuickNDirty Scripts besser in Perl zu schreiben während 
effiziente (hier speichereffiziente) Programme besser in C (oder einer 
anderen strenger typisierten Sprache) geschrieben werden.

von Adam (Gast)


Lesenswert?

Also im Prinzip kann name und adresse jeweils als String ausgelesen 
werden. ich will es direkt in einem Array in C++ speichern, bzw. genauer 
gesagt als QString, Oberfläche wird mit Qt gemacht.

struct info
{
   QString name;
   QString adresse;
}

info arrayParsedVariables[anzahl geparster Variablen]

Die Umwandlungen sind dann kein Problem...

Die Variablennamen waren ein fake. Der Quellcode ist in C.

bsp für funktionen:

1002bba0    00000020                   : csl_i2cInit.o 
(.text:csl_section:i2c)
                  1002bbc0    00000020                   : 
csl_mcaspInit.o (.text:csl_section:mcasp)
                  1002bbe0    00000020                   : csl_sysinit.o 
(.text:csl_section:sysInit)
                  1002bc00    00000020                   : 
csl_uhpiClose.o (.text:csl_section:uhpi)


Also da ich von Perl keine Ahnung habe, bin ich eigentlich eher 
abgeneigt, aber wenn es wirklich so geeignet dafür ist, werde ich es mir 
wohl mal anschauen.

Direkt mit C++ zu parsen wär eigentlich auch cool, wobei ein Perl skript 
sicher auch leicht in Qt einzubetten wäre..

Wie oben zu sehen ist bräuchte ich dann noch die Anzahl geparster 
Variablen, aber ich denke das ist dann kein Problem ;)

von Adam (Gast)


Lesenswert?

1002bba0    00000020        : csl_i2cInit.o (.text:csl_section:i2c)
1002bbc0    00000020        : csl_mcaspInit.o (.text:csl_section:mcasp)
1002bbe0    00000020        : csl_sysinit.o (.text:csl_section:sysInit)
1002bc00    00000020        : csl_uhpiClose.o (.text:csl_section:uhpi)

Sorry das layout der Funktionen hat es vorhin zerschossen.. Der Abstand 
der Leerzeichen stimmt nicht , aber ist ja egal..

Funktionen werd ich denke ich sowieso nicht benötigen.

von Kali (Gast)


Lesenswert?

Ja. Wenn Du garkein Perl kannst, dann ist die C-Lösung sicher schneller 
zu implementieren.

>Also im Prinzip kann name und adresse jeweils als String ausgelesen
>werden.

Genau. Die Addresse kannst Du ja, falls Bedarf besteht, später noch in 
ein Integer umwandeln.

Du brauch im Grunde folgendes Gerüst.

1. Map-Datei zum lesen öffnen
2. Eine komplette Zeile lesen
3. "Matchen" mit scanf, resp. sscanf oder fscanf. "%s   %s"
4. Falls Match, dann strucht alloziieren, mitglieder setzen.
5. Falls kein Match, dann nichts weiter
6. Prüfen auf eof
7. Falls kein eof dann Schritt 2.
8. Falls eof, dann Datei schliessen.

Was Dir vielleicht im Wege gestanden haben könnte ist die Vermutung, das 
Du die Syntax der Datei vollständig beschreiben musst, obwohl Du nur 
einen Teil der Inhalte tatsächlich brauchst. Das ist aber nicht 
notwendig. Sowohl das C-Beispiel als auch das in Perl ignorieren die 
uninteressanten Zeilen einfach. Das geht hier, weil eine syntaktische 
Einheit immer komplett mit einer Zeile erledigt ist. (Um die Sprache C 
zu "parsen" könnte man von dieser Annahme nicht mehr ausgehen).

von Kali (Gast)


Lesenswert?

>Der Abstand der Leerzeichen stimmt nicht , aber ist ja egal..

Ich bin mir nicht sicher ob das notwendig ist, denn Du könntest ja sehr 
viel mehr Erfahrung in C und Dateibehandlung haben als erkennbar ist, 
aber...

Hier lauert jedenfalls eine Falle. In C, in dem scanf String musst Du 
genau die Anzahl der Leerzeichen angeben!

Ein regelrechter Parser in C, der ein oder mehr Leerzeichen matchen 
soll, wäre nicht mehr mit (einem einzelnen) scanf zu machen.
(In Perl könntest Du mit den regulären Ausdrücken spezifizieren, das 
mindestens ein, sonst aber beliebig viele Leerzeichen oder auch Tabs 
folgen).

von Kali (Gast)


Lesenswert?

Nur so nebenbei.

Falls Dir an kalten Winterabenden mal langweilig ist, empfehle ich Dir 
das "Drachenbuch" 
http://www.amazon.de/s/ref=nb_sb_noss?__mk_de_DE=%C5M%C5Z%D5%D1&url=search-alias%3Daps&field-keywords=Aho+COmpilerbau&x=0&y=0
Da liest Du unter anderem über Parser.

von Adam (Gast)


Lesenswert?

Vielen Dank für deine Hilfe!

Also ich denke schon das ich es dann in C bzw. C++ parsen werde,...

wie könnte man definieren das beispielsweise erst ab der Stelle

GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name

angefangen werden soll zu parsen?

Ich bin jetzt leider die nächsten zwei stunden offline, werde aber 
später nochmal reinschauen, vielen Dank!

von Kali (Gast)


Lesenswert?

Oder, um einen mehr praxisbezogenen Einstieg zu haben, lies mal die Doku 
zu lex und yacc/bison. Aber das nur nebenbei.

von Kali (Gast)


Lesenswert?

>wie könnte man definieren das beispielsweise erst ab der Stelle
>GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name
>angefangen werden soll zu parsen?

Es kommte in bisschen auf die Umstände an, ob das überhaupt notwendig 
ist.

Ich schriebe ja schon in einem meiner Beiträge:

> Sowohl das C-Beispiel als auch das in Perl ignorieren die uninteressanten > 
Zeilen einfach.

Wie kommt das? Nun, scanf gibt als Rückgabewert die Anzahl der 
"gematchten" Werte. In dem Beispiel sind es zwei. Gibt es nicht zwei 
zurück so liegt keine Zeile der beschriebenen Form vor. In dem 
Codebeispiel wird sie dann einfach ignoriert.

Wenn also in der map-Datei sonst eine Zeilen existieren, die von dem 
scanf-Muster beschrieben werden, dann brauchst Du nichts weiter zu 
prüfen.

Wenn aber, sonst noch Zeilen existieren, die von dem scanf-Muster 
beschrieben werden, die Dich aber nicht interessieren, dann musst Du 
zusätzliche Kriterien finden.

Nehmen wir mal an, dass vor der Zeile

>GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name

Zeilen stehen, die von dem scanf gematcht werden, Dich aber nicht 
interessieren. Dann führst Du einfach ein boolsche Variable z.B. namens 
BISHER_IGNORIERE_ICH_DAS_MUSTER ein. Beim Programmstart ist die auf TRUE 
gesetzt.

Dann schreibst Du eine zusätzliche Prüfung ob die Zeile
>>GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name

auftritt. So
1
if (strcmp(zeile, "GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name") {
2
   BISHER_IGNORIERE_ICH_DAS_MUSTER = False;
3
}

und machst die Prüfung auf die interessante Zeile abhängig von dieser 
Variablen.
1
if (BISHER_IGNORIERE_ICH_DAS_MUSTER == False)
2
  if (scanf (infile, "%x   %s", addr, identifier))
3
    printf (outfile, "%s bliblablu %s\n", addr, identifier;

Ansonsten ignorierst Du einfach weiter alle Zeilen.


In zwei Stunden werde ich wahrscheinlich nicht mehr online sein. Aber 
ich denke, mit ein wenig Nachdenken wirst Du schon alleine weiter 
kommen.

Viel Erfolg.

von Kali (Gast)


Lesenswert?

Da fehlt ein wichtiges "k".

>Wenn also in der map-Datei sonst keine Zeilen existieren, die von dem
>scanf-Muster beschrieben werden, dann brauchst Du nichts weiter zu
>prüfen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.