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.

111 lines
5.8 KiB

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