2009-07-08 13 views
14

la voce di Wikipedia per i C Preprocessor stati:Usando il preprocessore C per lingue diverse C

Il linguaggio del preprocessore direttive è agnostico alla grammatica di C, in modo che il C preprocessore può anche essere utilizzato in modo indipendente per elaborare altri tipi di file .

Come può essere fatto? Qualche esempio o tecnica?

MODIFICA: Sì, sono principalmente interessato all'elaborazione delle macro. Anche se probabilmente non è consigliabile o mantenibile, sarebbe comunque utile sapere cosa è possibile.

+5

Cosa è necessario fare con il preprocessore? Se hai solo bisogno dell'elaborazione della macro, puoi usare m4: http://www.gnu.org/software/m4/ – dwhall

+0

woah, m4? Voglio dire .. sul serio? Pensavo fosse una cosa ben dimenticata per la maggior parte delle persone. Dove viene usato al giorno d'oggi? Una cosa che so, è che è usato per compilare i file .cf di sendmail. – shylent

+1

m4 può ancora essere utilizzato quando si esegue configure; rendere; fare installare. Guarda attentamente configure. –

risposta

16

È possibile chiamare CPP direttamente:

cpp <file> 

Piuttosto che chiamare attraverso gcc:

gcc -E filename 

fare notare, tuttavia, che, come detto nello stesso articolo di Wikipedia, la lingua di C preprocessore non è davvero attrezzato per uso generale:

Tuttavia, poiché il preprocessore C non ha caratteristiche di alcuni altri r preprocessore, come macro ricorsive, espansione selettiva secondo per quotare, valutazione stringa in condizionali e completezza Turing , è molto limitato rispetto a un processore macro più generale come m4.

Avete considerato di dilettarsi con un linguaggio di elaborazione macro più flessibile, come ad esempio il m4 di cui sopra?

+2

+1 per il riferimento a 'm4'. Questo è stato tradizionalmente il preprocessore di scelta per compiti complessi; Il CPP è molto primitivo al confronto. – ephemient

+6

Non puoi davvero "divertirti" con CPP. m4 d'altra parte è un campo minato di godimento; devi solo superare la gobba iniziale del dolore. – kjfletch

+0

m4 sembra interessante, grazie a tutti quelli che ne hanno parlato. – user4812

0

È possibile implementare il preprocessore C nel compilatore per un'altra lingua.

È possibile utilizzarlo per preelaborare qualsiasi tipo di file di testo, ma ci sono molte cose migliori a tale scopo.

1

In genere è possibile richiamare il compilatore C con un'opzione di pre-elaborazione solo (e ignorare qualsiasi istruzione #line). Prendi questo come un semplice esempio:

<?php 
function foo() 
{ 
#ifdef DEBUG 
    echo "Some debug info."; 
#endif 
    echo "Foo!"; 
} 

foo(); 

Definiamo un file sorgente PHP con istruzioni di preelaborazione. Possiamo quindi preprocessare esso (gcc può fare anche questo):

cl -nologo -EP foo.php > foo2.php 

Dal DEBUG non è il definito il primo echo è spogliato. Inoltre qui le righe che iniziano con # sono commenti in PHP, quindi non è necessario pre-elaborarli per una build di "debug".

Modifica: poiché hai chiesto informazioni sui macro. Anche questo funziona bene e potrebbe essere utilizzato per generare codice di codice di riscaldamento ecc.

+0

le persone stanno davvero facendo questo genere di cose? – Geo

+1

@Geo, si lo sono. Perl ha (o aveva l'abitudine di avere) un'opzione della riga di comando per eseguire lo script perl tramite CPP prima di lasciare che il parser ad esso, per esempio. Se tutto ciò di cui hai bisogno è un po 'di gestione di #ifdef per attivare e disattivare i blocchi di codice o # include di condividere le linee di origine, cpp è in realtà una buona scelta di strumenti. – RBerteig

2

Molti compilatori C hanno un indicatore che indica loro solo il pre-elaborazione. Con gcc è la bandiera -E. ad esempio: uscita

$ gcc -E -     
#define FOO foo 
bar FOO baz 

volontà:

# 1 "<stdin>" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "<stdin>" 

bar foo baz 

Con altri compilatori C dovrete controllare i manuali per vedere come swithc alla modalità di pre-elaborazione-only.

+3

Si potrebbe desiderare che il proprio esempio faccia effettivamente qualcosa. – dborba

+0

Heh. Buon punto Fisso. –

0

Fondamentalmente quello che sta dicendo è che i preprocessori non hanno nulla a che fare con la sintassi C. Sono fondamentalmente semplici parser che seguono un insieme di regole. Quindi potresti usare un preprocessore come se tu usassi sed o awk per compiti sciocchi. Non chiedermi perché vorresti farlo comunque.

Ad esempio, in un file di testo:

#define pi 3.141 

pi is not an irrational number. 

quindi si esegue il preprocessore & si otterrebbe.

3.141 non è un numero irrazionale.

2

Ad esempio, Assemblatore.Mentre molti assemblatori hanno il proprio modo di includere #include le macro e #define, può essere utile usare il preprocessore C per questo. GNU make, ad esempio, ha regole implicite per trasformare i file * .S in file * .s eseguendo il preprocessore ('cpp'), prima di alimentare il file * .s all'assembler GNU ('as').

+0

Anche se a seconda del caso di una singola lettera del nome del file era una scelta di design scarsa lì ... dove ho fatto la cosa equivalente in altri progetti, ho usato .asm o .src per la fonte "reale" codice e lo standard .s per il codice emesso da cpp. Sfortunatamente ci sono molti sviluppatori (anche usando gli strumenti di Gnu) che vivono su file system che non possono distinguere i nomi dal solo caso. Il valore predefinito di NTFS è la conservazione del caso, ma non la distinzione tra maiuscole e minuscole, ad esempio. – RBerteig

+0

Non ho detto che era una scelta * intelligente *.;-) – DevSolar

+0

In realtà GNU Make non lo esegue tramite il preprocessore C (almeno non direttamente), lo esegue tramite il compilatore C '$ (CC)', questo metodo funziona su file system sensibili al maiuscolo/minuscolo poiché non lo fa richiedono due file con lo stesso nome. –

1

Utilizzando il compilatore di Microsoft, penso (l'ho appena controllato, non l'ho testato) che è lo /P compiler option.

Altri compilatori presumibilmente hanno opzioni simili (o, per alcuni compilatori, il preprocessore potrebbe effettivamente essere un eseguibile diverso, che di solito viene eseguito implicitamente dal compilatore ma che può anche essere eseguito separatamente separatamente).

1

Supponendo che si sta utilizzando GCC, si può prendere qualsiasi file di testo normale vecchia, a prescindere dal suo contenuto, ed eseguire:

gcc -E filename

eventuali direttive del preprocessore nel file saranno trattati dal preprocessore e GCC quindi esci.

Il punto è che non importa quale sia il contenuto effettivo del file di testo, dal momento che tutte le preoccupazioni del preprocessore sono le sue stesse direttive.

2

Sì, può essere fatto analizzando la propria lingua tramite il preprocessore gcc (ad esempio 'gcc -E').

Abbiamo fatto questo sul mio lavoro con il nostro linguaggio specifico. Ha abbastanza alcuni vantaggi:

  • È possibile utilizzare C di istruzioni include (#include) che è molto potente
  • È possibile utilizzare le costruzioni #ifdef
  • È possibile definire costanti (#define MAGIC_NUMBER 42) o funzioni macro (#define min (x, y) ((x (< (y) (x):. (y))

... e le altre cose nel processore c

TUTTAVIA, anche tu erediti il costruzioni C non sicure, e avere un preprocessore non integrato con la tua lingua principale ne è la causa. Pensate alla minima qualcosa di macro e fare come:

a = 2; 
b = 3; 

c = min(a--, b--); 

Basti pensare che valore A e B avranno dopo la funzione min?

stesso vale per le costanti non tipizzato di impostare il

vedere il libro Safer C per i dettagli.

+0

Re il tuo esempio di codice sorgente ... '2', perché gli operatori di incremento/decremento postfix fanno schifo, non a causa di tutto ciò che ha a che fare con il preprocessore macro di C. Come JavaScript, esistono un certo numero di "C: The Bad Parts", e postfix-'++'/'--' sono un buon esempio. Il mio suggerimento è di dimenticare che esistono e ** usano solo prefisso-'++'/'--' ** _ (ad esempio' min (- a, --b); 'e' for (int i = 0; i

1

Ho sentito parlare di persone che utilizzano il pre-processore C sul codice Ada. Ada has no preprocessor, quindi devi fare qualcosa del genere se vuoi sottoporre a pre-elaborazione il tuo codice.

Tuttavia, è stata una decisione progettuale concreta di non dargliene uno, quindi fare questo è molto poco-Ada. Non consiglierei a nessuno di farlo.

1

Qualche tempo fa ho lavorato su un progetto che utilizzava imake per la generazione di makefile. Come ricordo, era fondamentalmente la sintassi del preprocessore c per generare i file make.

Problemi correlati