math_store.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.MathStore = void 0;
  4. const BaseUtil = require("../common/base_util.js");
  5. const locale_js_1 = require("../l10n/locale.js");
  6. const semantic_annotations_js_1 = require("../semantic_tree/semantic_annotations.js");
  7. const base_rule_store_js_1 = require("./base_rule_store.js");
  8. const speech_rule_js_1 = require("./speech_rule.js");
  9. class MathStore extends base_rule_store_js_1.BaseRuleStore {
  10. constructor() {
  11. super();
  12. this.annotators = [];
  13. this.parseMethods['Alias'] = this.defineAlias;
  14. this.parseMethods['SpecializedRule'] = this.defineSpecializedRule;
  15. this.parseMethods['Specialized'] = this.defineSpecialized;
  16. }
  17. initialize() {
  18. if (this.initialized) {
  19. return;
  20. }
  21. this.annotations();
  22. this.initialized = true;
  23. }
  24. annotations() {
  25. for (let i = 0, annotator; (annotator = this.annotators[i]); i++) {
  26. (0, semantic_annotations_js_1.activate)(this.domain, annotator);
  27. }
  28. }
  29. defineAlias(name, prec, ...args) {
  30. const fullPrec = this.parsePrecondition(prec, args);
  31. if (!fullPrec) {
  32. console.error(`Precondition Error: ${prec} ${args}`);
  33. return;
  34. }
  35. const condition = this.preconditions.get(name);
  36. if (!condition) {
  37. console.error(`Alias Error: No precondition by the name of ${name}`);
  38. return;
  39. }
  40. condition.addFullCondition(fullPrec);
  41. }
  42. defineRulesAlias(name, query, ...args) {
  43. const rules = this.findAllRules(function (rule) {
  44. return rule.name === name;
  45. });
  46. if (rules.length === 0) {
  47. throw new speech_rule_js_1.OutputError('Rule with name ' + name + ' does not exist.');
  48. }
  49. const keep = [];
  50. const findKeep = (rule) => {
  51. const cstr = rule.dynamicCstr.toString();
  52. const action = rule.action.toString();
  53. for (let i = 0, k; (k = keep[i]); i++) {
  54. if (k.action === action && k.cstr === cstr) {
  55. return false;
  56. }
  57. }
  58. keep.push({ cstr: cstr, action: action });
  59. return true;
  60. };
  61. rules.forEach((rule) => {
  62. if (findKeep(rule)) {
  63. this.addAlias_(rule, query, args);
  64. }
  65. });
  66. }
  67. defineSpecializedRule(name, oldDynamic, newDynamic, opt_action) {
  68. const dynamicCstr = this.parseCstr(oldDynamic);
  69. const rule = this.findRule((rule) => rule.name === name && dynamicCstr.equal(rule.dynamicCstr));
  70. const newCstr = this.parseCstr(newDynamic);
  71. if (!rule && opt_action) {
  72. throw new speech_rule_js_1.OutputError('Rule named ' + name + ' with style ' + oldDynamic + ' does not exist.');
  73. }
  74. const action = opt_action ? speech_rule_js_1.Action.fromString(opt_action) : rule.action;
  75. const newRule = new speech_rule_js_1.SpeechRule(rule.name, newCstr, rule.precondition, action);
  76. this.addRule(newRule);
  77. }
  78. defineSpecialized(name, _old, dynamic) {
  79. const cstr = this.parseCstr(dynamic);
  80. if (!cstr) {
  81. console.error(`Dynamic Constraint Error: ${dynamic}`);
  82. return;
  83. }
  84. const condition = this.preconditions.get(name);
  85. if (!condition) {
  86. console.error(`Alias Error: No precondition by the name of ${name}`);
  87. return;
  88. }
  89. condition.addConstraint(cstr);
  90. }
  91. evaluateString(str) {
  92. const descs = [];
  93. if (str.match(/^\s+$/)) {
  94. return descs;
  95. }
  96. let num = this.matchNumber(str);
  97. if (num && num.length === str.length) {
  98. descs.push(this.evaluateCharacter(num.number));
  99. return descs;
  100. }
  101. const split = BaseUtil.removeEmpty(str.replace(/\s/g, ' ').split(' '));
  102. for (let i = 0, s; (s = split[i]); i++) {
  103. if (s.length === 1) {
  104. descs.push(this.evaluateCharacter(s));
  105. }
  106. else if (s.match(new RegExp('^[' + locale_js_1.LOCALE.MESSAGES.regexp.TEXT + ']+$'))) {
  107. descs.push(this.evaluateCharacter(s));
  108. }
  109. else {
  110. let rest = s;
  111. while (rest) {
  112. num = this.matchNumber(rest);
  113. const alpha = rest.match(new RegExp('^[' + locale_js_1.LOCALE.MESSAGES.regexp.TEXT + ']+'));
  114. if (num) {
  115. descs.push(this.evaluateCharacter(num.number));
  116. rest = rest.substring(num.length);
  117. }
  118. else if (alpha) {
  119. descs.push(this.evaluateCharacter(alpha[0]));
  120. rest = rest.substring(alpha[0].length);
  121. }
  122. else {
  123. const chars = Array.from(rest);
  124. const chr = chars[0];
  125. descs.push(this.evaluateCharacter(chr));
  126. rest = chars.slice(1).join('');
  127. }
  128. }
  129. }
  130. }
  131. return descs;
  132. }
  133. parse(ruleSet) {
  134. super.parse(ruleSet);
  135. this.annotators = ruleSet['annotators'] || [];
  136. }
  137. addAlias_(rule, query, cstrList) {
  138. const prec = this.parsePrecondition(query, cstrList);
  139. const newRule = new speech_rule_js_1.SpeechRule(rule.name, rule.dynamicCstr, prec, rule.action);
  140. newRule.name = rule.name;
  141. this.addRule(newRule);
  142. }
  143. matchNumber(str) {
  144. const locNum = str.match(new RegExp('^' + locale_js_1.LOCALE.MESSAGES.regexp.NUMBER));
  145. const enNum = str.match(new RegExp('^' + MathStore.regexp.NUMBER));
  146. if (!locNum && !enNum) {
  147. return null;
  148. }
  149. const isEn = enNum && enNum[0] === str;
  150. const isLoc = (locNum && locNum[0] === str) || !isEn;
  151. if (isLoc) {
  152. return locNum ? { number: locNum[0], length: locNum[0].length } : null;
  153. }
  154. const num = enNum[0]
  155. .replace(new RegExp(MathStore.regexp.DIGIT_GROUP, 'g'), 'X')
  156. .replace(new RegExp(MathStore.regexp.DECIMAL_MARK, 'g'), locale_js_1.LOCALE.MESSAGES.regexp.DECIMAL_MARK)
  157. .replace(/X/g, locale_js_1.LOCALE.MESSAGES.regexp.DIGIT_GROUP.replace(/\\/g, ''));
  158. return { number: num, length: enNum[0].length };
  159. }
  160. }
  161. exports.MathStore = MathStore;
  162. MathStore.regexp = {
  163. NUMBER: '((\\d{1,3})(?=(,| ))((,| )\\d{3})*(\\.\\d+)?)|^\\d*\\.\\d+|^\\d+',
  164. DECIMAL_MARK: '\\.',
  165. DIGIT_GROUP: ','
  166. };