2010-09-14 6 views
7

Sto mantenendo/sviluppando una piattaforma per i test dei compiti a casa. È per lo più automatico. Quello che devo aggiungere ora è l'analisi del codice. Devo controllare il codice per costrutti specifici.Estensione della piattaforma di test dei compiti a casa per includere l'analisi del codice (C/C++)

Ad esempio:

Fa il file main.cpp contengono una classe denominata user con un metodo const get_name()?

C'è qualche strumento là fuori che mi permetterebbe di fare cose del genere (l'ideale sarebbe qualcosa che può essere copiato). Solo Linux.

risposta

0

Ho scoperto lo strumento dehydra da Mozilla. Sembra essere scritto principalmente per scopi interni, ma potrebbe essere esattamente quello che stavo cercando.

https://developer.mozilla.org/En/Dehydra/Using_Dehydra

Edit: Dehydra è grande. Mancano alcune caratteristiche minori come la determinazione dei metodi const, ma per il resto grandiose.

3

Una possibilità potrebbe essere quella di eseguire il codice tramite GCC e utilizzare l'estensione GCC-XML per produrre descrizioni XML della struttura interna del programma. È quindi possibile utilizzare la libreria XML preferita per analizzare il documento o applicarvi un XSLT se è sufficiente visualizzarlo come HTML o altro.

1

Come si applica a C? :)

Il file main.cpp contiene una classe denominata utente con un metodo const get_name()?

Creare un altro file (test.cpp) con

void test(void) { 
    const user x; 
    x.get_name(); 
} 

compilazione test.cpp e main.cpp insieme. Se c'è un errore (codice di uscita! = 0), quindi NO!, il file main.cpp non definisce una classe (pubblica) denominata utente con il metodo specifico.

Avvertenza: non conosco il numero C++, quindi scusate eventuali errori maggiori (o minori) in quanto sopra.


Modifica sceneggiatura aggiunto

#! /bin/sh 

cat main.c test.c > 3710532.c 
if gcc 3710532.c > /dev/null 2>&1 
then echo OK 
else echo BZZZT 
fi 
rm 3710532.c 

Non ho un ready-to-use C++ compilatore installato su questa macchina sono in, quindi il mio test è stato con un compilatore C e C file. Il mio compilatore non ha "lavorato con" gcc -combine main.c test.c quindi ho ottimizzato quella parte.

Esecuzione di questo script con una combinazione di lavoro di main.c e test.c output 'OK', altrimenti viene emesso 'BZZZT'.


Per le prove ho usato questo main.c

typedef int user; 

int get_name(void) { 
    return 0; 
} 

int main(void) { 
    return 0; 
} 

e questo test.c

void test(void) { 
    const user x; 
    get_name(); 
} 

corsa Esempio

 
$ ./3710532.sh 
OK
+0

Hmmm ... se non vi sono errori, quindi ** SÌ! **: main.cpp definisce la classe e il metodo; altrimenti l'errore potrebbe essere qualsiasi cosa – pmg

+0

Questo si compilerebbe bene con un metodo non-const 'get_name'. Devi rendere 'x' un' const user' nonostante il punto di pmg riguardo ad altri possibili errori. –

+0

Grazie Marco. Codice modificato: 'x' è ora' const'. Non ho nemmeno registrato il 'const' per il metodo. Il solo fatto di 'x' const garantisce che il metodo sia anche' const'? – pmg

-1

Se si vuole fare l'analisi di codice arbitrario , hai bisogno di parsing/matching arbitrario/etc. GCC-XML fornisce informazioni sulla dichiarazione, ma non il contenuto dei metodi.

nostro DMS Software Reengineering Toolkit fornirà le stesse informazioni di astratto come GCC-XML, ma dispongono in più di dettaglio completo per il contenuto delle definizioni (ad esempio, il metodo corpo informazioni), sostenuto dal suo C++ Front End. Questo ti consentirà di accedere ai contenuti delle consegne e per controllare i tuoi programmi per studenti.

DMS fornisce l'analisi generale di AST, tabelle di simboli e corrispondenza del modello di origine. Il front-end C++ fornisce un parsing completo in C++, costruendo AST C++ e le corrispondenti informazioni sui simboli. Quello che fai dopo per il riconoscimento spetta a te, ma il tuo esempio sembra riguardare la ricerca di un modello specifico.

metà del vostro esempio sarà gestita dal alcuni modelli di sorgente DMS per C++:

pattern is_correct_student_class(m:members):class = 
    " class user { \m } ". 

pattern is_correct_student_method_present(p:parameters,s:statements):method = 
    " const get_name(\p) { \s } " 

(perdoni la mia sintassi C++, non scrivo un sacco di esso), che corrisponde ad ogni AST, rispettivamente, , corrispondente alla classe utente indicata e al metodo const desiderato. Le virgolette sono meta-virgolette, con la roba all'interno essendo la sintassi C++ con gli escape \ p, \ m e \ s che rappresentano i metavariabili p, m ed s, che sintatticamente devono essere un elenco di parametri, un elenco di metodi e una dichiarazione elenca rispettivamente per abbinare il modello. Le definizioni dell'elenco dei parametri, ecc. Vengono derivate automaticamente dalla sezione grammaticale C++ del front-end C++.

L'altra metà è implementato da un bit di codice DMS PARLANSE eseguito dopo richiamando il parser C++ e nome/tipo resolver:

(define has_student_code (lamdba (function boolean [tree AST])) 
     (AST:IsInTree tree 
      (lambda (function boolean [tree1 AST] 
       (&& (Registry:MatchPattern tree1 "is_correct_student_class") 
        (AST:IsInList (AST:GetNthGrammarChild tree1 4) ; the member list 
         (lambda (function boolean [tree2 AST]) 
          (Registry:MatchPattern tree2 ; a member 
           "is_correct_student_method_present") 
         )lambda 
     )lambda 
    ) 
    )define 

con qualche libertà adottate per semplificare la presentazione.

Questo è un controllo piuttosto semplice; è possibile accedere alla tabella dei simboli dal codice PARLANSE per effettuare controlli più sofisticati se ciò ha senso.

Mentre DMS non funziona direttamente sotto Linux, sembra funzionare sotto Wine.