| 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]+)(e(\+|-)[0-9]+)?)em\b return 'EMS';
|
|---|
| 21 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)ex\b return 'EXS';
|
|---|
| 22 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)ch\b return 'CHS';
|
|---|
| 23 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)rem\b return 'REMS';
|
|---|
| 24 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)vw\b return 'VWS';
|
|---|
| 25 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)vh\b return 'VHS';
|
|---|
| 26 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)vmin\b return 'VMINS';
|
|---|
| 27 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)vmax\b return 'VMAXS';
|
|---|
| 28 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)cm\b return 'LENGTH';
|
|---|
| 29 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)mm\b return 'LENGTH';
|
|---|
| 30 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)Q\b return 'LENGTH';
|
|---|
| 31 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)in\b return 'LENGTH';
|
|---|
| 32 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)pt\b return 'LENGTH';
|
|---|
| 33 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)pc\b return 'LENGTH';
|
|---|
| 34 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)px\b return 'LENGTH';
|
|---|
| 35 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)deg\b return 'ANGLE';
|
|---|
| 36 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)grad\b return 'ANGLE';
|
|---|
| 37 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)rad\b return 'ANGLE';
|
|---|
| 38 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)turn\b return 'ANGLE';
|
|---|
| 39 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)s\b return 'TIME';
|
|---|
| 40 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)ms\b return 'TIME';
|
|---|
| 41 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)Hz\b return 'FREQ';
|
|---|
| 42 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)kHz\b return 'FREQ';
|
|---|
| 43 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)dpi\b return 'RES';
|
|---|
| 44 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)dpcm\b return 'RES';
|
|---|
| 45 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)dppx\b return 'RES';
|
|---|
| 46 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)\% return 'PERCENTAGE';
|
|---|
| 47 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)\b return 'NUMBER';
|
|---|
| 48 |
|
|---|
| 49 | (([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)-?([a-zA-Z_]|[\240-\377]|(\\[0-9a-fA-F]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-fA-F]))([a-zA-Z0-9_-]|[\240-\377]|(\\[0-9a-fA-F]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-fA-F]))*\b return 'UNKNOWN_DIMENSION';
|
|---|
| 50 |
|
|---|
| 51 | "(" return 'LPAREN';
|
|---|
| 52 | ")" return 'RPAREN';
|
|---|
| 53 |
|
|---|
| 54 | <<EOF>> return 'EOF';
|
|---|
| 55 |
|
|---|
| 56 | /lex
|
|---|
| 57 |
|
|---|
| 58 | %left ADD SUB
|
|---|
| 59 | %left MUL DIV
|
|---|
| 60 | %left UPREC
|
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 | %start expression
|
|---|
| 64 |
|
|---|
| 65 | %%
|
|---|
| 66 |
|
|---|
| 67 | expression
|
|---|
| 68 | : math_expression EOF { return $1; }
|
|---|
| 69 | ;
|
|---|
| 70 |
|
|---|
| 71 | math_expression
|
|---|
| 72 | : CALC LPAREN math_expression RPAREN { $$ = $3; }
|
|---|
| 73 | | math_expression ADD math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
|
|---|
| 74 | | math_expression SUB math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
|
|---|
| 75 | | math_expression MUL math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
|
|---|
| 76 | | math_expression DIV math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
|
|---|
| 77 | | LPAREN math_expression RPAREN { $$ = { type: 'ParenthesizedExpression', content: $2 }; }
|
|---|
| 78 | | function { $$ = $1; }
|
|---|
| 79 | | dimension { $$ = $1; }
|
|---|
| 80 | | number { $$ = $1; }
|
|---|
| 81 | ;
|
|---|
| 82 |
|
|---|
| 83 | function
|
|---|
| 84 | : FUNCTION { $$ = { type: 'Function', value: $1 }; }
|
|---|
| 85 | ;
|
|---|
| 86 |
|
|---|
| 87 | dimension
|
|---|
| 88 | : LENGTH { $$ = { type: 'LengthValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|---|
| 89 | | ANGLE { $$ = { type: 'AngleValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|---|
| 90 | | TIME { $$ = { type: 'TimeValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|---|
| 91 | | FREQ { $$ = { type: 'FrequencyValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|---|
| 92 | | RES { $$ = { type: 'ResolutionValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|---|
| 93 | | UNKNOWN_DIMENSION { $$ = { type: 'UnknownDimension', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|---|
| 94 | | EMS { $$ = { type: 'EmValue', value: parseFloat($1), unit: 'em' }; }
|
|---|
| 95 | | EXS { $$ = { type: 'ExValue', value: parseFloat($1), unit: 'ex' }; }
|
|---|
| 96 | | CHS { $$ = { type: 'ChValue', value: parseFloat($1), unit: 'ch' }; }
|
|---|
| 97 | | REMS { $$ = { type: 'RemValue', value: parseFloat($1), unit: 'rem' }; }
|
|---|
| 98 | | VHS { $$ = { type: 'VhValue', value: parseFloat($1), unit: 'vh' }; }
|
|---|
| 99 | | VWS { $$ = { type: 'VwValue', value: parseFloat($1), unit: 'vw' }; }
|
|---|
| 100 | | VMINS { $$ = { type: 'VminValue', value: parseFloat($1), unit: 'vmin' }; }
|
|---|
| 101 | | VMAXS { $$ = { type: 'VmaxValue', value: parseFloat($1), unit: 'vmax' }; }
|
|---|
| 102 | | PERCENTAGE { $$ = { type: 'PercentageValue', value: parseFloat($1), unit: '%' }; }
|
|---|
| 103 | | ADD dimension { var prev = $2; $$ = prev; }
|
|---|
| 104 | | SUB dimension { var prev = $2; prev.value *= -1; $$ = prev; }
|
|---|
| 105 | ;
|
|---|
| 106 |
|
|---|
| 107 | number
|
|---|
| 108 | : NUMBER { $$ = { type: 'Number', value: parseFloat($1) }; }
|
|---|
| 109 | | ADD NUMBER { $$ = { type: 'Number', value: parseFloat($2) }; }
|
|---|
| 110 | | SUB NUMBER { $$ = { type: 'Number', value: parseFloat($2) * -1 }; }
|
|---|
| 111 | ;
|
|---|