You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
5.8 KiB
112 lines
5.8 KiB
/* description: Parses expressions. */
|
|
|
|
/* lexical grammar */
|
|
%lex
|
|
|
|
%options case-insensitive
|
|
|
|
%%
|
|
\s+ /* skip whitespace */
|
|
|
|
(\-(webkit|moz)\-)?calc\b return 'CALC';
|
|
|
|
[a-z][a-z0-9-]*\s*\((?:(?:\"(?:\\.|[^\"\\])*\"|\'(?:\\.|[^\'\\])*\')|\([^)]*\)|[^\(\)]*)*\) return 'FUNCTION';
|
|
|
|
"*" return 'MUL';
|
|
"/" return 'DIV';
|
|
"+" return 'ADD';
|
|
"-" return 'SUB';
|
|
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)em\b return 'EMS';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)ex\b return 'EXS';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)ch\b return 'CHS';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)rem\b return 'REMS';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)vw\b return 'VWS';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)vh\b return 'VHS';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)vmin\b return 'VMINS';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)vmax\b return 'VMAXS';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)cm\b return 'LENGTH';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)mm\b return 'LENGTH';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)Q\b return 'LENGTH';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)in\b return 'LENGTH';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)pt\b return 'LENGTH';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)pc\b return 'LENGTH';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)px\b return 'LENGTH';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)deg\b return 'ANGLE';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)grad\b return 'ANGLE';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)rad\b return 'ANGLE';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)turn\b return 'ANGLE';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)s\b return 'TIME';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)ms\b return 'TIME';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)Hz\b return 'FREQ';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)kHz\b return 'FREQ';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)dpi\b return 'RES';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)dpcm\b return 'RES';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)dppx\b return 'RES';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)\% return 'PERCENTAGE';
|
|
(([0-9]+("."[0-9]+)?|"."[0-9]+)(e(\+|-)[0-9]+)?)\b return 'NUMBER';
|
|
|
|
(([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';
|
|
|
|
"(" return 'LPAREN';
|
|
")" return 'RPAREN';
|
|
|
|
<<EOF>> return 'EOF';
|
|
|
|
/lex
|
|
|
|
%left ADD SUB
|
|
%left MUL DIV
|
|
%left UPREC
|
|
|
|
|
|
%start expression
|
|
|
|
%%
|
|
|
|
expression
|
|
: math_expression EOF { return $1; }
|
|
;
|
|
|
|
math_expression
|
|
: CALC LPAREN math_expression RPAREN { $$ = $3; }
|
|
| 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 { $$ = { type: 'ParenthesizedExpression', content: $2 }; }
|
|
| function { $$ = $1; }
|
|
| dimension { $$ = $1; }
|
|
| number { $$ = $1; }
|
|
;
|
|
|
|
function
|
|
: FUNCTION { $$ = { type: 'Function', value: $1 }; }
|
|
;
|
|
|
|
dimension
|
|
: LENGTH { $$ = { type: 'LengthValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|
| ANGLE { $$ = { type: 'AngleValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|
| TIME { $$ = { type: 'TimeValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|
| FREQ { $$ = { type: 'FrequencyValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|
| RES { $$ = { type: 'ResolutionValue', value: parseFloat($1), unit: /[a-z]+$/i.exec($1)[0] }; }
|
|
| UNKNOWN_DIMENSION { $$ = { type: 'UnknownDimension', value: parseFloat($1), unit: /[a-z]+$/i.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: '%' }; }
|
|
| ADD dimension { var prev = $2; $$ = prev; }
|
|
| SUB dimension { var prev = $2; prev.value *= -1; $$ = prev; }
|
|
;
|
|
|
|
number
|
|
: NUMBER { $$ = { type: 'Number', value: parseFloat($1) }; }
|
|
| ADD NUMBER { $$ = { type: 'Number', value: parseFloat($2) }; }
|
|
| SUB NUMBER { $$ = { type: 'Number', value: parseFloat($2) * -1 }; }
|
|
;
|