Discussion: Grammaire R++ V0.2

  1. #1
    Membre éclairé

    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    septembre 2007
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Santé

    Informations forums :
    Inscription : septembre 2007
    Messages : 200
    Points : 714
    Points
    714

    Par défaut Grammaire R++ V0.2

    1 En français

    1.1 Quelques Tokens

    Un <IDENTIFIANT> est une suite de lettres et de chiffres commençant nécessairement par une lettre minuscule.
    Un <TYPE> est une suite de lettres et de chiffres commençant nécessairement par une lettre majuscule.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Integer  	# Un des type de base du langage
    ToTO		# Classe ToTO
    Toto		# Classe Toto
    1.2 Règles syntaxiques

    10. Un programme est un ensemble éventuellement vide de plusieurs instructions (30).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a <- 4
    plot(b)
    for(a in 1:5) cat("X")
    30. Une instruction est soit une définition (50), soit une instruction élémentaire (33).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a <- 4        # Définition
    plot(a)       # Instruction élémentaire
    33. Une instruction élémentaire est soit l'utilisation d'une fonction (60), soit une structure (190), soit un bloc d'instruction (35).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    plot(a)				# Instruction élémentaire
    for(a in 1:5){cat("X")}         # Structure
    {                               # bloc d'instruction
       a <- a*2
       b <- a*3
    }
    35. Un bloc d'instructions est un ensemble (éventuellement vide) d'instructions (30) comprit entre accolades.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    {
       a <- 4			
       for(a in 1:5) cat("X") 
    }
    50. Une définition peut être soit la définition d'une variable (55), soit la définition d'une fonction (250).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a <- 3
    Integer f <- function(Integer x){return(x^2)}
    55. La définition d'une variable se fait en spécifiant une variable (180) suivit de <ASSIGN> (c'est à dire de "<-") puis d'une expression (100). Il est possible de forcer le type d'une variable grâce aux constructeurs. Dans les cas non ambiguë, un typeur de R++ se charge de définir le type de l'expression et fixe ainsi le type de la variable. Enfin, comme en python, on peut définir plusieurs variables séparées par des virgules en fournissant plusieurs expressions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    n <- 2                  # Assignation d'un entier. Le type est déterminé automatiquement par le typeur
    a <- Character(5)       # Assignation de la chaine de caractères "5". Le type est forcé.
    notes <- c(2,4,3)       # Assignation d'un vecteur d'entier.
    a,b <- 3,"bonjour"      # Assignation de 3 à a et de "Bonjour" à b
    [[[Note importante : la modification de la valeur d'une variable devrait se faire avec la fonction set. En pratique, elle utilise la même syntaxe que la définition. zz <- 4 peut donc être :
    1. Soit la déclaration de la variable zz. Dans ce cas, le typeur détermine le type de l'expression, puis affecte ce type à zz
    2. Soit une modification de la variable zz. Dans ce cas, le typeur détermine le type de l'expression, puis vérifie qu'il est compatible avec le type de zz. Si ca n'est pas le cas, cela déclenche une erreur.

    Par contre, l'instruction zz[2] <- 3 est nécessairement une modification d'une variable existante.]]]


    60. Une action (au sens large) est l'appel d'une fonction. Cette fonction peut utiliser zéro, un ou plusieurs arguments (70). Cas particulier, une "expression" seule (sans fonction) est une simplification de l'instruction "get(expression)". Elle est donc considérée également comme une fonction. Si une fonction retourne un résultat et que se résultat n'est pas utilisé, alors il est affiché à l'écran (ie il est envoyé à la fonction "show").
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    a <- factoriel(3)       # fonction factoriel appliqué a 3. Le résultat est utilisé (stocké dans a)
    a                       # fonction get appliquée à a, puis envoyé à show pour affichage
    show(get(a))            # idem
    print(t(a))             # fonction get appliqué à a, puit t appliqué à get(a), le tout est envoyé a print.
    print(t(get(a)))        # idem
    [[[a terme, on aura le choix entre cette écriture et une écriture un peu plus objet : f(a,b,c) pourra aussi s'écrire a.f(b,c)]]]

    70. Plusieurs arguments sont une suite d'argument (au singulier, 80) séparés par des virgules.
    80. Un argument est une expression arithmétique. Cela peut être un littéral (exemple : TRUE ; 3 ; 4.5 ; "bon" ; c(2,3,1)), une variable, une fonction retournant une valeur, ou une combinaison de tout cela via des opérations. Un peu plus formellement, un argument est un nom d'argument (90) suivit du signe "=" puis d'une expression (100). Le nom d'argument et le "=" sont optionnels.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    type="Integer"
    value=3+f(6,g(a[4] AND a[7]))   # Pas très beau, mais possible
    "bonjour"
    90. Un nom d'argument est un <IDENTIFIANT>.
    100. Une expression est un ensemble de valeurs combinées entres elles par des opérateurs binaires (120).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    3*2^3-5*(3+1)
    TRUE AND FALSE XOR TRUE
    3+f(3,4)-a[3]
    120. Un opérateur binaire est un opérateur mathématique qui prend deux valeurs et qui en retourne une.
    130. Une valeur est un optionnellement un opérateur unaire (135) suivit soit d'un littéral (140), soit d'une variable (180), soit d'une expression entre parenthèses (100), soit une fonction (60) (Celle-ci doit retourner une valeur mais ça n'est pas à la grammaire de vérifier ce genre de choses).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    3            # litteral 3
    -a           # opposé de la variable a
    (3+9)        # expression entre parenthèses
    f(3)         # fonction f avec pour argument 3
    135. Un opérateur unaire est soit <MINUS>, soit <NOT>
    140. Un littéral est un <LIT_LOGICAL>, un <LIT_INTEGER>, un <LIT_NUMERIC>, un <LIT_CHARACTER>, un factor (150), un ordered (160) ou un type composé (170).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    TRUE
    2
    -2.3
    !FALSE
    "Bonjour"
    "F" in c("E","Z","F","P")
    "B" in c("E"<"D"<"C"<"B"<"A")
    list(1,"bonjour",TRUE,c(1,2))
    150. Un factor est un <LIT_CHARACTER> qui fait parti d'un vecteur (non ordonnée) de <LIT_CHARACTER>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "F" in c("E","Z","F","P")
    160. Un ordered est un <LIT_CHARACTER> qui fait parti d'un vecteur ordonnée de <LIT_CHARACTER>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "B" in c("E"<"D"<"C"<"B"<"A")
    170. Un type composé (un vecteur, une série ou une liste) est un ensemble de littéraux (140) tous de même type et de même dimension pour les vecteurs, de même type pour les séries et de type quelconque pour les listes. Cas particulier, un vecteur de vecteur s'appelle une matrix, un vecteur de liste s'appelle un dataFrame (dans ce derniers cas, les listes sont naturellement toutes de même type et de même longueur, comme l'impose le vecteur).
    A noter, le type d'un vecteur n'est pas vecteur, mais vecteur d'integer ou vecteur de numeric,... De même, les listes sont typées. Ainsi, list(3,"H") est de type list d'integer et character. Ainsi, une tentative d'écriture de 3 dans le deuxième élément de la liste déclencherait une erreur (car le deuxième élément est de type character).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    c(1,3,2)                                               # Vecteur d'integer
    series(c(1),c(2,3),c(2))                               # Series (tailles différentes) de vecteur d'integer
    c(c("R","R"),c("A","B"),c("F","E"))                    # Vecteur de vecteur de character (ie matrix de character)
    list(TRUE,"bon",c(1,2))                                # Liste de logical, character et vecteur d'integer
    c(list("tres bon",FALSE,1),list(TRUE,"bon",2))         # Vecteur de liste, tous de même taille
    dataFrame(c(FALSE,TRUE),c("tres bon","bon"),c(1,2))    # Idem, mais sous format dataFrame
    list(c(FALSE,TRUE),c("tres bon","bon"),c(1,2))         # Liste de vecteur tous de même taille
    Note : un dataFrame est un vecteur de liste, mais est stocké sous forme de liste de vecteur (plus simple et plus rapide) et est déclaré avec une syntaxe proche de la liste de vecteur. Cependant, l'acces aux éléments se fait comme un vecteur de liste. Ainsi, M[2,] sera le deuxième élément du vecteur (ie la deuxième liste, c'est à dire la deuxième ligne), M[,3] sera le troisième élément de chaque liste (ie la troisième colonne) et M[2,3] sera le troisième élément de la deuxième liste. Si M est une liste de vecteur, alors la notation serait inversée...

    180. Une variable est un <IDENTIFIANT> suivit optionnellement de plusieurs arguments (70) entre crochets. Les arguments doivent être des entiers positifs, des vecteurs d'entier positif ou des vecteurs de logical (de même longueur que le vecteur auquel ils s'appliquent).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    nom
    taille[3]
    taille[c(TRUE,FALSE,TRUE)]
    notes[f(1),]
    notes[2,4]
    190. Une structure est soit un if (200), soit un switch (210), soit un for (220), soit un while (230), soit un until (235), soit repeat (240).

    200. La syntaxe d'un if est <IF> logical <THEN> instruction (30) <ELSE> instruction (30) <END_ELSE>. Au niveau de la grammaire, le logical est identifié par une expression (100). Le "<ELSE> bloc" est optionnel. Le <END_ELSE> est (hélas) également optionnel.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if(a==3){
       cat(a)
    }else{ 
       cat(a^2)
    }endIf
    
    if(a<=3){
       cat(a^2)
    }
    
    if(a<=3) cat(a^2) else cat(a^3)
    210. La syntaxe d'un switch est <SWITCH><OPEN_PAR>variable (180) <CLOSE_PAR><IS> <CASE> expression (100) <DO> instruction (30) <ELSE> instruction (30) <END_SWITCH>. Les "<CASE> expression <DO> instruction" peuvent être en nombre variable. Le "<ELSE> instruction" est optionnel. Cette structure permet de coder tous les switch disponible en R++ (switch, switchBreak et switchCont), seul le mot clef <SWITCH> change.
    Enfin, la variable est optionnelle. Sa suppression permet de coder le switch généralisé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    switch(toto){
       case("E"){cat("EE")}
       case("F"){cat("FF")}
       else{cat("EF)}
    }endSwitch
    
    switch{ 
       case(toto=="E"){cat("EE")}
       case(toto=="G" and titi>6){cat("RR")}
       case(titi>3){cat("EFR")}
    }
    
    switchAll{ 
       case(toto=="E"){cat("EE")}
       case(toto=="G" and titi>6){cat("RR")}
       case(titi>3){cat("EFR")}
    }endSwitch
    220. La syntaxe d'un for est <FOR> variable (180) <IN> expression (100) <DO> instruction (30) <END_FOR>. L'expression doit nécessairement être un vecteur, mais cela sera vérifié au typage. Le <END_FOR> est optionnel.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for(i in c(1,2,3,4,5)){     # For appliqué à un bloc
       a <- a+i^2
    }
    
    for(i in c(1,2,3,4,5))      # For appliqué à une définition de variable, avec le endFor
       a <- a+i^2
    endFor
    
    for(i in c(1,2,3,4,5))      # Idem, sans le endFor 
       a <- a+i^2
    230. La syntaxe d'un while est <WHILE> logical <DO> instruction (30) <END_WHILE>. Le logical est identifié par une expression (100). Le <END_WHILE> est optionnel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while(i<5){
       i <- i + 1
       cat(i^2,"\n")
    }endWhile

    235. La syntaxe d'un until est la même que celle du while :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    until(i>=5){
       i <- i + 1
       cat(i^2,"\n")
    }endUntil
    240. La syntaxe d'un repeat est <REPEAT> instruction (30) <WHILE> logical <END_WHILE>. Le logical est identifié par une expression (100). Le <END_REPEAT> est optionnel. Le <WHILE> peut être remplacé par un <UNTIL>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    repeat{ 
       i <- i + 1
       cat(i^2,"\n")
    }while(i<5)
    
    repeat{ 
       i <- i + 1
       cat(i^2,"\n")
    }until(i>=5)
    250. Une fonction est définie par un nom, un type (signature) et le corps de la fonction. La syntaxe est la suivante : <TYPE> nom de la fonction <ASSIGN> <FUNCTION> liste de variables typées (260) puis corps de la fonction. Le nom de la fonction est un <IDENTIFIANT> (90). Le corps de la fonction est une instruction (30).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Integer toto <- function(Integer ref x, Integer val y, Integer z){
       z <- x+y
       return(z)
    }
    260. Une variable typée est un <TYPE> optionnellement suivit du mot clef <VAL> ou <REF> (précisant, dans le cadre d'un appel de fonction, si l'argument doit être passé par valeur ou par référence) puis suivit d'un <IDENTIFIANT>. La syntaxe pour <VAL> et <REF> est à réfléchir ("val"/"ref" ? "="/"<-"? " "/"="?)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Integer toto 		# variable entière toto
    Integer val toto        # variable entière toto, passée par valeur
    Toto ref titi		# objet titi, de classe Toto, passé par référence
    Note : si le mode de transmission des arguments "ref" ou "val" n'est pas précisé explicitement, il est déterminé par R++ de la manière suivante : si la variable n'est pas modifiée, elle est transmise par ref. Si elle est modifiée, elle est transmise par val.

    2 En diagramme
    Je ne sais pas si ça sert a quelque chose, mais c'est joli ! [[[Ne prend pas en compte les dernières modifications de la grammaire.]]]

    3 Définition des token

    3.0 Quelques règles

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    .                             # point est l'opérateur utilisé pour appliquer une fonction (méthode) à une variable toto.length(). On ne peut plus l'utiliser dans un nom de variable (comme on faisait dans R)
    ~                             # tilde signifie "en fonction de". Il sera utilisé dans les tests ou pour définir les formules

    3.1 Expressions régulières

    [[[Certains langages permettent d'utiliser les alphabets spécifiques dans les noms de variable (par exemple définir une variable "mariée". A terme, je pense que c'est une bonne chose à inclure.]]]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    letterMaj		[A-Z]
    letterMin		[a-z]
    letter			letterMaj | letterMin
    digit			[0_9]
    digitNotNul		[1_9]
    other			é | è | ç | à | ê | ù
    ascii			letter | digit | other
    3.2 Littéraux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    LIT_LOGICAL		TRUE | FALSE
    LIT_INTEGER		("-"|"+")? (digitNotNul digit* | "0")
    LIT_NUMERIC		LIT_INTEGER "." digit+ ("E" LIT_INTEGER)?
    LIT_CHARACTER		QUOTE1 ascii* QUOTE1 | QUOTE2 ascii* QUOTE2 | QUOTE3 ascii* QUOTE3
    LIT_VECTOR              "c"
    LIT_SUITE               "suite"
    LIT_LIST                "list"
    LIT_TYPE_COMPOSE        LIT_VECTOR | LIT_SUITE | LIT_LIST
    3.3 Les mots clefs du langage

    [[[Note : a terme, on voudrait pouvoir écrire if a==3 then cat("E") else cat("T") endIf alors que dans R, on est (plus ou moins) obligé d'écrire if(a==3){cat("E")}else{cat("T")}. Résultat, pour coller à la définition (200), on en est rendu à définir des choses comme <THEN> = ")"...]]]


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    IF		if(
    THEN		)
    ELSE		else
    END_IF		endIf [[[N'existe pas sous R... Sera optionnel]]]
    SWITCH		switch
    SWITCH_ALL	switchAll
    SWITCH_Break	switchBreak
    IS		)
    CASE		case(
    DO		)
    END_SWITCH	endSwitch
    FOR		for(
    IN		in
    DO		)
    END_FOR	        endFor [[[N'existe pas sous R... Sera optionnel]]]
    WHILE		while(
    END_WHILE	endWhile [[[N'existe pas sous R... Sera optionnel]]]
    REPEAT		repeat
    UNTIL		until
    END_UNTIL		endUntil
    FUNCTION		function
    END_FUNCTION		endFunction
    
    IS_EQUAL	isEqual
    T		t
    NB_ROW		nbRow
    NB_COL		nbCol
    NB_CHAR		nbChar
    ANY		any
    READFILE	readFile
    AS_CHARACTER 	asCharater
    COL		col
    ROW		row
    3.4 Operateurs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    PLUS		+
    MINUS		-
    MULT		*
    DIV		/
    
    AND		AND
    OR		OR
    EQUAL		==
    LOWER		<
    NOT		!
    
    PASTE		paste
    3.5 Identifiants

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IDENTIFIANT	letterMin (letter|digit)*
    TYPE 		letterMaj (letter|digit)*
    3.6 Ponctuation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    COMMA		,
    DOT		.
    OPEN_PAR	(
    CLOSE_PAR	)
    OPEN_BRAC	[
    CLOSE_BRAC	]
    OPEN_ACC	}
    CLOSE_ACC	}
    
    QUOTE1		'
    QUOTE2		"
    QUOTE3		"""
    ASSIGN		<-
    4 Règles syntaxiques

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    10.  programme       -> instruction*
    30.  instruction     -> definition | singleInstruc
    33.  singleInstruc         -> useFunction | structure | blocInstruction
    35.  blocInstruction -> <OPEN_ACC> instruction* <CLOSE_ACC>
    50.  definition        -> defineVariable | defineFunction
    55.  defineVariable    -> variable <ASSIGN> expression 
    60.  useFunction       -> <KEY_FUNCTION> <OPEN_PAR> arguments? <CLOSE_PAR> |  expression
    70.  arguments       -> argument (<COMMA> argument)*
    80.  argument        -> (nomDArgument <EQUAL>)? expression
    90.  nomDArgument    -> <IDENTIFIANT>
    
    100. expression      -> valeur (operateurBin valeur)*
    120. operateurBin    -> <PLUS> | <MULT> | <AND> | <OR> | <LOWER>
    130. valeur          -> operateurUni? (litteral | variable | <OPEN_PAR> expression <CLOSE_PAR> | useFunction )
    135. operateurUni    -> <NOT> | <MINUS>
    140. litteral        -> <LIT_LOGICAL> | <LIT_INTEGER> | <LIT_NUMERIC> | <LIT_CHARACTER> | factor | ordered | typeCompose
    150. factor          -> <LIT_CHARACTER> <IN> <LIT_VECTOR> <OPEN_PAR> <LIT_CHARACTER> (<COMMA> <LIT_CHARACTER>)* <CLOSE_PAR>
    160. ordered         -> <LIT_CHARACTER> <IN> <LIT_VECTOR> <OPEN_PAR> <LIT_CHARACTER> (<LOWER> <LIT_CHARACTER>)* <CLOSE_PAR>
    170. typeCompose     -> <LIT_TYPE_COMPOSE> <OPEN_PAR> litteral (<COMMA> litteral)* <CLOSE_PAR>
    180. variable        -> <IDENTIFIANT> (<OPEN_BRAC> arguments <CLOSE_BRAC>)?
    
    190. structure       -> if | switch | for | while |until | repeat 
    200. if              -> <IF> expression <THEN> bloc (<ELSE> bloc)? <ENDIF>?
    210. switch          -> (<SWITCH> | <SWITCH_ALL> | <SWITCH_BREAK>) (<OPEN_PAR> variable <CLOSE_PAR>)? <IS> (<CASE> expression <DO> bloc)* (<ELSE> bloc)? <END_SWITCH>
    220. for             -> <FOR> variable <IN> expression <DO> bloc <END_FOR>?
    230. while           -> <WHILE> expression <DO> bloc <END_WHILE>?
    235. until           -> <UNTIL> expression <DO> bloc <END_UNTIL>?
    240. repeat          -> <REPEAT> bloc (<WHILE> | <UNTIL>) expression <END_REPEAT>?
    250. function        -> <TYPE> <IDENTIFIANT> <ASSIGN> <FUNCTION> <OPEN_PAR> typedVariable? <CLOSE_PAR> bloc <END_FUNCTION>?
    260. typedVariable   -> <TYPE> (<VAL>|<REF>)? <IDENTIFIANT>
    5 Exemple de code R++ V0.1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
      /**************/
     /* structures */
    /**************/
    
    majeur <- TRUE
    
    if(majeur){ 
      salaire <- 1000
    }else{
      salaire <- 100
    }
    
    for(nbFrere in c(1,3,5,2,0,3)){
       switch(nbFrere){
          case(0){cat("Ah ?")}
          case(1){cat("Cool.")}
          case(2){cat("Wahou !")}
          else{("Pauvre maman !!!")}
       }
    }
    
    while(majeur){
      majeur <- FALSE
    }
    
    nbFrere <- 1
    repeat{
      nbFrere <- nbFrere + 1
    until(nbFrere<5)
    
    switchBreak{
       case(nbFrere==0){cat("0")}
       case(nbFrere>=4){cat("Trop !")}
    }
    
    
      /*************/
     /* fonctions */
    /*************/
    
    Integer carre <- function(Integer val x){
       return(x^2)
    }
    
    carre(nbFrere)
    carre(3)
    
    Numeric volume <- function(Numeric long, Numeric larg, Numeric haut){
       Numeric surface <- function(Numeric longueur, Numeric largeur){
          return(longueur*largeur)
       }
       return(haut*surface(longeur=long,largeur=larg))
    }
    
    volume(3,2,4)

  2. #2
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2013
    Messages : 7
    Points : 10
    Points
    10

    Par défaut méthodes

    Bonjour Christophe, je n'aurais pas mis l'appel de fonction a.f() pour l'instant puisque les objets sont pour la v0.3. D'autant qu'on ne peux pas définir de méthode mais seulement des fonctions globales.

    Autre remarque sur les fonctions: il faut décider si on dit "méthode" ou "fonction" et n'utiliser qu'un seul terms, sauf si il y a une différence et dans ce cas il faut la préciser.

    P.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2013
    Messages : 7
    Points : 10
    Points
    10

    Par défaut Autre remarque sur les méthodes

    Bonjour, j'ai une autre remarque sur l'appel de méthode, qui m'ennuie sérieusement.

    Actuellement il semble possible de faire:

    x.set(32)

    même si x n'est pas encore défini (donc équivalent à x <- 32).

    Pour moi c'est une mauvaise idée car cela va à l'encontre de la philiosophie objet. Je m'explique ci-dessous.

    La notation x.f(...) signifie "appeler la méthode f de l'objet x". L'idée étant que *à l'exécution* le choix de la méthode f se fera en fonction du type de x (à cause de l'héritage on ne peux pas savoir le type de x à l'avance).

    Mais lorsque x n'existe pas encore, alors que signifie x.f(...)? On ne peut pas le savoir puisque on ne sait pas le type de x.

    Vous allez me répondre "si on le connais c'est le type de l'argument, dans x.set(32) le type de x c'est int puisqe 32 est de type int". Et je répondrai que ce n'est pas si simple. Supposons que je définisse la classe C, avec une méthode qui s'appelle set et qui prend en argument un int. maintenant il y a deux façon de typer x.set(32), soit x est un int, soit x est un C.

    Une proposition:
    interdire la redéfinition de la méthode set. C'est une méthode statique spéciale qui a le comportement suivant:

    x.set(e) affecte la valeur de l'expression e dans la variable x si x existe, et sinon crée une variable du même type que y, appelée "x" et lui donne la même valeur.

    Amicalement,

    P.

  4. #4
    Membre éclairé

    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    septembre 2007
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Santé

    Informations forums :
    Inscription : septembre 2007
    Messages : 200
    Points : 714
    Points
    714

    Par défaut

    Citation Envoyé par P.Courtieu Voir le message
    Bonjour Christophe, je n'aurais pas mis l'appel de fonction a.f() pour l'instant puisque les objets sont pour la v0.3.
    T'as raison. On peut juste laisser le parser accepter a.f() sans pour autant l'implementer sémantiquement ? Quand j'ai écrit la V0.2, j'ai déjà en arrière pensé la V0.3. Donc je me suis dit autant introduire tout de suite la notation qu'on utilisera plus tard...

    Autre remarque sur les fonctions: il faut décider si on dit "méthode" ou "fonction" et n'utiliser qu'un seul terms, sauf si il y a une différence et dans ce cas il faut la préciser.
    Suite a notre discution de ce midi, on pourrait dire "method" pour les fonctions qui s'appliquent à un objet et fonction pour les fonctions qui sont indépendantes des objets ? Genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a.f() # f est une méthode
    g(a)  # g est une fonction
    Pour les experts java, ca revient a appeler "fonction" les méthodes static de java et "method" les méthodes non static de java. Ca vous va ?

  5. #5
    Membre éclairé

    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    septembre 2007
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Santé

    Informations forums :
    Inscription : septembre 2007
    Messages : 200
    Points : 714
    Points
    714

    Par défaut

    Citation Envoyé par P.Courtieu Voir le message
    La notation x.f(...) signifie "appeler la méthode f de l'objet x".
    Oui. Mais dans R++, l'instruction
    n'existera pas. Si on veut affecter, on utilise "<-".


    Vous allez me répondre...
    Et je répondrai...
    Toi non plus t'as pas d'ami ?
    :-)
    Supposons que je définisse la classe C, avec une méthode qui s'appelle set et qui prend en argument un int. maintenant il y a deux façon de typer x.set(32), soit x est un int, soit x est un C.
    Sauf que si tu définis une nouvelle classe, il faut que tu appelles le constructeur, il n'y a rien d'automatique. Donc il faudra utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    x <- Integer(32)
    x <- C(32)
    Plus généralement, avec constructeur systématique, on a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    a <- Integer(3)
    b <- Numeric(4)
    c <- Character("toto")
    d <- Vector(Integer(2,3,2))
    e <- DataFrame(Vector(Integer(12,23,23),Vector(Logical(true,false,true)))
    f <- List(Integer(2,3,2),true,Vector(Numeric(2.3,2.4)))
    g <- SuperClass(3,5,true)
    Sauf que c'est un peu lourd. Donc, sucre syntaxique, on peut parfois supprimer le constructeur. Plus précisément, on peut supprimer "Logical", "Integer", "Numeric", "Character" et "Vector". Ainsi, le code précédent devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    a <- 3                    # Creation d'un Integer
    b <- 4.0                  # Création d'un Numeric. Attention, b <- 4 type b comme un Integer
    c <- "toto"               # Création d'un Character
    d <- (2,3,2)              # Création d'un vecteur d'Integer
    e <- DataFrame((12,23,23),(true,false,true))  # Création d'un data.frame composé d'un vecteur d'Integer et d'un vecteru de Logical
    f <- List((2,3,2),true,(2.3,2.4))             # Création d'une liste de vecteur d'Integer, d'un logical et d'un vecteur de numeric. 
    g <- SuperClass(3,5,true) # Création d'un objet SuperClass
    C'est tout de même plus léger.

    Une proposition:
    interdire la redéfinition de la méthode set.
    A priori, dans R, le get et le set se disent "[" et "<-". Or il est possible de définir une nouvelle classe, puis de définir les opérateur "[" et "[<-". Personnellement, je trouve ca assez confortable et surtout ca permet d'assurer l’homogénéité du langage : si l'utilisateur à l'habitude de manipuler les matrices M avec M[3,2] et que je définis une nouvelle classe qui est une sorte de matrice étendue, il serait bon que ma nouvelle matrice étendue soit elle aussi manipulable avec des "[ , ]". Ainsi, l'utilisateur pourra inférer ce qu'il connait de matrice a matrice étendu. C'est un des objectifs de R++

    Christophe

  6. #6
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2013
    Messages : 7
    Points : 10
    Points
    10

    Par défaut

    D'accord, donc on prend la syntaxe <- pour l'affectation (avec création de variable si elle n'existe pas), et l'appel de méthode (y compris la méthode set) n'est possible que si l'objet existe déjà. Ça me va. la syntaxe "<-" et la méthode set ne sont donc *pas* la même chose et c'est très bien comme ça.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    août 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : août 2013
    Messages : 7
    Points : 10
    Points
    10

    Par défaut

    Bonjour, une petite remarque sur la syntaxe des vecteurs.

    Comment interpréter l'expression suivante: (1).

    Est-ce l'entier 1 mis entre parenthèses ou bien le vecteur de longueur un contenant l'entier 1?

    Dans le prototype que j'écris pour l'instant c'est l'entier un et pour avoir le vecteur il faut écrire: vector(1).

    Amicalement,
    Pierre




    17. Un type composé (un vecteur, une série ou une liste) est un ensemble de littéraux (14)
    Code :
    Sélectionner tout - Visualiser dans une fenêtre à part

    (1,3,2) # Vecteur d'integer
    series((1),(2,3),(2)) # Series (tailles différentes) de vecteur d'integer
    (("R","R"),("A","B"),("F","E")) # Vecteur de vecteur de character
    list(TRUE,"bon",(1,2)) # Liste de logical, character et vecteur d'integer

  8. #8
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    septembre 2002
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : septembre 2002
    Messages : 925
    Points : 1 944
    Points
    1 944

    Par défaut

    Citation Envoyé par Christophe Genolini Voir le message
    T'as raison. On peut juste laisser le parser accepter a.f() sans pour autant l'implementer sémantiquement ? Quand j'ai écrit la V0.2, j'ai déjà en arrière pensé la V0.3. Donc je me suis dit autant introduire tout de suite la notation qu'on utilisera plus tard...


    Suite a notre discution de ce midi, on pourrait dire "method" pour les fonctions qui s'appliquent à un objet et fonction pour les fonctions qui sont indépendantes des objets ? Genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a.f() # f est une méthode
    g(a)  # g est une fonction
    Pour les experts java, ca revient a appeler "fonction" les méthodes static de java et "method" les méthodes non static de java. Ca vous va ?
    Le terme objet dans sa purete absolue ets 'fonction membre'. Methode est un gallicisme.

    Truc interessant, y a eu des propals C++ pour que tout se fasse via

    f(x);

    dans ce cas, soit f(X) existe et on l'appelle, soit on cherche si X a une methode f() et on l'appelle. Ca permet de tout unifier.

Discussions similaires

  1. [LambdaProlog] grammaire en Java
    Par khokho dans le forum APIs
    Réponses: 3
    Dernier message: 04/07/2005, 11h26
  2. grammaire yacc lex simili C
    Par BigBarbare dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 16/05/2005, 22h40
  3. Décomposition d'une propriété : grammaire ?
    Par mathieu dans le forum Général Algorithmique
    Réponses: 3
    Dernier message: 04/05/2004, 10h47
  4. Réponses: 2
    Dernier message: 21/05/2002, 11h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo