U.DC.ExprCal.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. var ExprCal = {
  2. // gramParser :new syntax(), // 用于获取运行实例符号表的传入类
  3. expression :'', // 表达式字符数组
  4. charIndex :0, // 数组下标指针
  5. num :new Array(), // 运算数栈
  6. // 运算符栈关系运算符对应关系
  7. // '<' 对应 <
  8. // '>' 对应 >
  9. // 'e' 对应 ==
  10. // 'n' 对应 <>
  11. op :new Array(), // 运算符栈
  12. hasReturn :false,
  13. genCode :true,
  14. // 中间代码临时存放变量
  15. tempIndex :1,
  16. // 获取新temp变量名
  17. getTemp : function() {
  18. ExprCal.tempIndex++;
  19. return "@temp" + ExprCal.tempIndex;
  20. },
  21. IsDigit : function(c) {
  22. if (c >= '0' && c <= '9') {
  23. return true;
  24. }
  25. return false;
  26. },
  27. IsLetter : function(c) {
  28. if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
  29. return true;
  30. }
  31. return false;
  32. },
  33. init : function(expression)
  34. {
  35. ExprCal.expression = expression;
  36. ExprCal.charIndex=0;
  37. ExprCal.hasReturn=false;
  38. ExprCal.num=new Array();
  39. ExprCal.genCode = !Syntax.InWrite;
  40. tempIndex =1;
  41. },
  42. Calculate : function() {
  43. ExprCal.build();
  44. while (ExprCal.op.length > 0){
  45. ExprCal.calc();
  46. }
  47. if (!(ExprCal.hasReturn)) {
  48. ExprCal.gen("load", "_", ExprCal.num[ExprCal.num.length - 1],
  49. "@result");
  50. } else {
  51. ExprCal.gen("load", "_", Syntax.getLastReg(), "@result");
  52. }
  53. return 0;
  54. },
  55. gen : function(s1, s2, s3, s4) {
  56. if (ExprCal.genCode) {
  57. Syntax.gen(s1, s2, s3, s4);
  58. }
  59. },
  60. // 获取下一个字符
  61. getChar : function() {
  62. if (ExprCal.charIndex < ExprCal.expression.length) {
  63. return ExprCal.expression[ExprCal.charIndex];
  64. } else {
  65. return '\0';
  66. }
  67. },
  68. // 栈顶运算
  69. calc : function() {
  70. var value;
  71. var num1, num2;
  72. if (ExprCal.op.length == 0) {
  73. return;
  74. }
  75. switch (ExprCal.op[ExprCal.op.length - 1]) {
  76. case '<':
  77. num1 = ExprCal.num.pop();
  78. num2 = ExprCal.num.pop();
  79. value = ExprCal.getTemp();
  80. ExprCal.gen("lt", num2, num1, value);
  81. ExprCal.hasReturn = true;
  82. ExprCal.num.push(value);
  83. break;
  84. case '>':
  85. num1 = ExprCal.num.pop();
  86. num2 = ExprCal.num.pop();
  87. value = ExprCal.getTemp();
  88. ExprCal.gen("gt", num2, num1, value);
  89. ExprCal.hasReturn = true;
  90. ExprCal.num.push(value);
  91. break;
  92. case 'e':
  93. num1 = ExprCal.num.pop();
  94. num2 = ExprCal.num.pop();
  95. value = ExprCal.getTemp();
  96. ExprCal.gen("eq", num2, num1, value);
  97. ExprCal.hasReturn = true;
  98. ExprCal.num.push(value);
  99. break;
  100. case 'n':
  101. num1 = ExprCal.num.pop();
  102. num2 = ExprCal.num.pop();
  103. value = ExprCal.getTemp();
  104. ExprCal.gen("ne", num2, num1, value);
  105. ExprCal.hasReturn = true;
  106. ExprCal.num.push(value);
  107. break;
  108. case '+':
  109. num1 = ExprCal.num.pop();
  110. num2 = ExprCal.num.pop();
  111. value = ExprCal.getTemp();
  112. ExprCal.gen("add", num2, num1, value);
  113. ExprCal.hasReturn = true;
  114. ExprCal.num.push(value);
  115. break;
  116. case '-':
  117. num1 = ExprCal.num.pop();
  118. num2 = ExprCal.num.pop();
  119. value = ExprCal.getTemp();
  120. ExprCal.gen("sub", num2, num1, value);
  121. ExprCal.hasReturn = true;
  122. ExprCal.num.push(value);
  123. break;
  124. case '*':
  125. num1 = ExprCal.num.pop();
  126. num2 = ExprCal.num.pop();
  127. value = ExprCal.getTemp();
  128. ExprCal.gen("mul", num2, num1, value);
  129. ExprCal.hasReturn = true;
  130. ExprCal.num.push(value);
  131. break;
  132. case '/':
  133. num1 = ExprCal.num.pop();
  134. num2 = ExprCal.num.pop();
  135. value = ExprCal.getTemp();
  136. ExprCal.gen("div", num2, num1, value);
  137. ExprCal.hasReturn = true;
  138. ExprCal.num.push(value);
  139. break;
  140. }
  141. ExprCal.op.pop();
  142. },
  143. // 建立数栈和运算符栈
  144. build : function() {
  145. var t, tempExpr;
  146. var c = ExprCal.getChar();
  147. while (ExprCal.charIndex < ExprCal.expression.length) {
  148. // 处理变量
  149. if (ExprCal.IsLetter(c)) {
  150. t = "";
  151. tempExpr = "";
  152. // 标识符
  153. while (ExprCal.IsLetter(c) || ExprCal.IsDigit(c) || c == '_') {
  154. t += c;
  155. ExprCal.charIndex++;
  156. c = ExprCal.getChar();
  157. }
  158. // 数组下标
  159. if (c == '[') {
  160. var level = 1;
  161. ExprCal.op.push(c);
  162. ExprCal.charIndex++;
  163. c = ExprCal.getChar();
  164. while (c != ']' || level != 1) {
  165. if (c == '[') {
  166. level++;
  167. }
  168. if (c == ']') {
  169. level--;
  170. }
  171. tempExpr += c;
  172. ExprCal.charIndex++;
  173. c = ExprCal.getChar();
  174. }
  175. ExprCal.init(tempExpr);// /////////////////////////
  176. ExprCal.Calculate();
  177. tempExpr = "[@result]";
  178. }
  179. t += tempExpr;
  180. ExprCal.num.push(t);
  181. }
  182. // 处理数字
  183. if (ExprCal.IsDigit(c)) {
  184. t = "";
  185. while (ExprCal.IsDigit(c) || c == '.') {
  186. t += c;
  187. ExprCal.charIndex++;
  188. c = ExprCal.getChar();
  189. }
  190. ExprCal.num.push(parseFloat(t));
  191. }
  192. // 处理运算符
  193. switch (c) {
  194. case '(':
  195. ExprCal.op.push(c);
  196. break;
  197. case ')':
  198. while (ExprCal.op[ExprCal.op.length - 1] != '(') {
  199. ExprCal.calc();
  200. }
  201. ExprCal.op.pop();
  202. break;
  203. case '>': // > 运算
  204. if (ExprCal.op.length > 0
  205. && (ExprCal.op[ExprCal.op.length - 1] == '<'
  206. || ExprCal.op[ExprCal.op.length - 1] == 'e'
  207. || ExprCal.op[ExprCal.op.length - 1] == 'n'
  208. || ExprCal.op[ExprCal.op.length - 1] == '+'
  209. || ExprCal.op[ExprCal.op.length - 1] == '-'
  210. || ExprCal.op[ExprCal.op.length - 1] == '*' || ExprCal.op[ExprCal.op.length - 1] == '/')) {
  211. ExprCal.calc();
  212. }
  213. ExprCal.op.push('>');
  214. break;
  215. case '=': // == 运算
  216. ExprCal.charIndex++;
  217. if (ExprCal.op.length > 0
  218. && (ExprCal.op[ExprCal.op.length - 1] == '<'
  219. || ExprCal.op[ExprCal.op.length - 1] == '>'
  220. || ExprCal.op[ExprCal.op.length - 1] == 'n'
  221. || ExprCal.op[ExprCal.op.length - 1] == '+'
  222. || ExprCal.op[ExprCal.op.length - 1] == '-'
  223. || ExprCal.op[ExprCal.op.length - 1] == '*' || ExprCal.op[ExprCal.op.length - 1] == '/')) {
  224. ExprCal.calc();
  225. }
  226. ExprCal.op.push('e');
  227. break;
  228. case '<':
  229. if (ExprCal.expression[ExprCal.charIndex + 1] != '>') // > 运算
  230. {
  231. if (ExprCal.op.length > 0
  232. && (ExprCal.op[ExprCal.op.length - 1] == '>'
  233. || ExprCal.op[ExprCal.op.length - 1] == 'e'
  234. || ExprCal.op[ExprCal.op.length - 1] == 'n'
  235. || ExprCal.op[ExprCal.op.length - 1] == '+'
  236. || ExprCal.op[ExprCal.op.length - 1] == '-'
  237. || ExprCal.op[ExprCal.op.length - 1] == '*' || ExprCal.op[ExprCal.op.length - 1] == '/')) {
  238. ExprCal.calc();
  239. }
  240. ExprCal.op.push('<');
  241. } else // <> 运算
  242. {
  243. ExprCal.charIndex++;
  244. if (ExprCal.op.length > 0
  245. && (ExprCal.op[ExprCal.op.length - 1] == '<' || ExprCal.op[ExprCal.op.length - 1] == '>'
  246. || ExprCal.op[ExprCal.op.length - 1] == 'e'
  247. || ExprCal.op[ExprCal.op.length - 1] == '+'
  248. || ExprCal.op[ExprCal.op.length - 1] == '-'
  249. || ExprCal.op[ExprCal.op.length - 1] == '*' || ExprCal.op[ExprCal.op.length - 1] == '/')) {
  250. ExprCal.calc();
  251. }
  252. ExprCal.op.push('n');
  253. }
  254. break;
  255. case '+':
  256. while (ExprCal.op.length > 0
  257. && (ExprCal.op[ExprCal.op.length - 1] == '+' || ExprCal.op[ExprCal.op.length - 1] == '-'
  258. || ExprCal.op[ExprCal.op.length - 1] == '*' || ExprCal.op[ExprCal.op.length - 1] == '/')) {
  259. ExprCal.calc();
  260. }
  261. ExprCal.op.push(c);
  262. break;
  263. case '-':
  264. while (ExprCal.op.length > 0
  265. && (ExprCal.op[ExprCal.op.length - 1] == '+' || ExprCal.op[ExprCal.op.length - 1] == '-'
  266. || ExprCal.op[ExprCal.op.length - 1] == '*' || ExprCal.op[ExprCal.op.length - 1] == '/')) {
  267. ExprCal.calc();
  268. }
  269. ExprCal.op.push(c);
  270. break;
  271. case '*':
  272. while (ExprCal.op.length > 0
  273. && (ExprCal.op[ExprCal.op.length - 1] == '*' || ExprCal.op[ExprCal.op.length - 1] == '/')) {
  274. ExprCal.calc();
  275. }
  276. ExprCal.op.push(c);
  277. break;
  278. case '/':
  279. while (ExprCal.op.length > 0
  280. && (ExprCal.op[ExprCal.op.length - 1] == '*' || ExprCal.op[ExprCal.op.length - 1] == '/')) {
  281. ExprCal.calc();
  282. }
  283. ExprCal.op.push(c);
  284. break;
  285. default:
  286. ExprCal.charIndex++;
  287. c = ExprCal.getChar();
  288. continue;
  289. }
  290. ExprCal.charIndex++;
  291. c = ExprCal.getChar();
  292. }
  293. }
  294. }