2010-12-17 6 views
5

Kod źródłowy programu C można analizować zgodnie z gramatyką C (opisaną w CFG) i ostatecznie przekształcić w wiele AST. Zastanawiam się, czy takie narzędzie istnieje: może zrobić coś odwrotnego, po pierwsze losowo generując wiele AST, które zawierają żetony, które nie mają konkretnych wartości ciągu, tylko typy żetonów, zgodnie z CFG, a następnie generowanie betonu tokeny zgodnie z definicjami tokenów w wyrażeniu regularnym.Jakieś narzędzia mogą losowo generować kod źródłowy zgodnie z gramatyką języka?

Mogę sobie wyobrazić, że pierwszy krok wygląda na powtarzalną wymianę bez terminali, która jest losowa i może być ograniczona przez określoną liczbę czasów iteracji. Drugim krokiem jest generowanie losowych ciągów zgodnie z wyrażeń regularnych.

Czy jest jakieś narzędzie, które może to zrobić?

+0

Ale ... dlaczego?: p Przypuszczam, że mógłbyś - jeśli podążasz za specyfikacją CFG, masz gwarancję znalezienia co najmniej syntaktycznie poprawnego kodu C. Ale ja nie wiem. Sądzę, że ktokolwiek kiedykolwiek próbował coś takiego zrobić - prawdopodobnie musiałbyś napisać coś w rodzaju odwrotnego parsera ... – Robert

+0

Pracowałem z kilkoma ... (to żart; Kocham wszystkich moich kolegów). –

+2

Czy jest jakiś powód, dla którego ktoś chciałby losowego, bezsensownego kodu źródłowego, który (najprawdopodobniej) nie zrobiłby nic? –

Odpowiedz

3

Robi to "Język Generowania Danych" DGL, z dodatkową możliwością ważenia prawdopodobieństw produkcji w wynikowej gramatyce.

Ogólnie parser rekursywny może być bezpośrednio przepisany w zestaw procedur rekursywnych w celu wygenerowania, zamiast analizowania/rozpoznawania języka.

0

Jeśli masz model gramatyki w znormalizowanej formie (wszystkie zasady jak ten):

LHS = RHS1 RHS2 ... RHSn ; 

i język PrettyPrinter (np AST narzędzie do konwersji tekstu), można zbudować jeden z nich dość z łatwością.

Po prostu zacznij od symbolu celu jako drzewa jednostek.

Repeat until no nonterminals are left: 
    Pick a nonterminal N in the tree; 
     Expand by adding children for the right hand side of any rule 
     whose left-hand side matches the nonterminal N 

dla terminali, które przenoszą wartości (na przykład nazw zmiennych, liczby, ciągi, ...) musisz wygenerować losową zawartość.

Powikłaniem powyższego algorytmu jest to, że nie kończy się on w sposób wyraźny. To, co naprawdę chcesz zrobić, to wybrać jakiś limit rozmiaru twojego drzewa i uruchomić algorytm, aż znikną wszystkie nieterminale lub przekroczysz limit. W drugim przypadku cofnij, cofnij ostatnią zamianę i spróbuj czegoś innego. Dzięki temu uzyskasz ograniczoną liczbę głębokości - najpierw wyszukaj AST o ustalonym rozmiarze.

Następnie wystarczy wydrukować wynik. Jest to prettyprinter part, które trudno jest uzyskać.

[Możesz zbudować wszystkie te rzeczy samodzielnie, w tym ślicznotkę, ale to sporo pracy. Buduję narzędzia, które obejmują wszystkie te maszyny bezpośrednio w sparametryzowanym języku; zobacz mój bio].

Nieprzyjemny problem nawet z dobrze uformowanymi AST polega na tym, że mogą one być bezsensowne; możesz utworzyć deklarację liczby całkowitej X i przypisać jej literalną wartość, dla języka, który na to nie pozwala.Prawdopodobnie można wyeliminować niektóre proste problemy, ale semantyka języka może być niewiarygodnie złożona, za przykład należy uznać C++. Zapewnienie, że skończysz z semantycznie znaczącym programem, jest niezwykle trudne; w istocie, musisz przeanalizować wynikowy tekst, a także wykonać rozpoznanie nazwy i typu/sprawdzenia. W przypadku C++ potrzebny jest kompletny front-end C++.

0

Problem z generowaniem losowym polega na tym, że dla wielu układów CFG spodziewana długość ciągu wyjściowego jest nieskończona (można łatwo obliczyć spodziewaną długość za pomocą generowania funkcji odpowiadających nieterminalnym symbolom i równaniom odpowiadającym regułom gramatyki); musisz kontrolować względne prawdopodobieństwa produkcji w określony sposób, aby zagwarantować zbieżność; na przykład, czasami, ważenie każdej reguły produkcji dla nieterminowego symbolu odwrotnie do długości jego RHS wystarcza

jest dużo więcej na ten temat w: Noam Chomsky, Marcel-Paul Sch \ "{u} tzenberger , "Algebraiczna teoria języków bez kontekstu", str. \ 118-161 w P. Braffort i D. Hirschberg (red.), Programowanie komputerowe i systemy formalne, Holandia Północna (1963) (patrz wpis w Wikipedii na Twierdzenie wyliczeniowe Chomsky'ego-Schützenbergera)

Powiązane problemy