Re: [css3-values] Adding min() and max() into calc() grammar

On Wednesday 16 December 2009 22:17:48 L. David Baron wrote:
> In http://www.w3.org/mid/4A71E157.20600@inkedblade.net the working
> group resolved to add min() and max() to calc(), as well as allowing
> them at the top level where calc() is allowed.  I don't think
> anybody has drafted any of the text for this yet, though, so here's
> an attempt at the grammar, which seems to me to be the main
> interesting part.
[...] 
> (I don't see any reason to add min() and max() to <number-term>.)

No reason, except maybe consistency. I don't mind either way. I have 
tried to write down the resulting complete grammar myself and came up 
with the following. The first one allows min() and max() over unitless 
numbers:

S: calc | min | max;
calc: "calc(" S* sum ")" S*;
min: "min(" S* sum [ "," S* sum ]* ")" S*;
max: "max(" S* sum [ "," S* sum ]* ")" S*;
sum: product [ addop product ]*;
addop: "+" S* | "-" S*;
product: [ factor "*" S* ]? dimen
  [ [ "*" | "/" ] S* factor | "mod" S* dimen ]*;
factor: num [ mulop num ]*;
mulop: "*" S* | "/" S* | "mod" S*;
dimen: ["+"|"-"]? [ DIMENSION | min | max | "(" S* sum ")" S* ];
num: ["+"|"-"]? [ NUMBER | umin | umax | "(" S* factor ")" S* ];
umin: "min(" S* factor [ "," S* factor ] ")" S*;
umax: "max(" S* factor [ "," S* factor ] ")" S*;

Here is one where min() and max() only work over values with dimensions:

S: calc | min | max;
calc: "calc(" S* sum ")" S*;
min: "min(" S* sum [ "," S* sum ]* ")" S*;
max: "max(" S* sum [ "," S* sum ]* ")" S*;
sum: product [ addop product ]*;
addop: "+" S* | "-" S*;
product: [ factor "*" S* ]? dimen
  [ [ "*" | "/" ] S* factor | "mod" S* dimen ]*;
factor: num [ mulop num ]*;
mulop: "*" S* | "/" S* | "mod" S*;
dimen: ["+"|"-"]? [ DIMENSION | min | max | "(" S* sum ")" S* ];
num: ["+"|"-"]? [ NUMBER | "(" S* factor ")" S* ];

There is an extra constraint that the units of the DIMENSION tokens must 
be valid for the property they are used on. E.g., both 'width' 
and 'pause' accept 'calc()' as a value, but the former only accepts 
length units, while the latter only accepts time units. You cannot 
do 'calc(5cm + 3s)'. I don't think it's worth writing separate grammars 
for the different dimensions.

I hesitated over one thing: is is allowed to write a unary minus before 
a parenthesis or a nested max()?

    7em + -(4cm - 3%) + -max(3%, 4pc)

It wasn't allowed in the latest draft, nor in David's modifications, but 
I added it anyway.

I don't think the grammar is LL(1) yet.



Bert
-- 
  Bert Bos                                ( W 3 C ) http://www.w3.org/
  http://www.w3.org/people/bos                               W3C/ERCIM
  bert@w3.org                             2004 Rt des Lucioles / BP 93
  +33 (0)4 92 38 76 92            06902 Sophia Antipolis Cedex, France

Received on Wednesday, 17 February 2010 16:47:51 UTC