python preprocessor für C/C++

Du hast eine Idee für ein Projekt?
Manuelh87
User
Beiträge: 36
Registriert: Sonntag 15. März 2009, 16:24

Hi!

Aufgrund eines kürzlich angefangenen Projekt für einen Mikrokontroller kam mir irgendwie der Wunsch nach einem mächtigeren preprocessor als der von C...
Gerade wenn man zum Beispiel konfigurierbare Source Codes haben will, wo der nutzer der Sourcen den Treiber ein wenig an den verwendenten Controller anpassen will ist man da schnell an den Grenzen (z.b. will ich dass schon der preprocessor z.b. die richtige Registereinstellungen für den uart macht und das aber noch portable zw. verschiedenen typen die verschiedene einstellungen haben was irgendwie nach sowas wie arrays und for schleifen verlangt....). natürlich könnt ich einfach ganz normal skripts für diese Dinge verwenden die C Codes erzeugen und das Problem umgehen... das ist aber recht unelegant.

Hier die Idee: den C preprocessor vollständig ersetzten durch ein neues filter... Preprocessor Anweisungen wie #define und #ifdef #if #elif #endif usw. sollen vom neuen filter wie vom c-preprocessor erkannt und verarbeitet werden. Zusätzlich gibt es die Möglichkeit in irgendeiner form python code einzubetten. (z.b. aller <?py:python code?> nach dem vorbild von php und html...) In den eingebetteten python codes soll man auch auf die normalen defines zugreifen können (z.b. in einem globalen dictonary).

Was haltet ihr davon?

Es gibt übrigens schon eine (quick & dirty) implementierung von nur dem python preprocessor allerdings ohne die c-prep. anweisungen zu parsen.. (header die python code enthalten müssen hier mit <?include "dateiname"> includiert werden.) Ich poste heut am abend wenn ich drann denk den code wies bisher ist... er ist leider keine schönheit, ich werd ihn mir aber nochmal vornehmen.. und vielleicht wenn ich hoch motiviert bin versuch ich gleich das mit den #if #endif usw. zu implementieren...
BlackJack

@Manuelh87: Das klingt ein wenig nach Template-System. Hast Du Dir schon die angeschaut die es bereits gibt und wenn ja was spricht dagegen das Rad nicht *nochmal* neu zu erfinden? Cheetah fand ich für so eine Aufgabe schonmal recht nützlich.
lunar

Ich halte davon gar nichts. Anstatt mit der Erfindung eines neuen Präprozessors ein eigentlich längst totes Konzept wieder zu beleben, solltest Du Dich lieber nach Alternativen umsehen. Im Falle von C ist diese Alternative der Wechsel zu einer mächtigeren, ausdrucksstärkeren Sprache, die Metaprogrammierung beherrscht, im Falle von C++ sind Templates die Alternative. Von ganz wenigen Ausnahmen abgesehen können Templates alles, was der Präprozessor auch kann, aber eben auch einiges mehr.

PS: Es gibt kein C/C++, es gibt nur C und C++ :)
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Für längst nicht jeden Prozessor gibt es einen Compiler für C++. Geschweige denn Compiler für andere Sprachen. Insofern halte ich die Idee gar nicht für so dumm.
Manuelh87
User
Beiträge: 36
Registriert: Sonntag 15. März 2009, 16:24

Okay... die quick & dirty source codes sind mal online [url]git://github.com/boon-code/pyprep.git[/url] bzw. http://github.com/boon-code/pyprep


Von ganz wenigen Ausnahmen abgesehen können Templates alles, was der Präprozessor auch kann
Ja ich find ja auch das Templates ne nette Sache sind... aber ich wüsst jetzt nicht wie ich soetwas wie verschiedene uart einstellungen durchrechnen und die beste verwenden kurz und schlank mit templates realisieren könnte.

Man kann diese Spielereien sicher mit großem Aufwand auch mit dem normalen preprocessor machen, oder irgendwie wahrscheinlich auch mit templates... aber da python so schön kompakt zu schreiben ist dacht ich mir, wäre es mir sehr recht wenn ich alle möglichen berechnungen und konfigurationen welche nicht zur laufzeit zu machen sind mit python erledigen könnte...

Ich muss gestehen ich bin mir grad nicht sicher ob es nen c++ compiler für avrs gibt... ich glaub da ist nur ein c-compiler wobei es glaub ich an den biliotheken scheitert (iostream usw zu fett...) aber weiß ich grad echt nicht. aber ich glaub ich wollt mal c++ verwenden und es ging nicht.. k.a.

@BlackJack:
Cheetah hab ich mir jetzt kurz angesehen... naja ich glaub dass es nicht dafür gedacht ist z.b. ebenfalls diese defines zu verarbeiten... aber korrigier mich wenn ich falsch liege


Generell ist noch zu sagen dass die source codes bitte noch nicht alle oben beschriebenen features hat... bei weitem nicht... mir ist noch garnicht so klar wie ich das ganze designen soll...

mfg Manuel
BlackJack

@Manuelh87: Was meinst Du mit "diese defines zu verarbeiten"?

Mit den meisten Python-Template-Engines kannst Du recht einfach beliebige Textdateien aus Vorlagen und Python-Code erzeugen. Wobei Schleifen und bedingte Anweisungen in der Regel direkt von der Template-Sprache zur Verfügung gestellt werden. Alles was nicht in der Template-Sprache geht, muss man dann in Python schreiben. Wobei es von Template-Engine zu Template-Engine variiert, ob man das Python direkt in das Template schreiben darf oder ob man es in eigene Module schreiben muss. Letzteres finde ich besser, denn dann wird das alles ein wenig sauberer und wiederverwendbarer. Ausserdem möchte ich bei sachen die etwas komplexer sind, ganz gerne Syntaxhighlighting, und das ist bei "gemischten" Quelltexten immer so eine Sache.

Und was Du da gerade machst, ist recht offensichtlich eine *weitere* Template-Engine. Ohne dass Du Dich ausführlich mit dem beschäftigt hast, was es schon gibt.

Dein Beispiel ist IMHO komisch. Dieses zusammenbasteln von Namen ist in normalen Python-Programmen schon keine gute Idee und das wird sie auch in Templates nicht. Warum nicht in der `main.c` ein Dictionary `TIMER_PRESCALER_SETTINGS` anlegen und das dann in den inkludierten Templates mit Werten füllen!?

Statt zu prüfen ob der Name existiert, hättest Du auch einfach den `KeyError` abfangen können. Und `found` ist überflüssig, weil Du ja schon mit ``break`` arbeitest, dann kannst Du auch gleich ``else`` verwenden. Andererseits ist es total umständlich was Du da machst. Über die Schlüssel eines Dictionaries zu iterieren um an den Wert zu kommen!? Warum!?

Mit Cheetah könnte das so aussehen (hal.h):

Code: Alles auswählen

#include "some-other-file.h"

// user section:
#+set $TIMER_RATE = 5000
#+set $TIMER_ID = 1
#+set global $TIMER_PRESCALER_SETTINGS = $dict()

// code section (don't modify)
#+include 'timer1.h'
#+include 'timer2.h'

#+set $pre = $TIMER_PRESCALER_SETTINGS.get($TIMER_ID)
#+if $pre
    #define init_timer() (TM${TIMER_ID}CRA1 = $pre[$TIMER_RATE])
#+else
    #error  no prescaler setting found
#+end if

#define SOME_OTHER_THING
Dabei ist jetzt der Präfix von Cheetah-Direktiven '#+' statt '#', damit man weiterhin welche für den C-Präprozessor in die Templates schreiben kann.

Und die `timer1.h` sähe dann so aus:

Code: Alles auswählen

#+set global $TIMER_PRESCALER_SETTINGS[1] = {5000: 0x14, 600: 0x20}

// some other code
Manuelh87
User
Beiträge: 36
Registriert: Sonntag 15. März 2009, 16:24

Ja ich weiß, mein Beispiel ist wirklich nicht das beste... Mehr ist mir am Abend leider nicht eingefallen...
Das ganze war ja nur ein Beispiel.... Und beim schreiben ist mir schon aufgefallen was alles noch wichtig wäre zu implementieren und was ich mir noch alles überlegen sollte...

Naja wegen Cheetah: Du hast nicht ganz richtig wenn du sagst ich hab nicht nachgesehen ob es soetwas gibt was ich gerne hätte.. hab ich, gibts nicht.
Dabei bin ich allerdings nicht auf Cheetah gestoßen, ich hab aber nicht das gefühl dass ich damit erreichen kann, was ich will...

Versteh mich nicht falsch, aber ich hab das Gefühl verwende ich Cheetah muss ich mich an die gegebenheiten anpassen, kompromisse machen, dabei wird kaum das rauskommen was mir vorschwebt...

1. Das ganze soll wenig overhead erzeugen und halbwegs einfach zu lesen sein (ich geb zu dass trifft jetzt noch nicht auf mein gebilde da zu)
For jeden Befehl irgendwelche zeichen machen zu müssen fänd ich recht lästig und dient jetzt nicht unbedingt der lesbarkeit... ich find soetwas wie bei php recht gut (kann cheetah mir das bieten?) ich mein wenn ich mir den code durchlese muss ich immer schauen: ist dass grad ein befehl, ist das ein normales define... das ganze ist recht unübersichtlich... während bei php ist es für mich wesentlich besser getrennt...

2. Ich will dass man von dem eingebetteten python code auch die defines 'sehen' kann... nicht dass es quasi 2 preprocessoren sind die über den code fahren und jeder wertet seine dinge aus, sondern dass der pyprep drüberfährt und man aber auch auf die gefundenen defines zugreifen kann (eben aus einem globalen dictonary heraus so wie $_GET bei php)... trotzdem fährt nachher der C preprocessor nochmal extra drüber... aber es soll jetzt nicht für jedes define das eingebettete python benutzt werden... der syntax von C soll schon so bleiben wie mans gewohnt ist, und die dinge die man bisher mit defines gut machen konnte, soll man auch weiterhin so machen... geht es also nur darum, irgendwelche switches zu sezten (compiliere mit feature xx oder ohne) soll man weiterhin ganz normal defines verwenden können... aber man soll eben auch aus dem eingebetteten python code z.b. nachsehen können ob das feature xx vorher gesetzt wurde... ich will quasi den c preprocessor nur ergänzen...

Aus den Beispieln von cheetah konnte ich leider nicht so ganz schließen was alles möglich ist, aber wie gesagt ich will mich eben nicht auf ein system anpassen müssen, sondern ich will mein system umsetzten....

wenn ich erreichen kann dass cheetah alles zwischen <?py: und ?> wie python code ausführt und dass man dann in irgendeiner form nachsehen kann im code ob ein #define gesetzt ist (oder z.b. auch den wert auslesen) kann dann hast du recht und ich sollt es wirklich verwenden... aber ich will nunmal keine kompromisse eingehen müssen... auf jeden fall will ich das zwischen <?py und ?> wirklich python code steht und nicht irgendwas zwischen python code und nochwas...

Wie gesagt, ich habs mir nicht im Detail angesehen, aber ich hab das Gefühl dass ich das nicht mit cheetah erreichen kann.

Nichts für ungugt ich bin wirklich dankbar für Tipps (auch wenn das vielleicht grad nicht den anschein hat...)
BlackJack

@Manuelh87: Welche Template-Engines hast Du denn evaluiert?

Ad 1) Das man vor jeden Befehl ein Zeichen setzen muss ist *gut* denn so kann man die beiden Sprachen besser auseinanderhalten aber gleichzeitig auch stärker vermischen. Man hat nicht Blöcke von einer Sprache in einer anderen und kann sich viel besser das Endergebnis vorstellen als bei einem Block in einer Sprache bei der Text mittels ``print`` oder `echo()` erzeugt wird, dessen Struktur man gar nicht richtig sehen kann. Das ist ja gerade einer der Nachteile bei PHP der selbst PHP-Programmierer dazu bringt Template-Engines zu verwenden, obwohl PHP selbst ja schon so etwas in der Richtung ist.

Ad 2) Dann solltest Du einen C-Präprozessor erweitern. Du müsstest den ja sonst in Python komplett nachbauen um überhaupt herauszufinden welche ``#define``\s eigentlich gesetzt sind und auf welchen Wert. Denn die können ja wiederum von Bedingungen abhängig sein. Sogar von welchen die compilerabhängig sind. Zum Beispiel wenn auf ein Makro getestet wird, welches von einem bestimmten Compiler gesetzt wird.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Manuelh87 hat geschrieben:wenn ich erreichen kann dass cheetah alles zwischen <?py: und ?> wie python code ausführt und dass man dann in irgendeiner form nachsehen kann im code ob ein #define gesetzt ist (oder z.b. auch den wert auslesen) kann dann hast du recht und ich sollt es wirklich verwenden... aber ich will nunmal keine kompromisse eingehen müssen... auf jeden fall will ich das zwischen <?py und ?> wirklich python code steht und nicht irgendwas zwischen python code und nochwas...
Auja, Python-Code direkt in C-Code einbetten der zur Compilezeit ausgeführt wird. Zum Glück erkenne ich eine schlechte Idee, wenn ich sie sehe.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Manuelh87
User
Beiträge: 36
Registriert: Sonntag 15. März 2009, 16:24

@Leonidas: Ich erkenne nutzlose Meldungen, wenn ich sie lese, prahl ich deswegen rum :wink:

@BlackJack: naja gar keine, das ist für mich sofort ausgeschieden, da es viel zu speziell ist was ich gerne hätte... ich hab nachgesehen ob es soetwas in die Richtung schon gibt... hab aber nix gefunden...
1) naja bei php seh ich das problem wo anders... einfach nur zeilen wo man irgendwelche texte einsetzt find ich nicht kompliziert, dass problem ist meines erachtens, dass man den eigentlichen funktionalen code möglichst vom design abkoppeln will und soll... Das Programm soll ja auch nicht genutzt werden wo es nicht notwendig ist... aber gerade für diese low-level treiber dinge wo verschiedene hardware im spiel ist halt ich soetwas für praktisch. Und ich finde einfach mit template engines quasi eine neue sprache zu basteln ist sinnlos, da sich dann genau ein mensch damit auskennt, nämlich der der die reglen festlegt... ich will was allgemein verwendbar und lesbares schaffen. Bei mir muss man lediglich python noch können. Beherrscht man das, kann man das system recht schnell nutzten ohne zuerst docus durchakkern zu müssen wie ich jetzt dieses individuelle system verwenden soll. Korrigier mich wenn ich falsch lieg, aber so würd ich das sehn.

2) Ja! Es bedeutet ich muss im prinzip den C Präprozessor ersetzten! Vollkomment richtig... Und natürlich unterliegt dass dann gewissen einschränkungen... aber das find ich nicht weiter schlimm, man kann halt genau die compiler abhängigen defines nicht auswerten...

Es ist ja in Moment nur eine Idee... ich weiß noch nicht wie es am besten wäre das umzusetzten... Aber ich bin echt erschüttert über die begrenzte vorstellungskraft hier im forum. Es gibt doch viel ansätzte wie man das problem lösen könnte... ich hab ja sogut wie alles in der hand... ich kann die eingebetteten python codes nochmal vorher parsen, dann mit defines ersetzten und den Präprozessor das auswerten erledigen lassen... für jedes define direkt den code so vorbereiten dass das auswerten den richtigen C code erzeugt... Seit doch nicht so engstirnig...

Ich geb schon zu dass es seine tücken hat, aber dass macht doch auch den Reiz aus... sonst könnt ich ja gleich nurmehr Hallo Welt Programme schreiben...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Manuelh87 hat geschrieben:@Leonidas: Ich erkenne nutzlose Meldungen, wenn ich sie lese, prahl ich deswegen rum :wink:
Na also wenn du sinnvolle Tipps ausschlagen willst, dann kann man dir halt schlecht helfen.
Manuelh87 hat geschrieben:naja gar keine, das ist für mich sofort ausgeschieden, da es viel zu speziell ist was ich gerne hätte...
Ich habe keine angeschaut aber weiß, dass keine passt? :roll:
Manuelh87 hat geschrieben:2) Ja! Es bedeutet ich muss im prinzip den C Präprozessor ersetzten! Vollkomment richtig... Und natürlich unterliegt dass dann gewissen einschränkungen... aber das find ich nicht weiter schlimm, man kann halt genau die compiler abhängigen defines nicht auswerten...
Es ist also ok, wenn perfekt gültiger C Code bei dir nicht kompiliert? Also du solltest zumindest unbekannte ``defines`` durch den "richtigen" Präprozessor laufen lassen um die aufzulösen.
Manuelh87 hat geschrieben:Es ist ja in Moment nur eine Idee... ich weiß noch nicht wie es am besten wäre das umzusetzten... Aber ich bin echt erschüttert über die begrenzte vorstellungskraft hier im forum. Es gibt doch viel ansätzte wie man das problem lösen könnte... ich hab ja sogut wie alles in der hand... ich kann die eingebetteten python codes nochmal vorher parsen, dann mit defines ersetzten und den Präprozessor das auswerten erledigen lassen... für jedes define direkt den code so vorbereiten dass das auswerten den richtigen C code erzeugt... Seit doch nicht so engstirnig...
Das hat weniger was mit Engstirnigkeit und mehr mit Erfahrung zu tun. In der Regel schrillen die Alarmglocken wenn man sich seine eigene Template-Engine, sein eigenes Buildsystem oder sein eigenes VCS schreibt.

Gerade für dein Problem würde ich bei C eher darauf zurückgreifen eine Art ``config.h`` zu generieren (meinetwegen auch mit Python) die die Konfiguration enthält. Was gefällt dir denn an diesem Ansatz nicht, den so ziemlich von allen genutzt wird? Die Autotools sind ja extra dafür da, so eine Konfiguration zu bauen und haben den Vorteil dass sie universell unterstützt sind - und wenn sie dir nicht gefallen gibt es ebenfalls CMake, dass ebenfalls inzwischen einige Verbreitung gefunden hat.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@Manuelh87:

Ad 1) Du findest Templates hier sinnlos willst aber selber so etwas schreiben!? Denn letztendlich machst Du doch genau das. Und wenn es lesbar sein soll, dann solltest Du eben *nicht* den Weg von Codeblöcken gehen, die an der Stelle wo sie stehen Quelltext ausspucken, welcher an der Stelle in den C-Quelltext eingesetzt wird. Wenn das nämlich ein wenig komplexer wird, ich denke da an automatisch generierte Strukturen und vielleicht sogar dazu passende Funktionen, dann kann sich kein Mensch mehr durch anschauen des Python-Quelltextes vorstellen wie der davon generierte C-Quelltext aussehen mag. Bei Templates kann man da in der Regel besser die Struktur erkennen, die am Ende herauskommt. Und man kann auch erst einmal den C-Quelltext oder Teile davon so hinschreiben wie er später erzeugt werden soll und das dann Schritt für Schitt in ein Template umbauen.

Und statt durch Template-Engine-Doku muss man bei Deinem System halt die Doku zu Deinem System durchlesen.

Ad 2) Dann solltest Du vielleicht damit anfangen und erst einmal den C-Präprozessor in Python nachbilden. Wenn Du das nicht komplett machst, dann fällt das ganze spätestens auf die Nase wenn Standardheader eingebunden werden, denn da wird bei den Compilern die ich so kenne recht reger Gebrauch vom C-Präprozessor gemacht.

Mein Problem, und wenn ich den Kommentar richtig deute auch das von Leonidas, ist nicht begrenzte Vorstellungskraft, sondern im Gegenteil, dass wir uns das nur zu gut vorstellen können. Und das ist halt keine schöne Vorstellung. Ich habe auch den Verdacht das *Du* entweder nicht die Vorstellung hast was Deine Konstrukte semantisch bedeuten sollen, oder noch nicht die ganzen Fälle bedenkst, die so auftreten können. Mal was ganz einfaches:

Code: Alles auswählen

#ifdef __cc65__
    #define FOO 42
#else
    #define FOO 23
#endif

/* 1 */

#if (FOO - 12) * 10 == 100
    #undef FOO
#endif

/* 2 */
An der Stelle der beiden Kommentare sollte Dein Präprozessor den Wert von `FOO` kennen, oder? Bevor das nicht funktioniert, solltest Du IMHO gar nicht erst über das *Erweitern* nachdenken. Also ich finde es ja einfacher etwas zusätzlich zum C-Präprozessor zu schreiben, statt den neu zu implementieren und zu erweitern. Und wenn ich ihn neu implementieren wollte, würde ich mir als erstes mal den C-Standard schnappen und den entsprechenden Teil lesen. Denn Standardkonform sollte Deine Erweiterung schon sein. Sonst kannst Du nicht mehr beliebige Header-Dateien von Bibliotheken verwenden, insbesondere auch die von der Standardbibliothek nicht.
Manuelh87
User
Beiträge: 36
Registriert: Sonntag 15. März 2009, 16:24

Wie überheblich muss man eigentlich sein? Was denkt ihr denn? Dass ich mir das schnell am Abend ausgedacht hab und sofort hier poste ohne mir was überlegt zu haben. Meint ihr, dass ihr sofort alle Aspekte davon besser beurteiln könnt als ich, der sich ausführlich damit beschäftigt hat.
Na also wenn du sinnvolle Tipps ausschlagen willst
Ja, sinnvoller Tip, durch schlüssige Argumentation, vollkommend richtig... Du hast dich auch so eingehend damit beschäftigt. Wieviele Sekunden hast du dir überlegt was nötig wäre um so etwas umzusetzten und ab wann hast du beschlossen dass es unmöglich ist? Du lässt mich wohl bewusst an deinen Überlegungen nicht Teilhaben, da ich ja sowieso nicht in der Lage bin diese komplexen Vorgänge die da bei dir ablaufen nachzuvollziehen... richtig?
Ich habe keine angeschaut aber weiß, dass keine passt?
Hab ich doch schon erklärt... ist von vornherein ausgeschieden da es die Anforderungen wohl nicht erfüllen wird, außer ich bilde den c-präprozessor nach und zusätzlich auch noch den python interpreter... Tolle Idee! Aber ich lass mich gerne von deiner unglaublichen Erfahrung belehren wenn du so gütig wärst und mir ein template system nennst mit dem genau das möglich ist, der aufwand aber trotzdem geringer als mit meinem Ansatz.
Es ist also ok, wenn perfekt gültiger C Code bei dir nicht kompiliert? Also du solltest zumindest unbekannte ``defines`` durch den "richtigen" Präprozessor laufen lassen um die aufzulösen.
Es wäre für mich eine mögliche Lösung diese Einschränkung zu akzeptieren. Wenn du meine vorher vorgeschlagenen Lösungsmethoden aber mal genau angesehen hättest, würdest du merken, dass es mit diesen Methoden durchaus möglich wäre, diese defines richtig zu verarbeiten...
Ich sag ja nicht dass ich schon jede einzelne Möglichkeit genau kenne und abgewogen hab, aber prinzipiell scheint mir das ganze Umsetztbar...
Das hat weniger was mit Engstirnigkeit und mehr mit Erfahrung zu tun. In der Regel schrillen die Alarmglocken wenn man sich seine eigene Template-Engine, sein eigenes Buildsystem oder sein eigenes VCS schreibt.
Ja, denn das ist ja auch unmöglich... es gibt ja auch keine Buildsysteme VCS's und Template Engines... das folgt ja unmittelbar darauß...
Fakt ist, ich hab ja auch gar nicht vor irgendwas davon zu machen. Dauernd erklärt mir hier einer dass ich doch ein Template System machen will... Nein! Wo bitte sag ich dass... ich will ein konkretes Problem lösen, nämlich ein filter entwerfen, dass es ermöglicht, python code in C Dateien zu haben, welcher ausgewertet wird. Zusätzlich soll es die Möglichkeit geben, auch auf #defines zugreifen zu können, was dafür sorgen soll, dass man jetzt nicht überall wo vorher präprozessordirektiven standen python code schreiben muss... Das ist keine Template-Engine...
Gerade für dein Problem würde ich bei C eher darauf zurückgreifen eine Art ``config.h`` zu generieren (meinetwegen auch mit Python) die die Konfiguration enthält. Was gefällt dir denn an diesem Ansatz nicht, den so ziemlich von allen genutzt wird? Die Autotools sind ja extra dafür da, so eine Konfiguration zu bauen und haben den Vorteil dass sie universell unterstützt sind - und wenn sie dir nicht gefallen gibt es ebenfalls CMake, dass ebenfalls inzwischen einige Verbreitung gefunden hat.
Ja danke! Darauf dass das möglich ist hab ich ja schon hingewiesen... Aber was ist leichter? Direkt im source-code 3 zeilen eingebettetes Python (mit kommentaren) zu haben die z.b. die richtige uart einstellung herausfinden und den wert für irgendein Config-Register herausschreiben, oder ein externes skript, dass erst die eigentliche datei generiert und dementsprechend aussieht?? natürlich kann man das halbwegs intelligent machen, aber es ist auf jedenfall schwieriger nachzuvollziehen als das direkte.. aber du kannst mir ja argumentativ erklären warum ich das nicht richtig sehe...
Und statt durch Template-Engine-Doku muss man bei Deinem System halt die Doku zu Deinem System durchlesen.
Ja, nur das ich den Syntax nicht erklären muss.. lediglich 3-4 Methoden die der Nutzer verwenden kann...
Mein Problem, und wenn ich den Kommentar richtig deute auch das von Leonidas, ist nicht begrenzte Vorstellungskraft, sondern im Gegenteil, dass wir uns das nur zu gut vorstellen können. Und das ist halt keine schöne Vorstellung. Ich habe auch den Verdacht das *Du* entweder nicht die Vorstellung hast was Deine Konstrukte semantisch bedeuten sollen, oder noch nicht die ganzen Fälle bedenkst, die so auftreten können.

Naja anstatt ein sinnloses Beispiel zu geben was man nicht alles dämliches mit dem Präprozessor machen kann, könntest du dir ja auch überlegen wie man genau dieses Problem umgehen kann... und das nenne ich mangelnde Vorstellungskraft... zum "Nein das geht nicht" sagen gehört nicht viel. Zum "so könnte es gehen" gehört viel mehr.
Du hast soeben erkannt, dass der Weg mit dem Präprozessor schwierig werden könnte... das hab ich auch und zwar hier:
ich hab ja sogut wie alles in der hand... ich kann die eingebetteten python codes nochmal vorher parsen, dann mit defines ersetzten und den Präprozessor das auswerten erledigen lassen... für jedes define direkt den code so vorbereiten dass das auswerten den richtigen C code erzeugt
Die erste Variante bringts wahrscheinlich auch nicht wirklich... die 2. Variante klingt für mich ganz brauchbar. Gut, das bedeutet natürlich gewisse Einschränkungen, aber prinzipiell könnte das doch klappen?
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Zeig uns lauffähigen Code, alles weitere diskutieren ist sinnlos.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wenn ich mir das gepostete Beispiel einmal angucke, fällt mir da nichts dran auf, was man nicht mit einer Template-Engine (wie z.B. jinja2) lösen könnte.

Insofern wäre es schon einmal interessant, genau zu definieren, was das ganze können soll. Evtl. durch kleine Beispiele o.ä. Davon ausgehend könnte man dann ableiten, ob man mit einer Template-Engine auskommt oder nicht.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ideen und Visionen sind ja gut, aber vielleicht solltest du bei all deiner Vorstellungskraft auch mal ein bißchen mehr zu Papier bzw Code bringen. ;)
BlackJack

@Manuelh87: Ich hatte bis jetzt in der Tat den Eindruck, dass Du Dir das mal eben so ausgedacht, aber nicht zuende gedacht hast. Und dann eben mal schnell was hingehackt, was nicht im Mindesten den schwierigen Teil Deiner Anforderungen erfüllt. Es wird ein Problem gelöst, das eigentlich keines ist, weil das noch mit dem C-Präprozessor erledigt werden könnte. Und das auch noch mit absolut gruseligem Python-Quelltext.

Wieso sollte aus dem Umstand, dass die Alarmglocken schrillen wenn man seine eigene Template-Engine, sein eigenes Buildsystem oder VCS schreiben will, unmittelbar daraus folgen, dass es diese Dinge nicht gibt!? Gerade *weil* es sie schon gibt, sollte man sich gut überlegen das Rad noch einmal zu erfinden.

Python-Code in C eingebettet ist nicht leichter nachzuvollziehen als das extern zu machen. Das Syntax-Highlighting stimmt nicht, oder immer nur für eine der Sprachen. Und man muss den Python-Quelltext im C-Quelltext auch erst einmal finden. Desweiteren hat man dann in einer Datei sowohl Code der zur Übersetzungszeit ausgeführt wird, als auch welchen der zur Laufzeit des späteren Programms ausgeführt wird. Wenn man das getrennt macht, ist es leichter das auseinanderzuhalten. Und die Interaktion mit dem C-Präprozessor muss man auch nochmal klären. Zu welchem Zeitpunkt passiert was? Was passiert mit Präprozessoranweisungen, die vom Python-Code erzeugt werden? Wann werden die ausgewertet? Wenn der ein ``#define`` ausspuckt, ist dessen Wert dann ab dem Zeitpunkt in folgenden Python-Codeblöcken bekannt? Weisst Du wie einfach oder auch aufwending das jeweils zu implementieren ist? Diese Sachen musst Du Dokumentieren, das ist also etwas mehr Doku als nur die Syntax.

Ich habe kein sinnloses Beispiel gezeigt was man alles dämliches mit dem C-Präprozessor machen kann. Solche Sachen kommen in freier Wildbahn tatsächlich vor. Ich rate Dir nochmal Dich in Header-Dateien von Compilern und Bibliotheken umzusehen. Da gibt's haufenweise bedingte ``#define``\s und auch ``#undef``\s und auch Rechnungen habe ich schon öfter gesehen. Gerade im Embedded-Bereich, zum Beispiel um irgendwelche Grössen auszurechnen und anhand derer zu entscheiden in welche Speicherbank bestimmte Daten am Ende geladen werden sollen. Da wären wir wieder bei fehlender Vorstellungskraft Deinerseits. ;-)

Ich habe übrigens nie gesagt "Nein das geht nicht", sondern "das macht in meinen Augen keinen Sinn". Du bist es von der falschen Seite angegangen. Was Du da gemacht hast, sieht nach billigem Template-System aus. Du musst aber Deine Idee in einen C-Präprozessor integrieren, und dazu müsste man den halt mal schreiben. Das ist nicht unmöglich, macht aber Arbeit. Und der sollte besser standardkonform sein, denn sonst hast Du ein System, das nicht mehr alle Quellen übersetzen kann, die auf den C-Standard setzen. Damit wär's für die Tonne.

Und Du hast IMHO immer noch nicht den Vorteil gezeigt, den der ganze Aufwand am Ende bringen soll. Solange Du nicht ein überzeugendes, durchdachtes Beispiel zeigen kannst, statt dem hingeklatschten, überkomlizierten Beispiel mit dem absolut gruseligem eingebetteten Python-Quelltext, den Du uns da bisher zugemutet hast, wirst Du kaum jemanden überzeugen können. Wenn ich meine Vorstellungskraft bemühe und aus dem extrapoliere was da zu sehen ist, wünschte ich mir deutlich weniger Phanasie zu haben. :twisted:
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich finde ja, jeder sollte das "Recht" haben, jedes Stück Software bauen zu dürfen, egal ob es das schon X-mal gibt oder nicht. Somit wäre es doch eine nette "Fingerübung", einen syntaktisch zu cpp kompatiblen Präprozessor zu in Python zu bauen. Ebenso könnte man natürlich eine der 10+ Template-Sprachen aus der Python-Web-Entwicklung benutzen. Oder dies hier: http://ray.cg.tuwien.ac.at/rft/Papers/PYM/pym.html oder mal hier rauf gucken: http://pyparsing.wikispaces.com/message ... me/2706592

Der Quelltext auf github scheint mir noch Optimierungspotential zu haben. Auch kann er noch nicht die bekannten C-Präprozessoranweisungen umsetzen. Die halte ich für aufwendiger als jetzt noch eine weitere Anweisung für das Ausführen von Python-Code mittels eval() einzubauen. Der Tipp, einfach mal zu versuchen, die normalen (Linux) C-Header-Dateien erfolgreich zu parsen scheint mir ein guter Tipp und Testfall zu sein.

Stefan
BlackJack

@sma: Das Recht will ich niemandem absprechen. Wenn die Ausgangslage gewesen wäre, dass jemand einen erweiterbaren C-Präprozessor als Fingerübung schreiben möchte, wäre meine Reaktion auch anders gewesen.

Bei dem PyParsing-Link steht zwar “Ich brauche einen C-Präprozessor” in der Betreffzeile der Beiträge, aber das entwickelt sich ja eher zu einem C-Parser. Von den Strukturen von C hat der C-Präprozessor keine Ahnung, der ist da doch etwas einfacher gestrickt also wohl einfacher umzusetzen.

Für's Testen einer eigenen Implementierung eines C-Präprozessors könnte man bei OpenSource C-Compilern nach Testfällen schauen.
Manuelh87
User
Beiträge: 36
Registriert: Sonntag 15. März 2009, 16:24

Ok... sry, das läuft hier glaub ich in die falsche Richtung.. war die letzte Woche auch leider recht unter Druck... also tut mir leid wenn ich ein bisschen harsch war...

Okay, wo soll ich anfangen? Also mal das mit dem Syntax hervorheben... tschuldige aber das ist ein schlechtes argument, muss man halt anpassen, bei vielen editoren ist das sicherlich möglich.. es geht ja auch für php...

Ein Konfigfile das den GESAMTEN Quellcode erstellt ist ja wohl sicher keine gute Lösung... sicher wenn ich nur ein zwei defines berechnen will, dann geht das, aber was ist wenns komplizierter wird?? Dann müsst ich da ein kompliziertes python skript erstellen, dass genauso gemischt ist wenn du willst, wie meines, nur dass du hier den quellcode wirklich nichtmehr erkennen kannst... du müsstest ja quasi dauernd textausgaben machen... so wie das bei php und html ist, hat das schon sinn...

Ihr habt natürlich vollkomment Recht! Die Source codes sind im wesentlichen pfusch. Im Prinzip ein einfacher text-sucher der eval benutzt nicht aufregend... und was ich im wesentlichen suche, wäre ne Methode mit ebensowenig aufwand die am besten den C Preprozessor nutzt und trickreich mit möglichst geringen einschränkungen dafür sorgt dass man in irgendeiner form in python die defines benutzen kann... mir ist klar dass sich das sehr unsauber anhört, um details kann ich mich ja kümmern wenn ichs soweit hab... ich dachte nur vielleicht hat jemand eine idee... ein anderer ansatz wäre die codes für z.b. den gnu c compiler und dem enthaltenen preprocessor herzunehmen, und das lustige python eval zeug da hinzuzufügen (gnu c ist ja hoffentlich in C oder C++ geschrieben, also lässt sich ja im prinzip gut integrieren) ... nur wäre dass dann halt ein eigener kompiler.. nicht so leicht zu verteilen... generell schwierig...
Wenn da nur ein python filter wäre, kann ich das einfach mitverteilen mit meinem makefile von irgendwelchen programmen...

ursprüunglich wollt ich ja zuerst nur das was es eh schon kann... sogar weniger... einfach einen ersatz für die methode ein python skript erstellt mir eine konfiguration... vielleicht wird es auch einfach nur das, wenn ich seh dass sich die neue idee nicht machen lässt... (insofern stimmt es natürlich dass ich mir noch nicht alles im detail überlegt hab... ich suche eben gerade nach einer möglichst unaufwendigen lösung)

Im Prinzip habt ihr auch mit eurem immer wieder erwähnten template system recht... ich könnte mir einfach eins aussuchen... quasi meine eigene erweiterungssprache bauen, bzw ist ja scheinbar auch schon einiges vordefiniert... und glücklich sein... nur würd ich halt lieber python als diese sprache sehen... (das war ja auch mit der grund warum ich das hier gepostet hab, sonst hätte das ja garnix mit python zu tun...)

ich würde gerne die ultimative lösung hinbekommen, geht das aber so garnicht, wird es warscheinlich einfach sowas wie php für html... und ich lass es quasi vom makefile in 2 schritten übersetzten... also im prinzip das gleiche wie ein config skript, nur anstatt print "#define VALUE %s" % "irgendwas" steht halt bei mir nur #define VALUE <?py:echo(wertdervorherberechnetwurde)?>... das sieht jetzt nicht soviel besser aus, aber was wenn ich da noch 10 normale defines hab... sicher ich könnt ein extra headerfile annlegen und dort alles fixe reintun, aber was wenn die sache verstrickter ist... ich glaub es ist im gewissen bereichen auch geschmackssache... ich persöhnlich finde das php konzept in dem bereich sehr klug...

Also gebt mir noch ein bisschen Zeit, ich bin noch nicht zu viel mehr gekommen als ein bisschen mit dem gcc rumzuspielen...
Die Idee die ich versuche umzusetzten geht mal in Richtung den zugriff durch #ifdefs zu ersetzten... im ersten schritt will ich mal nur quasi #ifdef und so unterstützen... danach geht es um konkrete werte...
Wie gesagt, versuchen tu ich mal so wenig wie möglich sebst machen zu müssen, indem ich einfach mal den preprozessor vom gcc arbeiten lasse... sollte dies so garnicht wollen, bericht ich euch wies weitergehen wird... wenn wer von euch noch einen voorschlag hat, was man noch probieren könnte um das zu erreichen, ist er natürlich herzlich eingeladen mir einen tipp zu geben...
Antworten