Spécifications CSS
Annexe D : La grammaire de CSS2
Contents
Cet annexe est normatif.
La grammaire ci-dessous définit la syntaxe de CSS2. C'est, en quelque sorte, un sur-ensemble de CSS2, dans la mesure où cette spécification impose des contraintes sémantiques supplémentaires que n'exprime pas cette grammaire. Un agent utilisateur conforme doit aussi adhérer aux règles d'interprétation ascendantes, à la convention de notation des propriétés et valeurs et celle de la notation des unités. Le langage du document pouvant en plus imposer certaines restrictions (ex. en HTML, il existe des restrictions sur les valeurs admises par l'attribut "class").
D.1 La grammaire
La grammaire ci-dessous est LL(1) (mais noter que la plupart des agents utilisateurs ne devraient pas l'employer telle quelle car celle-ci n'exprime pas les conventions d'interprétation, mais seulement la syntaxe CSS2). Le format de ces productions est optimisé pour une consultation humaine, certaines notations raccourcies allant au-delà de Yacc (voir [YACC]) étant employées :
- * : 0 ou plus ;
- + : 1 ou plus ;
- ? : 0 ou 1 ;
- | : options séparées ;
- [ ] : regroupement.
Voici les productions :
stylesheet : [ CHARSET_SYM S* STRING S* ';' ]? [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* [ [ ruleset | media | page | font_face ] [S|CDO|CDC]* ]* ; import : IMPORT_SYM S* [STRING|URI] S* [ medium [ ',' S* medium]* ]? ';' S* ; media : MEDIA_SYM S* medium [ ',' S* medium ]* '{' S* ruleset* '}' S* ; medium : IDENT S* ; page : PAGE_SYM S* IDENT? pseudo_page? S* '{' S* declaration [ ';' S* declaration ]* '}' S* ; pseudo_page : ':' IDENT ; font_face : FONT_FACE_SYM S* '{' S* declaration [ ';' S* declaration ]* '}' S* ; operator : '/' S* | ',' S* | /* vide */ ; combinator : '+' S* | '>' S* | /* vide */ ; unary_operator : '-' | '+' ; property : IDENT S* ; ruleset : selector [ ',' S* selector ]* '{' S* declaration [ ';' S* declaration ]* '}' S* ; selector : simple_selector [ combinator simple_selector ]* ; simple_selector : element_name? [ HASH | class | attrib | pseudo ]* S* ; class : '.' IDENT ; element_name : IDENT | '*' ; attrib : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S* [ IDENT | STRING ] S* ]? ']' ; pseudo : ':' [ IDENT | FUNCTION S* IDENT S* ')' ] ; declaration : property ':' S* expr prio? | /* vide */ ; prio : IMPORTANT_SYM S* ; expr : term [ operator term ]* ; term : unary_operator? [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | TIME S* | FREQ S* | function ] | STRING S* | IDENT S* | URI S* |RGB S* |UNICODERANGE S* | hexcolor ; function : FUNCTION S* expr ')' S* ; /* * Il y a une contrainte sur la couleur, * celle-ci devant avoir 3 ou 6 chiffres hexadécimaux (ex. [0-9a-fA-F]) * après le signe "#" ; ex. "#000" est OK, mais pas "#abcd". */ hexcolor : HASH S* ;
D.2 Le scanner lexical
Ce qui suit est l'atomiseur, écrit en notation Flex (voir [FLEX]) L'atomiseur est insensible à la casse.
Les deux expressions "\377" qui surviennent représentent le nombre du caractère le plus élevé que Flex peut gérer (en décimal : 255). Celles-ci devraient être interprétées comme étant "\4177777" (en décimal : 1114111), lequel est le code du point le plus élevé pour Unicode/ISO-10646.
%option case-insensitive h [0-9a-f] nonascii [\200-\377] unicode \\{h}{1,6}[ \t\r\n\f]? escape {unicode}|\\[ -~\200-\377] nmstart [a-z_]|{nonascii}|{escape} nmchar [a-z0-9-_]|{nonascii}|{escape} string1 \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\" string2 \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\' ident {nmstart}{nmchar}* name {nmchar}+ num [0-9]+|[0-9]*"."[0-9]+ string {string1}|{string2} url ([!#$%&*-~]|{nonascii}|{escape})* w [ \t\r\n\f]* nl \n|\r\n|\r|\f range \?{1,6}|{h}(\?{0,5}|{h}(\?{0,4}|{h}(\?{0,3}|{h}(\?{0,2}|{h}(\??|{h}))))) %% [ \t\r\n\f]+ {return S;} \/\*[^*]*\*+([^/][^*]*\*+)*\/ /* ignorer les commentaires */ "<!--" {return CDO;} "-->" {return CDC;} "~=" {return INCLUDES;} "|=" {return DASHMATCH;} {string} {return STRING;} {ident} {return IDENT;} "#"{name} {return HASH;} "@import" {return IMPORT_SYM;} "@page" {return PAGE_SYM;} "@media" {return MEDIA_SYM;} "@font-face" {return FONT_FACE_SYM;} "@charset" {return CHARSET_SYM;}"@"{ident} {return ATKEYWORD;}"!{w}important" {return IMPORTANT_SYM;} {num}em {return EMS;} {num}ex {return EXS;} {num}px {return LENGTH;} {num}cm {return LENGTH;} {num}mm {return LENGTH;} {num}in {return LENGTH;} {num}pt {return LENGTH;} {num}pc {return LENGTH;} {num}deg {return ANGLE;} {num}rad {return ANGLE;} {num}grad {return ANGLE;} {num}ms {return TIME;} {num}s {return TIME;} {num}Hz {return FREQ;} {num}kHz {return FREQ;} {num}{ident} {return DIMEN;} {num}% {return PERCENTAGE;} {num} {return NUMBER;} "url("{w}{string}{w}")" {return URI;} "url("{w}{url}{w}")" {return URI;} {ident}"(" {return FUNCTION;} U\+{range} {return UNICODERANGE;} U\+{h}{1,6}-{h}{1,6} {return UNICODERANGE;} . {return *yytext;}
D.3 La comparaison entre les atomisations de CSS2 et CSS1
Il existe quelques différences entre la syntaxe spécifiée dans la recommandation CSS1 ([CSS1]) et celle spécifiée plus haut. La plupart de ces différences étant dues aux nouveaux atomes de CSS2 qui n'existaient pas en CSS1. Et les autres étant dues au fait que la grammaire a été récrite pour une meilleure lisibilité. Cependant, il y a certains changements incompatibles, ceux-ci étaient considérés comme des erreurs de la syntaxe CSS1. Leur explication suit :
- Le codage des caractères des feuilles de style CSS1 ne pouvaient avoir lieu que sur 1 octet, comme pour ASCII et ISO-8859-1. CSS2 n'a plus ces limitations. Dans les faits, l'extrapolation à partir de l'atomiseur CSS1 ne présentant pas de grandes difficultés, certains agents utilisateurs acceptaient les codages sur deux octets ;
- CSS1 n'admettait que quatre chiffres hexadécimaux après la barre oblique inverse (\) pour la désignation des caractères Unicode, CSS2 en admet six. En plus, CSS2 admet un caractère blanc pour la délimitation d'une séquence de masquage. Par exemple, selon CSS1, la chaîne "\abcdef" est formée de 3 lettres (\abcd, e et f), selon CSS2, celle-ci n'en a qu'une (\abcdef) ;
- Le caractère tabulation (ASCII 9) n'était pas admis dans une chaîne. C'est pourquoi, comme en CSS1, on n'employait les chaînes que pour les noms des polices et pour les URLs, le seul cas où cela pouvait conduire à une incompatibilité entre CSS1 et CSS2 réside dans une feuille de style dans laquelle le nom d'une famille de polices contient une tabulation ;
- De la même façon en CSS1, les nouvelles lignes (masquées par une barre oblique inverse) n'étaient pas admises ;
- CSS2 interprète un nombre immédiatement suivi par un identificateur comme étant un atome DIMEN (c.à.d. une unité inconnue), CSS1 l'interprétait comme un nombre et un identificateur. Cela signifie que pour CSS1, les déclarations 'font: 10pt/1.2serif' tout comme 'font: 10pt/1.2 serif' étaient valides, mais pour CSS2, l'espace est devenu obligatoire avant "serif" (certains agents utilisateurs acceptaient la première forme mais pas la seconde) ;
-
En CSS1, le nom d'une classe pouvait commencer par un chiffre (".55ft"), à moins qu'il s'agissait d'une
dimension reconnue (".55in"). CSS2 interprète de telles classes comme étant des dimensions inconnues
(ce qui laisse le champs libre pour l'addition ultérieure de nouvelles unités). Pour que la classe ".55ft" soit valide en
CSS2, le premier chiffre doit être masqué (
".\55ft"".\35 5ft").
Version en cache
21/11/2024 09:34:49 Cette version de la page est en cache (à la date du 21/11/2024 09:34:49) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.Document créé le 12/08/2006, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/css-rf-grammar.html
L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.
Références
Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.