CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Question sur de la syntaxe Java

XKCD
XKCD
Niveau 10
24 novembre 2011 à 13:52:01

Bonjour :)

J'ai une question sur la syntaxe Java (j'écris un compilateur Java simplifié, et n'ayant jamais codé dans ce langage, j'ai un peu de mal à piger certains trucs). C'est simple : Qu'est-ce qu'on peut mettre avant un point ?

Par exemple, je sais qu'on peut écrire quelque chose du type :

identifiant1.identifiant2.identifiant3

ou encore, quelques mots-clés :

this.identifiant
null.identifiant ( ? )

Mais on peut faire des trucs compliqués à base de parenthèses, de ce type :

(expressionquelconque).identifiant

ou bien c'est interdit ?

Merci d'avance ! :)

Bunyan
Bunyan
Niveau 17
24 novembre 2011 à 13:58:29

Typiquement, le point se met après un objet.
Que ce objet soit this, une variable (locale, d'instance, global) ou un retour de méthode.

Le null.machin est impossible (où alors je n'ai jamais rencontré dans quel cas celui-ci pourrait être possible).

Tu peux faire, par exemple :
monObjet.maMéthode(); => correct, les accents sont acceptés.
((UnType)monObjet).maMéthode();

monObjet.maMéthode().uneAutreMéthode().encoreUneAu
treMéthode().ToujoursUneAutreMéthode(); => du moment que les méthodes retournent des objets et que les appels de méthodes sont cohérent avec l'objet renvoyé.

Après, tu peux appeler des variables public aussi :
unObjet.maVariable = 2;
unObjet étant une variable ici.

Tu peux appeler des constantes :
UnMachin.MACONSTANTE;
UnMachin étant une classe.

Tu peux t'amuser avec les enums, mais là, je passe.

Grosso-modo : il faut un objet à avant le point, et une méthode ou une variable après.

XKCD
XKCD
Niveau 10
24 novembre 2011 à 14:16:33

OK, merci pour les précisions. Néanmoins, mon problème se situe au niveau purement syntaxique, pour l'instant je n'en suis pas au stade où je donne des types à chacun de mes groupes sémantiques (en disant "tel bloc = un appel de méthode", "tel bloc = une déclaration d'objet", etc.).

Donc avant un point, on peut mettre soit un identifiant (que l'on espère être un identifiant de classe), soit un groupe syntaxique du type "identifiant - parenthèse gauche - liste de parametres, éventuellement vide - parenthèse droite", c'est ça ?

Et les paramètres - dis-moi si je me trompe, c'est aussi de simples identifiants ?

041
041
Niveau 10
24 novembre 2011 à 14:17:30

null.identifiant = NullPointerException

"Mais on peut faire des trucs compliqués à base de parenthèses, de ce type :

(expressionquelconque).identifiant "

Oui, exemple

import java.util.ArrayList;
class d
{
static Object b = new ArrayList<String>();
public static void main(String[] args)
{
        String a = "azerty";
        ((ArrayList<String>)b).add (a);

        System.out.println(((ArrayList<String>)get
B()).size());
}
static Object getB()
{ return b; }
}

XKCD
XKCD
Niveau 10
24 novembre 2011 à 14:32:50

OK donc j'enlève la gestion des null.bidule, c'est toujours une question de réglée.

Donc 041, ce que tu me dis c'est que globalement on peut mettre n'importe quelle expression devant un point ? Ou alors c'est juste à cause de l'utilisation de ArrayList (que je ne dois pas implémenter) ?

Question supplémentaire : qu'a-t-on le droit d'encadrer de parenthèses ?

Par exemple, si j'ai deux variables qui s'appellent identifiant et autreidentifiant, et que j'écris quelque chose comme :

(identifiant) + autreidentifiant

le compilateur va-t-il accepter ça ? Ou bien il va analyser l'expression "(identifiant)" comme un cast sur un type inconnu ?

Parce que là mon parseur, lorsqu'il voit quelque chose du type (identifiant), il ne sait pas comment choisir entre les deux (et moi non plus) :(

041
041
Niveau 10
24 novembre 2011 à 15:53:25

"Donc 041, ce que tu me dis c'est que globalement on peut mettre n'importe quelle expression devant un point ?"
:d) Si l'expression te donne une instance d'un objet, oui.
Ou si tu fais une référence statique à une variable de classe, ex:
System.out.println(separator);

"Question supplémentaire : qu'a-t-on le droit d'encadrer de parenthèses ?

Par exemple, si j'ai deux variables qui s'appellent identifiant et autreidentifiant, et que j'écris quelque chose comme :

(identifiant) + autreidentifiant

le compilateur va-t-il accepter ça ?"

:d) Ca dépend.
String a="a";
String b="b";
File c=new File("1.txt");
a=(a)+b; //a="ab" (les parenthèses ne changent rien)
a=(String)+b; //Erreur
a=(File.pathSeparator)+b; //a="/b"
a=c+c; // Erreur, l'opérateur + n'est pas défini pour les File
a=File.separator; //a="/"
a=(File).separator; //Erreur car il prendra ça comme cast
a=(lol)+b; // Erreur, lol n'existe pas

Donc si "identifiant" est une instance d'une classe, tu le traite comme variable.
Si c'est le nom d'une classe/type, tu le traite comme cast
Si c'est aucun des deux, erreur.

041
041
Niveau 10
24 novembre 2011 à 15:54:29

"Ou si tu fais une référence statique à une variable de classe, ex:
System.out.println(separator); "

Je voulais écrire
System.out.println(File.separator);

041
041
Niveau 10
24 novembre 2011 à 15:56:02

"a=(File.pathSeparator)+b; //a="/b" "

Et là je voulais mettre File.separator , c'est pas le même( : et / ), enfin, dans la logique c'est pas important.

( Désolé du triple post :( )

XKCD
XKCD
Niveau 10
24 novembre 2011 à 17:24:57

Merci beaucoup pour ces précisions, je comprends mieux ce qui se passe. Néanmoins, je ne peux pas appliquer ce que tu me conseilles : au stade de l'analyse sémantique, je n'ai aucune idée de ce qu'il y a "derrière" un identifiant, et donc je ne peux pas savoir si il s'agit d'une instance d'une classe ou bien du nom d'une classe ou d'un type.

Pour simplifier, en compilation y'a quatre étapes :

1) Analyse lexicale : on transforme un fichier texte en suite de "lexèmes" (typiquement, le texte :

a=(a)+b;

devient la liste suivante :

IDENTIFIANT("a") , EGAL , PARENTHESEGAUCHE , IDENTIFIANT("a") , PARENTHESEDROITE , PLUS , IDENTIFIANT("b") , POINTVIRGULE

(désolé pour les majuscules mais c'est l'usage).

2) L'analyse sémantique (aussi appelé "parseur") prend cette liste bizarre et la transforme en arbre de syntaxe abstraite, donc un truc du type

Affectation(Identifiant("a"),Plus(Parenthèses("a")
,Identifiant("b")))

sauf que là, Parenthèses("a") n'a pas beaucoup de sens, mais j'y reviens.

3) Le typage prend un tel arbre et déduit les types des différents identifiants en fonction de ce à quoi ils sont rattachés (par exemple, lorsqu'il va lire l'arbre Incrementation(Identifiant("a")) provenant de la ligne "a++;", il va noter quelque part "le type de "a", c'est int").

4) Et la compilation proprement dite crée du code assembleur à partir des instructions.

Moi je suis à l'étape 2, et typiquement, pour une expression du type "a=(a)+b", je sais que "a" est un identifiant mais j'ai aucune chance de savoir à l'avance si c'est un nom de type, de classe, de variable ou d'instance de classe. Et donc je suis bien bloqué :(

Si quelqu'un a une idée géniale, je suis preneur, mais en tous cas le fait de lire tes explications me permet de demander de l'aide à mon prof sans avoir l'air de ne rien comprendre à rien. Merci beaucoup 041 :)

041
041
Niveau 10
24 novembre 2011 à 22:16:41

Un cast se trouve toujours directement à gauche d'une variable.
Dans tous les cas, il y a une variable à sa droite, donc au niveau de l'analyse sémantique, t'as qu'à considéré que si ce qu'il y a à droite de (identifiant) est lui même un identifiant (Eventuellement aussi entre parenthèses...), c'est un cast.

Par contre, si à droite de (identifiant) il y a un ".", "+", ";" etc, alors c'est juste un identifiant entre parenthèses.

Enfin, d'après moi ça devrait aller comme ça.

XKCD
XKCD
Niveau 10
24 novembre 2011 à 23:49:23

Je pense que je vais faire comme ça. Enfin que je vais d'abord regarder s'il y a un opérateur devant (opérateurs mathématiques, booléens, ".", "instanceof") ou un point-virgule, et que si c'est pas le cas je vais dire que c'est un cast.

Là où la question se pose c'est dans le cas de :

(a)-b

Vu qu'on ne peut pas savoir si le "-" est un moins binaire (variable a moins variable b) ou unaire (cast de l'expression "-b" vers le type a), mais je crois que le comportement de Java dans ce cas est de considérer le - comme un type binaire, donc je vais faire comme ça :-)

P'tain, la syntaxe pour les casts est vraiment pourrie à gérer :fou:

hyrulink2
hyrulink2
Niveau 7
25 novembre 2011 à 10:08:07

Ou sinon il y a la grammaire java:
http://cui.unige.ch/java/JAVAF/AJAVA.html

Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Création de sites web
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment