2013-01-19 11 views
27

Ho usato a pensare C++ è stato il "strano" uno con tutte le ambiguità con < e >, ma dopo aver tentato di implementare un parser Credo di aver trovato un esempio che rompe quasi ogni lingua che utilizza < e > per i tipi generici:In che modo Java, C++, C# e così via aggirano questa particolare ambiguità sintattica con < and >?

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

Ciò può essere sintatticamente sia interpretato come una chiamata di metodo generico (g), o potrebbe essere interpretata come dare f i risultati di due confronti.

In che modo tali linguaggi (in particolare Java, which I thought was supposed to be LALR(1)-parsable?) aggirano questa ambiguità sintattica?

Non riesco a immaginare un modo non hacky/context-free di occuparsi di questo, e sono sconcertato dal modo in cui qualsiasi linguaggio del genere può essere privo di contesto, per non parlare di LALR (1) -pastabile .. .

(vale la pena notare che anche un parser GLR non può restituire un singolo parse di questa affermazione con nessun contesto !!)

+2

+1 grande questione, Solo una nota, il compilatore java ha un sacco di euristiche per risolvere l'ambiguità, si indovina un sacco. Loro stessi ammettono che il loro sistema generico è rotto e che ci sono casi in cui non riesce (anche se sono di tasso), guarda la presentazione delle caratteristiche di Java 8 spiegano alcuni dei problemi e come li risolveranno in java 8. –

+0

@BenjaminGruenbaum: Grazie. :) Per quanto riguarda l'euristica, sono sicuramente ottimi per generare buoni messaggi di errore del compilatore, ma a meno che non facciano parte della grammatica della specifica della lingua, non possono essere legalmente utilizzati per risolvere le ambiguità, vero? E se essi * sono * parte della grammatica, allora come può la grammatica essere libera dal contesto (per non parlare di LR (1) -pastabile)? – Mehrdad

+2

non è ambiguo, dipende da ciò che g è dichiarato come – NimChimpsky

risposta

3

una chiamata di metodo generico in Java sarebbe < h, i > g (j) quindi non c'è alcuna ambiguità :)

+0

Wow, hai ragione ... ho pensato che sarebbe 'g (j)' ma [apparentemente non lo è] (http://ideone.com/bYyaaj)! +1 Ottima risposta, grazie :) – Mehrdad

+0

Anche questa è stata la mia reazione. Penso che sia più facile per i parser, e devo ammettere che è un brutto scherzo. I designer di Langauge non dovrebbero ascoltare i compilatori che si lamentano quando progettano; ottieni cose come questa –

2

non riesco proprio a immaginare un non-hacky/context-free modo di affrontare questo, e sono sconcertato da come qualsiasi linguaggio del genere può essere privo di contesto, per non parlare di LALR (1) -parsable ...

La risposta è che non lo sono (almeno non Java e C++; So molto poco di C#). La grammatica Java a cui si fa riferimento risale al 1996, molto prima che i generici fossero stati introdotti.

Per un'ulteriore discussione, vedi Are C# and Java Grammars LALR(x)?

+0

Neanche C è completamente privo di contesto poiché l'uso di un simbolo può rappresentare un identificatore o un nome di tipo, a seconda delle dichiarazioni che possono essere separate dall'uso da una quantità arbitraria di codice. – ebohlman