parser.cpp
上传用户:qccn516
上传日期:2013-05-02
资源大小:3382k
文件大小:15k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /* Parser
  2.  *
  3.  * Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #include "engine.h"
  20. #include "parser.h"
  21. float Parser::variables[26];
  22. /*
  23.  */
  24. Parser::Parser(const char *name) : data(NULL) {
  25. FILE *file = fopen(name,"r");
  26. if(!file) {
  27. fprintf(stderr,"Parse::Parse(): error open "%s" filen",name);
  28. return;
  29. }
  30. fseek(file,0,SEEK_END);
  31. int size = ftell(file);
  32. fseek(file,0,SEEK_SET);
  33. data = new char[size + 1];
  34. memset(data,0,sizeof(char) * (size + 1));
  35. fread(data,sizeof(char),size,file);
  36. fclose(file);
  37. char *s = data;
  38. char *d = data;
  39. int define_ok[32];
  40. int depth = 0;
  41. while(*s) {
  42. // #ifdef, #ifndef, #else, #endif preprocessor
  43. if(*s == '#' && !strncmp(s + 1,"ifdef",5)) {
  44. char define[1024];
  45. sscanf(s + 6,"%s",define);
  46. while(*s != '' && *s != 'n') s++;
  47. if(Engine::isDefine(define) == 1) define_ok[depth++] = 1;
  48. else define_ok[depth++] = 0;
  49. } else if(*s == '#' && !strncmp(s + 1,"ifndef",6)) {
  50. char define[1024];
  51. sscanf(s + 7,"%s",define);
  52. while(*s != '' && *s != 'n') s++;
  53. if(Engine::isDefine(define) == 0) define_ok[depth++] = 1;
  54. else define_ok[depth++] = 0;
  55. } else if(*s == '#' && !strncmp(s + 1,"else",4)) {
  56. while(*s != '' && *s != 'n') s++;
  57. define_ok[depth - 1] = !define_ok[depth - 1];
  58. } else if(*s == '#' && !strncmp(s + 1,"endif",5)) {
  59. while(*s != '' && *s != 'n') s++;
  60. depth--;
  61. }
  62. // C-like comments // and /* */
  63. else if(*s == '/' && *(s + 1) == '/') {
  64. while(*s && *s != 'n') s++;
  65. while(*s && *s == 'n') s++;
  66. *d++ = 'n';
  67. } else if(*s == '/' && *(s + 1) == '*') {
  68. while(*s && (*s != '*' || *(s + 1) != '/')) s++;
  69. s += 2;
  70. while(*s && *s == 'n') s++;
  71. *d++ = 'n';
  72. }
  73. // blocks
  74. else if(*s == '<' && isalpha(*(s + 1))) {
  75. int i = 0;
  76. for(; i < depth; i++) if(define_ok[i] == 0) break;
  77. if(i == depth) {
  78. while(d > data && *(d - 1) == 'n') d--;
  79. *d++ = *s = '';
  80. char *name = ++s;
  81. while(*s && *s != '>') s++;
  82. *s++ = '';
  83. while(*s && strchr(" tnr",*s)) s++;
  84. Block b;
  85. b.pointer = d;
  86. b.use = 0;
  87. blocks[name] = b;
  88. } else {
  89. s++;
  90. }
  91. }
  92. else {
  93. if(depth == 0) *d++ = *s++;
  94. else {
  95. int i = 0;
  96. for(; i < depth; i++) if(define_ok[i] == 0) break;
  97. if(i == depth) *d++ = *s++;
  98. else s++;
  99. }
  100. }
  101. }
  102. while(d > data && *(d - 1) == 'n') d--;
  103. *d = '';
  104. }
  105. Parser::~Parser() {
  106. for(std::map<std::string,Block>::iterator it = blocks.begin(); it != blocks.end(); it++) {
  107. if(!it->second.use) fprintf(stderr,"Parser::~Parser(): warning unused block "%s"n",it->first.c_str());
  108. }
  109. blocks.clear();
  110. delete data;
  111. }
  112. /*
  113.  */
  114. char *Parser::get(const char *name) {
  115. std::map<std::string,Block>::iterator it = blocks.find(name);
  116. if(it == blocks.end()) return NULL;
  117. it->second.use = 1;
  118. char *ret = it->second.pointer;
  119. while(*ret && strchr(" tnr",*ret)) ret++;
  120. char *s = ret + strlen(ret) - 1;
  121. while(s > ret && strchr(" tnr",*s)) s--;
  122. s++;
  123. *s = '';
  124. return ret;
  125. }
  126. /*****************************************************************************/
  127. /*                                                                           */
  128. /* read string                                                               */
  129. /*                                                                           */
  130. /*****************************************************************************/
  131. int Parser::read_string(const char *str,char *dest) {
  132. const char *s = str;
  133. char *d = dest;
  134. while(*s && strchr(" t",*s)) s++;
  135. if(*s == '"') {
  136. s++;
  137. while(*s && *s != '"') *d++ = *s++;
  138. s++;
  139. *d = '';
  140. } else {
  141. while(*s && !strchr(" t",*s)) *d++ = *s++;
  142. *d = '';
  143. }
  144. return s - str;
  145. }
  146. /*****************************************************************************/
  147. /*                                                                           */
  148. /* expressions                                                               */
  149. /*                                                                           */
  150. /*****************************************************************************/
  151. /*
  152.  */
  153. int Parser::priority(char op) {
  154. if(strchr("sScCtTleqfr",op)) return 4;
  155. if(strchr("*/%",op)) return 3;
  156. if(strchr("+-",op)) return 2;
  157. if(strchr("<>!=&|",op)) return 1;
  158. return 0;
  159. }
  160. /*
  161.  */
  162. float Parser::expression(const char *str,const char *variable,float value) {
  163. static struct {
  164. char op;
  165. float num;
  166. } stack[1024];
  167. int stack_depth = 0;
  168. static char stack_op[1024];
  169. int stack_op_depth = 0;
  170. const char *s = str;
  171. int brackets = 0;
  172. while(*s) {
  173. if(*s == '(') brackets++;
  174. else if(*s == ')') brackets--;
  175. s++;
  176. }
  177. if(brackets != 0) {
  178. fprintf(stderr,"Paser::expression(): parse error before '%c'n",brackets > 0 ? '(' : ')');
  179. return 0.0;
  180. }
  181. s = str;
  182. while(*s) {
  183. if(*s == '(') {
  184. stack_op[stack_op_depth++] = *s++;
  185. }
  186. else if(*s == ')') {
  187. while(stack_op_depth > 0 && stack_op[--stack_op_depth] != '(') stack[stack_depth++].op = stack_op[stack_op_depth];
  188. s++;
  189. }
  190. else if(strchr("<>+-*/%",*s)) {
  191. while(stack_op_depth > 0 && priority(*s) <= priority(stack_op[stack_op_depth - 1])) {
  192. stack[stack_depth++].op = stack_op[--stack_op_depth];
  193. }
  194. stack_op[stack_op_depth++] = *s++;
  195. }
  196. else if(!strncmp("==",s,2)) {
  197. stack_op[stack_op_depth++] = '=';
  198. s += 2;
  199. }
  200. else if(!strncmp("!=",s,2)) {
  201. stack_op[stack_op_depth++] = '!';
  202. s += 2;
  203. }
  204. else if(!strncmp("&&",s,2)) {
  205. stack_op[stack_op_depth++] = '&';
  206. s += 2;
  207. }
  208. else if(!strncmp("||",s,2)) {
  209. stack_op[stack_op_depth++] = '|';
  210. s += 2;
  211. }
  212. else if(!strncmp("sin",s,3)) {
  213. stack_op[stack_op_depth++] = 's';
  214. s += 3;
  215. }
  216. else if(!strncmp("asin",s,4)) {
  217. stack_op[stack_op_depth++] = 'S';
  218. s += 4;
  219. }
  220. else if(!strncmp("cos",s,3)) {
  221. stack_op[stack_op_depth++] = 'c';
  222. s += 3;
  223. }
  224. else if(!strncmp("acos",s,4)) {
  225. stack_op[stack_op_depth++] = 'C';
  226. s += 4;
  227. }
  228. else if(!strncmp("tan",s,3)) {
  229. stack_op[stack_op_depth++] = 't';
  230. s += 3;
  231. }
  232. else if(!strncmp("atan",s,4)) {
  233. stack_op[stack_op_depth++] = 'T';
  234. s += 4;
  235. }
  236. else if(!strncmp("log",s,3)) {
  237. stack_op[stack_op_depth++] = 'l';
  238. s += 3;
  239. }
  240. else if(!strncmp("exp",s,3)) {
  241. stack_op[stack_op_depth++] = 'e';
  242. s += 3;
  243. }
  244. else if(!strncmp("sqrt",s,4)) {
  245. stack_op[stack_op_depth++] = 'q';
  246. s += 4;
  247. }
  248. else if(!strncmp("fabs",s,4)) {
  249. stack_op[stack_op_depth++] = 'f';
  250. s += 4;
  251. }
  252. else if(!strncmp("rand",s,4)) {
  253. stack_op[stack_op_depth++] = 'r';
  254. s += 4;
  255. }
  256. else if(strchr("0123456789.",*s)) {
  257. char buf[1024];
  258. char *b = buf;
  259. *b++ = *s++;
  260. while(*s && strchr("0123456789.",*s)) *b++ = *s++;
  261. *b = '';
  262. stack[stack_depth].op = 'n';
  263. stack[stack_depth++].num = atof(buf);
  264. }
  265. else if(variable && !strncmp(variable,s,strlen(variable))) {
  266. stack[stack_depth].op = 'n';
  267. stack[stack_depth++].num = value;
  268. s += 4;
  269. }
  270. else if(!variable && *s == '$') {
  271. s++;
  272. if(!isalpha(*s)) {
  273. fprintf(stderr,"Paser::expression(): unknown variable "%c"n",*s);
  274. return 0.0;
  275. }
  276. stack[stack_depth].op = 'n';
  277. stack[stack_depth++].num = variables[tolower(*s++) - 'a'];
  278. }
  279. else if(strchr(" tnr",*s)) s++;
  280. else {
  281. fprintf(stderr,"Paser::expression(): unknown token "%s"n",s);
  282. return 0.0;
  283. }
  284. }
  285. while(stack_op_depth--) stack[stack_depth++].op = stack_op[stack_op_depth];
  286. for(int tries = 0; tries < 1024; tries++) {
  287. int end = 0;
  288. for(int i = 0, a = -1, b = -1, num = 0; i < stack_depth; i++) {
  289. if(!stack[i].op) continue;
  290. end++;
  291. if(num >= 1 && strchr("sScCtTleqfr",stack[i].op)) {
  292. int c = a;
  293. if(b != -1) c = b;
  294. switch(stack[i].op) {
  295. case 's': stack[i].num = sin(stack[c].num); break;
  296. case 'S': stack[i].num = asin(stack[c].num); break;
  297. case 'c': stack[i].num = cos(stack[c].num); break;
  298. case 'C': stack[i].num = acos(stack[c].num); break;
  299. case 't': stack[i].num = tan(stack[c].num); break;
  300. case 'T': stack[i].num = atan(stack[c].num); break;
  301. case 'l': stack[i].num = log(stack[c].num); break;
  302. case 'e': stack[i].num = exp(stack[c].num); break;
  303. case 'q': stack[i].num = sqrt(stack[c].num); break;
  304. case 'f': stack[i].num = fabs(stack[c].num); break;
  305. case 'r': stack[i].num = rand() / (float)RAND_MAX * stack[c].num; break;
  306. }
  307. stack[i].op = 'n';
  308. stack[c].op = 0;
  309. end += 10;
  310. break;
  311. }
  312. else if(num >= 2 && strchr("<>!=&|+-*/%",stack[i].op)) {
  313. switch(stack[i].op) {
  314. case '<': stack[i].num = stack[a].num < stack[b].num; break;
  315. case '>': stack[i].num = stack[a].num > stack[b].num; break;
  316. case '=': stack[i].num = stack[a].num == stack[b].num; break;
  317. case '!': stack[i].num = stack[a].num != stack[b].num; break;
  318. case '&': stack[i].num = stack[a].num && stack[b].num; break;
  319. case '|': stack[i].num = stack[a].num || stack[b].num; break;
  320. case '+': stack[i].num = stack[a].num + stack[b].num; break;
  321. case '-': stack[i].num = stack[a].num - stack[b].num; break;
  322. case '*': stack[i].num = stack[a].num * stack[b].num; break;
  323. case '/': stack[i].num = stack[a].num / stack[b].num; break;
  324. case '%': stack[i].num = (int)stack[a].num % (int)stack[b].num; break;
  325. }
  326. stack[i].op = 'n';
  327. stack[a].op = stack[b].op = 0;
  328. break;
  329. }
  330. else if(num == 1 && strchr("!+-",stack[i].op)) {
  331. if(stack[i].op == '!') stack[a].num = !stack[a].num;
  332. if(stack[i].op == '-') stack[a].num = -stack[a].num;
  333. stack[i].op = 0;
  334. end += 10;
  335. break;
  336. }
  337. else if(stack[i].op == 'n') {
  338. switch(num++) {
  339. case 0: a = i; break;
  340. case 1: b = i; break;
  341. default: a = b; b = i; break;
  342. }
  343. }
  344. else num = 0;
  345. }
  346. if(end < 3) {
  347. for(int i = 0; i < stack_depth; i++) {
  348. if(stack[i].op == 'n') return stack[i].num;
  349. }
  350. }
  351. }
  352. return 0.0;
  353. }
  354. /*****************************************************************************/
  355. /*                                                                           */
  356. /* simple interpreter                                                        */
  357. /*                                                                           */
  358. /*****************************************************************************/
  359. /*
  360.  */
  361. int Parser::read_token(const char *src,char *dest) {
  362. const char *s = src;
  363. int brackets_0 = 0;
  364. int brackets_1 = 0;
  365. while(*s) {
  366. if(*s == '(') brackets_0++;
  367. else if(*s == ')' && --brackets_0 < 0) break;
  368. else if(*s == '{') brackets_1++;
  369. else if(*s == '}' && --brackets_1 < 0) break;
  370. else if(*s == ';') break;
  371. if(dest) *dest++ = *s++;
  372. else s++;
  373. }
  374. if(dest) *dest = '';
  375. return s - src;
  376. }
  377. /*
  378.  */
  379. int Parser::interpret_eq(const char *src) {
  380. const char *s = src;
  381. while(*s && strchr(" t",*s)) s++;
  382. if(*s++ != '$') throw("Parser::interpret_eq(): missing '$'");
  383. char var = *s++;
  384. if(!isalpha(var)) throw("Parser::interpret_eq(): unknown variable");
  385. var = tolower(var);
  386. int op = 0;
  387. while(*s && strchr(" t",*s)) s++;
  388. if(!strncmp("=",s,1)) { s++; op = 0; }
  389. else if(!strncmp("+=",s,2)) { s += 2; op = 1; }
  390. else if(!strncmp("-=",s,2)) { s += 2; op = 2; }
  391. else if(!strncmp("++",s,2)) { s += 2; op = 3; }
  392. else if(!strncmp("--",s,2)) { s += 2; op = 4; }
  393. else throw("Parser::interpret_eq(): missing '='");
  394. char exp[1024];
  395. s += read_token(s,exp);
  396. if(*s) *s++;
  397. if(op == 0) variables[var - 'a'] = expression(exp);
  398. else if(op == 1) variables[var - 'a'] += expression(exp);
  399. else if(op == 2) variables[var - 'a'] -= expression(exp);
  400. else if(op == 3) variables[var - 'a'] += 1.0f;
  401. else if(op == 3) variables[var - 'a'] -= 1.0f;
  402. return s - src;
  403. }
  404. /*
  405.  */
  406. int Parser::interpret_if(const char *src,char **dest) {
  407. const char *s = src + 2;
  408. char condition[1024];
  409. while(*s && strchr(" t",*s)) s++;
  410. if(*s++ != '(') throw("Parser::interpret_if(): can`t find '('");
  411. s += read_token(s,condition);
  412. if(*s++ != ')') throw("Parser::interpret_if(): can`t find ')'");
  413. while(*s && strchr(" t",*s)) s++;
  414. if(*s++ != '{') throw("Parser::interpret_if(): can`t find '{'");
  415. if(expression(condition)) {
  416. s += interpret_main(s,dest);
  417. while(*s && strchr(" t",*s)) s++;
  418. if(!strncmp("else",s,4)) {
  419. s += 4;
  420. while(*s && strchr(" t",*s)) s++;
  421. if(*s++ != '{') throw("Parser::interpret_if(): can`t find '{'");
  422. s += read_token(s,NULL);
  423. if(*s++ != '}') throw("Parser::interpret_if(): can`t find '}'");
  424. }
  425. } else {
  426. s += read_token(s,NULL);
  427. if(*s++ != '}') throw("Parser::interpret_if(): can`t find '}'");
  428. while(*s && strchr(" t",*s)) s++;
  429. if(!strncmp("else",s,4)) {
  430. s += 4;
  431. while(*s && strchr(" t",*s)) s++;
  432. if(*s++ != '{') throw("Parser::interpret_if(): can`t find '{'");
  433. s += interpret_main(s,dest);
  434. }
  435. }
  436. return s - src;
  437. }
  438. /*
  439.  */
  440. int Parser::interpret_for(const char *src,char **dest) {
  441. const char *s = src + 3;
  442. char condition[1024];
  443. char addition[1024];
  444. while(*s && strchr(" t",*s)) s++;
  445. if(*s++ != '(') throw("Parser::interpret_for(): can`t find '('");
  446. s += interpret_eq(s);
  447. s += read_token(s,condition);
  448. if(*s++ != ';') throw("Parser::interpret_for(): can`t find ';'");
  449. s += read_token(s,addition);
  450. if(*s++ != ')') throw("Parser::interpret_for(): can`t find ')'");
  451. while(*s && strchr(" t",*s)) s++;
  452. if(*s++ != '{') throw("Parser::interpret_for(): can`t find '{'");
  453. const char *begin = NULL;
  454. do {
  455. if(!begin) {
  456. begin = s;
  457. s += interpret_main(begin,dest);
  458. } else interpret_main(begin,dest);
  459. interpret_eq(addition);
  460. } while(expression(condition));
  461. return s - src;
  462. }
  463. /*
  464.  */
  465. int Parser::interpret_main(const char *src,char **dest) {
  466. const char *s = src;
  467. int brackets = 0;
  468. int new_word = 1;
  469. while(*s) {
  470. if(new_word && !strncmp("if",s,2) && strchr("( t",*(s + 2))) {
  471. s += interpret_if(s,dest);
  472. }
  473. else if(new_word && !strncmp("for",s,3) && strchr("( t",*(s + 3))) {
  474. s += interpret_for(s,dest);
  475. }
  476. else if(*s == '$' && (*(s + 1) == '(' || isalpha(*(s + 1)))) {
  477. if(*(s + 1) == '(') {
  478. s += 2;
  479. char exp[1024];
  480. s += read_token(s,exp);
  481. if(*s) *s++;
  482. (*dest) += sprintf(*dest,"%g",expression(exp));
  483. } else {
  484. const char *e = ++s;
  485. while(*e && !strchr("=(){};nr",*e)) e++;
  486. if(*e == '=') s += interpret_eq(s - 1);
  487. else (*dest) += sprintf(*dest,"%g",variables[tolower(*s++ - 'a')]);
  488. }
  489. } else {
  490. if(*s == '{') brackets++;
  491. else if(*s == '}') {
  492. brackets--;
  493. if(brackets < 0) {
  494. s++;
  495. break;
  496. }
  497. }
  498. if(strchr(" tnr",*s)) new_word = 1;
  499. else new_word = 0;
  500. *(*dest)++ = *s++;
  501. }
  502. }
  503. return s - src;
  504. }
  505. /*
  506.  */
  507. const char *Parser::interpret(const char *src) {
  508. if(!src) return NULL;
  509. char *dest = new char[2 * 1024 * 1024]; // 2 Mb
  510. try {
  511. char *d = dest;
  512. interpret_main(src,&d);
  513. *d = '';
  514. }
  515. catch(const char *msg) {
  516. fprintf(stderr,"%sn",msg);
  517. delete dest;
  518. return NULL;
  519. }
  520. return dest;
  521. }