2013-01-19 10 views
27

Kiedyś myślałem, C++ było „dziwne” jeden ze wszystkich niejasności z < i >, ale po próbie wdrożenia parser Chyba znalazłem przykład, który łamie tylko o każdy język, który używa < i > dla typów generycznych:W jaki sposób Java, C++, C#, itp. Omija tę szczególną syntaktyczną dwuznaczność z < and >?

f(g<h, i>(j)); 

Może to być interpretowane jako składniowo albo wywołanie metody rodzajowe (g), czy może to być interpretowane jako dające f wynikami dwóch porównań.

W jaki sposób takie języki (szczególnie Java, which I thought was supposed to be LALR(1)-parsable?) omijają tę składnię dwuznaczności?

Po prostu nie wyobrażam sobie żadnego niehackowego/pozbawionego kontekstu sposobu radzenia sobie z tym i jestem zaskoczony tym, jak każdy taki język może być pozbawiony kontekstu, nie mówiąc już o LALR (1). .

(warto zauważyć, że nawet parser GLR nie może wrócić pojedynczy przetwarza na tym rachunku bez kontekstu !!)

+2

+1 wielkie pytanie, Tylko uwaga, kompilator java ma wiele heurystyk, aby rozwiązać niejednoznaczność, to wiele. Oni sami przyznają, że ich ogólny system jest zepsuty i zdarzają się przypadki, w których się nie udaje (choć są to stawki), spójrzcie na prezentację funkcji java 8, wyjaśnijcie niektóre problemy i jak będą je rozwiązywać w java 8. –

+0

@BenjaminGruenbaum: Dzięki. :) Jeśli chodzi o heurystykę - są one z pewnością świetne do generowania dobrych komunikatów o błędach kompilatora, ale jeśli nie są częścią gramatyki języka, nie mogą być legalnie wykorzystane do rozwiązania niejasności, prawda? A jeśli * są * częścią gramatyki, to w jaki sposób gramatyka może być pozbawiona kontekstu (nie mówiąc już o LR (1))? – Mehrdad

+2

jego nie jest amibugous, to zależy od tego, co g jest zadeklarowane jako – NimChimpsky

Odpowiedz

3

rodzajowe wywołanie metody w Javie byłoby < H, I > g (j), więc nie ma dwuznaczności :)

+0

Wow, masz rację ... Myślałem, że to będzie 'g (j) 'ale [widocznie to nie jest] (http://ideone.com/bYyaaj)! +1 Świetna odpowiedź, dzięki :) – Mehrdad

+0

To była też moja reakcja. Myślę, że to ułatwia parserom i muszę przyznać, że to naprawdę brzydki hack. Projektanci Langauge nie powinni słuchać facetów kompilatorów narzekających podczas projektowania; dostajesz takie rzeczy. –

2

po prostu nie mogę sobie wyobrazić każdy non-hacky/bezkontekstowych sposób radzenia sobie z tym, i jestem zdziwiony, jak każdy taki język może być pozbawiony kontekstu, nie mówiąc już o LALR (1) -parsable ...

Odpowiedź brzmi: nie są (przynajmniej nie Java i C++; Wiem bardzo mało o C#). Gramatyka języka Java, z którą łączysz się, pochodzi z 1996 roku, na krótko przed wprowadzeniem generyków.

Dla dalszej dyskusji, patrz Are C# and Java Grammars LALR(x)?

+0

Nawet C nie jest w pełni wolne od kontekstu, ponieważ użycie symbolu może reprezentować albo identyfikator, albo nazwę typu, w zależności od deklaracji, które można oddzielić od użycia przez dowolną ilość kodu. – ebohlman

Powiązane problemy