|
1 | | -/* description: Parses expressions. */ |
2 | | - |
3 | | -/* lexical grammar */ |
4 | | -%lex |
5 | | -%% |
6 | | -\s+ /* skip whitespace */ |
7 | | - |
8 | | -(\-(webkit|moz)\-)?calc\b return 'CALC'; |
9 | | - |
10 | | -[a-z][a-z0-9-]*\s*\((?:(?:\"(?:\\.|[^\"\\])*\"|\'(?:\\.|[^\'\\])*\')|\([^)]*\)|[^\(\)]*)*\) return 'FUNCTION'; |
11 | | - |
12 | | -"*" return 'MUL'; |
13 | | -"/" return 'DIV'; |
14 | | -"+" return 'ADD'; |
15 | | -"-" return 'SUB'; |
16 | | - |
17 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)px\b return 'LENGTH'; |
18 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)cm\b return 'LENGTH'; |
19 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)mm\b return 'LENGTH'; |
20 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)in\b return 'LENGTH'; |
21 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)pt\b return 'LENGTH'; |
22 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)pc\b return 'LENGTH'; |
23 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)deg\b return 'ANGLE'; |
24 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)grad\b return 'ANGLE'; |
25 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)rad\b return 'ANGLE'; |
26 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)turn\b return 'ANGLE'; |
27 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)s\b return 'TIME'; |
28 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)ms\b return 'TIME'; |
29 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)Hz\b return 'FREQ'; |
30 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)kHz\b return 'FREQ'; |
31 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)dpi\b return 'RES'; |
32 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)dpcm\b return 'RES'; |
33 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)dppx\b return 'RES'; |
34 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)em\b return 'EMS'; |
35 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)ex\b return 'EXS'; |
36 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)ch\b return 'CHS'; |
37 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)rem\b return 'REMS'; |
38 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)vw\b return 'VWS'; |
39 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)vh\b return 'VHS'; |
40 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)vmin\b return 'VMINS'; |
41 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)vmax\b return 'VMAXS'; |
42 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)\% return 'PERCENTAGE'; |
43 | | -([0-9]+("."[0-9]+)?|"."[0-9]+)\b return 'NUMBER'; |
44 | | - |
45 | | -"(" return 'LPAREN'; |
46 | | -")" return 'RPAREN'; |
47 | | - |
48 | | -<<EOF>> return 'EOF'; |
49 | | - |
50 | | -/lex |
51 | | - |
52 | | -%left ADD SUB |
53 | | -%left MUL DIV |
54 | | -%left UPREC |
55 | | - |
56 | | - |
57 | | -%start expression |
58 | | - |
59 | | -%% |
60 | | - |
61 | | -expression |
62 | | - : math_expression EOF { return $1; } |
63 | | - ; |
64 | | - |
65 | | - math_expression |
66 | | - : CALC LPAREN math_expression RPAREN { $$ = $3; } |
67 | | - | math_expression ADD math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; } |
68 | | - | math_expression SUB math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; } |
69 | | - | math_expression MUL math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; } |
70 | | - | math_expression DIV math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; } |
71 | | - | LPAREN math_expression RPAREN { $$ = $2; } |
72 | | - | function { $$ = $1; } |
73 | | - | css_value { $$ = $1; } |
74 | | - | value { $$ = $1; } |
75 | | - ; |
76 | | - |
77 | | - value |
78 | | - : NUMBER { $$ = { type: 'Value', value: parseFloat($1) }; } |
79 | | - | SUB NUMBER { $$ = { type: 'Value', value: parseFloat($2) * -1 }; } |
80 | | - ; |
81 | | - |
82 | | - function |
83 | | - : FUNCTION { $$ = { type: 'Function', value: $1 }; } |
84 | | - ; |
85 | | - |
86 | | - css_value |
87 | | - : LENGTH { $$ = { type: 'LengthValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; } |
88 | | - | ANGLE { $$ = { type: 'AngleValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; } |
89 | | - | TIME { $$ = { type: 'TimeValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; } |
90 | | - | FREQ { $$ = { type: 'FrequencyValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; } |
91 | | - | RES { $$ = { type: 'ResolutionValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; } |
92 | | - | EMS { $$ = { type: 'EmValue', value: parseFloat($1), unit: 'em' }; } |
93 | | - | EXS { $$ = { type: 'ExValue', value: parseFloat($1), unit: 'ex' }; } |
94 | | - | CHS { $$ = { type: 'ChValue', value: parseFloat($1), unit: 'ch' }; } |
95 | | - | REMS { $$ = { type: 'RemValue', value: parseFloat($1), unit: 'rem' }; } |
96 | | - | VHS { $$ = { type: 'VhValue', value: parseFloat($1), unit: 'vh' }; } |
97 | | - | VWS { $$ = { type: 'VwValue', value: parseFloat($1), unit: 'vw' }; } |
98 | | - | VMINS { $$ = { type: 'VminValue', value: parseFloat($1), unit: 'vmin' }; } |
99 | | - | VMAXS { $$ = { type: 'VmaxValue', value: parseFloat($1), unit: 'vmax' }; } |
100 | | - | PERCENTAGE { $$ = { type: 'PercentageValue', value: parseFloat($1), unit: '%' }; } |
101 | | - | SUB css_value { var prev = $2; prev.value *= -1; $$ = prev; } |
102 | | - ; |
| 1 | +/* description: Parses expressions. */ |
| 2 | + |
| 3 | +/* lexical grammar */ |
| 4 | +%lex |
| 5 | + |
| 6 | +%options case-insensitive |
| 7 | + |
| 8 | +%% |
| 9 | +\s+ /* skip whitespace */ |
| 10 | + |
| 11 | +(\-(webkit|moz)\-)?calc\b return 'CALC'; |
| 12 | + |
| 13 | +[a-z][a-z0-9-]*\s*\((?:(?:\"(?:\\.|[^\"\\])*\"|\'(?:\\.|[^\'\\])*\')|\([^)]*\)|[^\(\)]*)*\) return 'FUNCTION'; |
| 14 | + |
| 15 | +"*" return 'MUL'; |
| 16 | +"/" return 'DIV'; |
| 17 | +"+" return 'ADD'; |
| 18 | +"-" return 'SUB'; |
| 19 | + |
| 20 | +([0-9]+("."[0-9]+)?|"."[0-9]+)px\b return 'LENGTH'; |
| 21 | +([0-9]+("."[0-9]+)?|"."[0-9]+)cm\b return 'LENGTH'; |
| 22 | +([0-9]+("."[0-9]+)?|"."[0-9]+)mm\b return 'LENGTH'; |
| 23 | +([0-9]+("."[0-9]+)?|"."[0-9]+)in\b return 'LENGTH'; |
| 24 | +([0-9]+("."[0-9]+)?|"."[0-9]+)pt\b return 'LENGTH'; |
| 25 | +([0-9]+("."[0-9]+)?|"."[0-9]+)pc\b return 'LENGTH'; |
| 26 | +([0-9]+("."[0-9]+)?|"."[0-9]+)deg\b return 'ANGLE'; |
| 27 | +([0-9]+("."[0-9]+)?|"."[0-9]+)grad\b return 'ANGLE'; |
| 28 | +([0-9]+("."[0-9]+)?|"."[0-9]+)rad\b return 'ANGLE'; |
| 29 | +([0-9]+("."[0-9]+)?|"."[0-9]+)turn\b return 'ANGLE'; |
| 30 | +([0-9]+("."[0-9]+)?|"."[0-9]+)s\b return 'TIME'; |
| 31 | +([0-9]+("."[0-9]+)?|"."[0-9]+)ms\b return 'TIME'; |
| 32 | +([0-9]+("."[0-9]+)?|"."[0-9]+)Hz\b return 'FREQ'; |
| 33 | +([0-9]+("."[0-9]+)?|"."[0-9]+)kHz\b return 'FREQ'; |
| 34 | +([0-9]+("."[0-9]+)?|"."[0-9]+)dpi\b return 'RES'; |
| 35 | +([0-9]+("."[0-9]+)?|"."[0-9]+)dpcm\b return 'RES'; |
| 36 | +([0-9]+("."[0-9]+)?|"."[0-9]+)dppx\b return 'RES'; |
| 37 | +([0-9]+("."[0-9]+)?|"."[0-9]+)em\b return 'EMS'; |
| 38 | +([0-9]+("."[0-9]+)?|"."[0-9]+)ex\b return 'EXS'; |
| 39 | +([0-9]+("."[0-9]+)?|"."[0-9]+)ch\b return 'CHS'; |
| 40 | +([0-9]+("."[0-9]+)?|"."[0-9]+)rem\b return 'REMS'; |
| 41 | +([0-9]+("."[0-9]+)?|"."[0-9]+)vw\b return 'VWS'; |
| 42 | +([0-9]+("."[0-9]+)?|"."[0-9]+)vh\b return 'VHS'; |
| 43 | +([0-9]+("."[0-9]+)?|"."[0-9]+)vmin\b return 'VMINS'; |
| 44 | +([0-9]+("."[0-9]+)?|"."[0-9]+)vmax\b return 'VMAXS'; |
| 45 | +([0-9]+("."[0-9]+)?|"."[0-9]+)\% return 'PERCENTAGE'; |
| 46 | +([0-9]+("."[0-9]+)?|"."[0-9]+)\b return 'NUMBER'; |
| 47 | + |
| 48 | +"(" return 'LPAREN'; |
| 49 | +")" return 'RPAREN'; |
| 50 | + |
| 51 | +<<EOF>> return 'EOF'; |
| 52 | + |
| 53 | +/lex |
| 54 | + |
| 55 | +%left ADD SUB |
| 56 | +%left MUL DIV |
| 57 | +%left UPREC |
| 58 | + |
| 59 | + |
| 60 | +%start expression |
| 61 | + |
| 62 | +%% |
| 63 | + |
| 64 | +expression |
| 65 | + : math_expression EOF { return $1; } |
| 66 | + ; |
| 67 | + |
| 68 | + math_expression |
| 69 | + : CALC LPAREN math_expression RPAREN { $$ = $3; } |
| 70 | + | math_expression ADD math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; } |
| 71 | + | math_expression SUB math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; } |
| 72 | + | math_expression MUL math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; } |
| 73 | + | math_expression DIV math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; } |
| 74 | + | LPAREN math_expression RPAREN { $$ = $2; } |
| 75 | + | function { $$ = $1; } |
| 76 | + | css_value { $$ = $1; } |
| 77 | + | value { $$ = $1; } |
| 78 | + ; |
| 79 | + |
| 80 | + value |
| 81 | + : NUMBER { $$ = { type: 'Value', value: parseFloat($1) }; } |
| 82 | + | SUB NUMBER { $$ = { type: 'Value', value: parseFloat($2) * -1 }; } |
| 83 | + ; |
| 84 | + |
| 85 | + function |
| 86 | + : FUNCTION { $$ = { type: 'Function', value: $1 }; } |
| 87 | + ; |
| 88 | + |
| 89 | + css_value |
| 90 | + : LENGTH { $$ = { type: 'LengthValue', value: parseFloat($1), unit: /[a-z]+/i.exec($1)[0] }; } |
| 91 | + | ANGLE { $$ = { type: 'AngleValue', value: parseFloat($1), unit: /[a-z]+/i.exec($1)[0] }; } |
| 92 | + | TIME { $$ = { type: 'TimeValue', value: parseFloat($1), unit: /[a-z]+/i.exec($1)[0] }; } |
| 93 | + | FREQ { $$ = { type: 'FrequencyValue', value: parseFloat($1), unit: /[a-z]+/i.exec($1)[0] }; } |
| 94 | + | RES { $$ = { type: 'ResolutionValue', value: parseFloat($1), unit: /[a-z]+/i.exec($1)[0] }; } |
| 95 | + | EMS { $$ = { type: 'EmValue', value: parseFloat($1), unit: 'em' }; } |
| 96 | + | EXS { $$ = { type: 'ExValue', value: parseFloat($1), unit: 'ex' }; } |
| 97 | + | CHS { $$ = { type: 'ChValue', value: parseFloat($1), unit: 'ch' }; } |
| 98 | + | REMS { $$ = { type: 'RemValue', value: parseFloat($1), unit: 'rem' }; } |
| 99 | + | VHS { $$ = { type: 'VhValue', value: parseFloat($1), unit: 'vh' }; } |
| 100 | + | VWS { $$ = { type: 'VwValue', value: parseFloat($1), unit: 'vw' }; } |
| 101 | + | VMINS { $$ = { type: 'VminValue', value: parseFloat($1), unit: 'vmin' }; } |
| 102 | + | VMAXS { $$ = { type: 'VmaxValue', value: parseFloat($1), unit: 'vmax' }; } |
| 103 | + | PERCENTAGE { $$ = { type: 'PercentageValue', value: parseFloat($1), unit: '%' }; } |
| 104 | + | SUB css_value { var prev = $2; prev.value *= -1; $$ = prev; } |
| 105 | + ; |
0 commit comments