-
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathparser.jison
105 lines (90 loc) · 4.73 KB
/
parser.jison
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* description: Parses expressions. */
/* lexical grammar */
%lex
%%
(--[0-9a-z-A-Z-]*) return 'CSS_CPROP';
\s+ /* skip whitespace */
"*" return 'MUL';
"/" return 'DIV';
"+" return 'ADD';
"-" return 'SUB';
([0-9]+("."[0-9]*)?|"."[0-9]+)px\b return 'LENGTH';
([0-9]+("."[0-9]*)?|"."[0-9]+)cm\b return 'LENGTH';
([0-9]+("."[0-9]*)?|"."[0-9]+)mm\b return 'LENGTH';
([0-9]+("."[0-9]*)?|"."[0-9]+)in\b return 'LENGTH';
([0-9]+("."[0-9]*)?|"."[0-9]+)pt\b return 'LENGTH';
([0-9]+("."[0-9]*)?|"."[0-9]+)pc\b return 'LENGTH';
([0-9]+("."[0-9]*)?|"."[0-9]+)deg\b return 'ANGLE';
([0-9]+("."[0-9]*)?|"."[0-9]+)grad\b return 'ANGLE';
([0-9]+("."[0-9]*)?|"."[0-9]+)rad\b return 'ANGLE';
([0-9]+("."[0-9]*)?|"."[0-9]+)turn\b return 'ANGLE';
([0-9]+("."[0-9]*)?|"."[0-9]+)s\b return 'TIME';
([0-9]+("."[0-9]*)?|"."[0-9]+)ms\b return 'TIME';
([0-9]+("."[0-9]*)?|"."[0-9]+)Hz\b return 'FREQ';
([0-9]+("."[0-9]*)?|"."[0-9]+)kHz\b return 'FREQ';
([0-9]+("."[0-9]*)?|"."[0-9]+)dpi\b return 'RES';
([0-9]+("."[0-9]*)?|"."[0-9]+)dpcm\b return 'RES';
([0-9]+("."[0-9]*)?|"."[0-9]+)dppx\b return 'RES';
([0-9]+("."[0-9]*)?|"."[0-9]+)em\b return 'EMS';
([0-9]+("."[0-9]*)?|"."[0-9]+)ex\b return 'EXS';
([0-9]+("."[0-9]*)?|"."[0-9]+)ch\b return 'CHS';
([0-9]+("."[0-9]*)?|"."[0-9]+)rem\b return 'REMS';
([0-9]+("."[0-9]*)?|"."[0-9]+)vw\b return 'VWS';
([0-9]+("."[0-9]*)?|"."[0-9]+)vh\b return 'VHS';
([0-9]+("."[0-9]*)?|"."[0-9]+)vmin\b return 'VMINS';
([0-9]+("."[0-9]*)?|"."[0-9]+)vmax\b return 'VMAXS';
([0-9]+("."[0-9]*)?|"."[0-9]+)\% return 'PERCENTAGE';
([0-9]+("."[0-9]*)?|"."[0-9]+)\b return 'NUMBER';
(calc) return 'NESTED_CALC';
(var) return 'CSS_VAR';
([a-z]+) return 'PREFIX';
"(" return 'LPAREN';
")" return 'RPAREN';
"," return 'COMMA';
<<EOF>> return 'EOF';
/lex
%left ADD SUB
%left MUL DIV
%left UPREC
%start expression
%%
expression
: math_expression EOF { return $1; }
;
math_expression
: math_expression ADD math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
| math_expression SUB math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
| math_expression MUL math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
| math_expression DIV math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
| LPAREN math_expression RPAREN { $$ = $2; }
| NESTED_CALC LPAREN math_expression RPAREN { $$ = { type: 'Calc', value: $3 }; }
| SUB PREFIX SUB NESTED_CALC LPAREN math_expression RPAREN { $$ = { type: 'Calc', value: $6, prefix: $2 }; }
| css_variable { $$ = $1; }
| css_value { $$ = $1; }
| value { $$ = $1; }
;
value
: NUMBER { $$ = { type: 'Value', value: parseFloat($1) }; }
| SUB NUMBER { $$ = { type: 'Value', value: parseFloat($2) * -1 }; }
;
css_variable
: CSS_VAR LPAREN CSS_CPROP RPAREN { $$ = { type: 'CssVariable', value: $3 }; }
| CSS_VAR LPAREN CSS_CPROP COMMA math_expression RPAREN { $$ = { type: 'CssVariable', value: $3, fallback: $5 }; }
;
css_value
: LENGTH { $$ = { type: 'LengthValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; }
| ANGLE { $$ = { type: 'AngleValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; }
| TIME { $$ = { type: 'TimeValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; }
| FREQ { $$ = { type: 'FrequencyValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; }
| RES { $$ = { type: 'ResolutionValue', value: parseFloat($1), unit: /[a-z]+/.exec($1)[0] }; }
| EMS { $$ = { type: 'EmValue', value: parseFloat($1), unit: 'em' }; }
| EXS { $$ = { type: 'ExValue', value: parseFloat($1), unit: 'ex' }; }
| CHS { $$ = { type: 'ChValue', value: parseFloat($1), unit: 'ch' }; }
| REMS { $$ = { type: 'RemValue', value: parseFloat($1), unit: 'rem' }; }
| VHS { $$ = { type: 'VhValue', value: parseFloat($1), unit: 'vh' }; }
| VWS { $$ = { type: 'VwValue', value: parseFloat($1), unit: 'vw' }; }
| VMINS { $$ = { type: 'VminValue', value: parseFloat($1), unit: 'vmin' }; }
| VMAXS { $$ = { type: 'VmaxValue', value: parseFloat($1), unit: 'vmax' }; }
| PERCENTAGE { $$ = { type: 'PercentageValue', value: parseFloat($1), unit: '%' }; }
| SUB css_value { var prev = $2; prev.value *= -1; $$ = prev; }
;