Istnieje twierdzenie ludowe, które mówi, że C jest trudne do przeanalizowania, a C ++ w zasadzie niemożliwe.
To nieprawda.
Prawdą jest, że C i C ++ są dość trudne do przeanalizowania przy użyciu parserów LALR (1) bez hakowania maszyn parsujących i plątania się w danych tabeli symboli. W rzeczywistości GCC parsował je, używając YACC i dodatkowych hackerów, i tak, to było brzydkie. Teraz GCC używa odręcznych parserów, ale nadal z hackerem tablicy symboli. Ludzie z Clang nigdy nie próbowali używać automatycznych generatorów parserów; AFAIK parser Clang zawsze był ręcznie kodowany rekursywnie.
Prawdą jest, że C i C ++ są stosunkowo łatwe do przeanalizowania z silniejszymi automatycznie generowanymi parserami, np. Parserami GLR , i nie potrzebujesz żadnych hacków. W Elsy C ++ parser jest jednym z przykładów. Nasz interfejs C ++ jest kolejnym (podobnie jak wszystkie nasze interfejsy „kompilatorów”, GLR jest całkiem wspaniałą technologią parsowania).
Nasz interfejs C ++ nie jest tak szybki jak GCC iz pewnością wolniejszy niż Elsa; włożyliśmy niewiele energii w jego dokładne dostrojenie, ponieważ mamy inne, bardziej palące problemy (niemniej jednak zostało ono użyte w milionach wierszy kodu C ++). Elsa jest prawdopodobnie wolniejsza niż GCC tylko dlatego, że jest bardziej ogólna. Biorąc pod uwagę dzisiejsze prędkości procesora, różnice te mogą nie mieć większego znaczenia w praktyce.
Ale "prawdziwe kompilatory", które są dziś szeroko rozpowszechniane, mają swoje korzenie w kompilatorach sprzed 10, 20 lub więcej lat. Nieskuteczność liczyła się wtedy znacznie bardziej i nikt nie słyszał o parserach GLR, więc ludzie robili to, co umieli. Clang jest z pewnością nowszy, ale twierdzenia ludowe przez długi czas zachowują swoją „zdolność przekonywania”.
Nie musisz już tego robić w ten sposób. Możesz bardzo rozsądnie użyć GLR i innych podobnych parserów jako front-endów, z ulepszeniem w utrzymywalności kompilatora.
Co to jest prawdą, jest to, że coraz gramatyki, który odpowiada zachowaniu przyjaznego sąsiedztwa kompilator jest trudne. Podczas gdy praktycznie wszystkie kompilatory C ++ implementują (większość) oryginalnego standardu, zwykle mają również wiele rozszerzeń z ciemnymi rogami, np. Specyfikacje DLL w kompilatorach MS itp. Jeśli masz silny silnik parsujący, możesz spędzić czas próbując uzyskać ostateczna gramatyka, aby pasowała do rzeczywistości, zamiast próbować naginać gramatykę, aby dopasować ją do ograniczeń generatora parsera.
EDYCJA Listopad 2012: Od czasu napisania tej odpowiedzi ulepszyliśmy nasz interfejs C ++, aby obsługiwał pełny C ++ 11, w tym dialekty ANSI, GNU i MS. Chociaż było wiele dodatkowych rzeczy, nie musimy zmieniać naszego silnika parsującego; właśnie zmieniliśmy zasady gramatyczne. My nie musimy zmieniać analizę semantyczną; C ++ 11 jest semantycznie bardzo skomplikowany i ta praca utrudnia uruchomienie parsera.
EDYCJA Luty 2015: ... teraz obsługuje pełne C ++ 14. (Zobacz pobieranie czytelnego dla człowieka kodu AST z kodu c ++, aby zapoznać się z analizami GLR prostego fragmentu kodu i niesławną C ++ „najbardziej irytującą analizą”).
EDYCJA Kwiecień 2017: Teraz obsługuje (wersję roboczą) C ++ 17.