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 toto tOTO toTO23
1.2 Règles syntaxiques
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
10. Un programme est un ensemble éventuellement vide de plusieurs instructions (30).
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
3 a <- 4 plot(b) for(a in 1:5) cat("X")
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 a <- 4 # Définition plot(a) # Instruction élémentaire
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
5
6 plot(a) # Instruction élémentaire for(a in 1:5){cat("X")} # Structure { # bloc d'instruction a <- a*2 b <- a*3 }
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
4 { a <- 4 for(a in 1:5) cat("X") }
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 a <- 3 Integer f <- function(Integer x){return(x^2)}
[[[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 :
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
- 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
- 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").
[[[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)]]]
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
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 age=4,sexe="h" 4,"h"
90. Un nom d'argument est un <IDENTIFIANT>.
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"
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 type value
120. Un opérateur binaire est un opérateur mathématique qui prend deux valeurs et qui en retourne une.
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]
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 + * AND OR
135. Un opérateur unaire est soit <MINUS>, soit <NOT>
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
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 - !
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
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))
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 "F" in c("E","Z","F","P")
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).
Code : Sélectionner tout - Visualiser dans une fenêtre à part "B" in c("E"<"D"<"C"<"B"<"A")
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).
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...
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
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).
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).
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]
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.
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.
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)
Enfin, la variable est optionnelle. Sa suppression permet de coder le switch généralisé.
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
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
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
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
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 :
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 until(i>=5){ i <- i + 1 cat(i^2,"\n") }endUntil
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
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)
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
4 Integer toto <- function(Integer ref x, Integer val y, Integer z){ z <- x+y return(z) }
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.
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
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.]]]
3.2 Littéraux
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.3 Les mots clefs du langage
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
[[[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> = ")"...]]]
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
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.5 Identifiants
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.6 Ponctuation
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 IDENTIFIANT letterMin (letter|digit)* TYPE letterMaj (letter|digit)*
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 COMMA , DOT . OPEN_PAR ( CLOSE_PAR ) OPEN_BRAC [ CLOSE_BRAC ] OPEN_ACC } CLOSE_ACC } QUOTE1 ' QUOTE2 " QUOTE3 """ ASSIGN <-
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 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>
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)
Partager