finsh_parser.c 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. /*
  2. * script parser for finsh shell.
  3. *
  4. * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
  5. *
  6. * This file is part of RT-Thread (http://www.rt-thread.org)
  7. * Maintainer: bernard.xiong <bernard.xiong at gmail.com>
  8. *
  9. * All rights reserved.
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License along
  22. * with this program; if not, write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  24. *
  25. * Change Logs:
  26. * Date Author Notes
  27. * 2010-03-22 Bernard first version
  28. */
  29. #include <finsh.h>
  30. #include "finsh_token.h"
  31. #include "finsh_node.h"
  32. #include "finsh_error.h"
  33. #include "finsh_parser.h"
  34. #include "finsh_var.h"
  35. /*
  36. * the structure of abstract syntax tree:
  37. * root____________
  38. * | \
  39. * child__ sibling__
  40. * | \ | \
  41. * child sibling child sibling
  42. * ...
  43. */
  44. static enum finsh_type proc_type(struct finsh_parser* self);
  45. static int proc_identifier(struct finsh_parser* self, char* id);
  46. static struct finsh_node* proc_variable_decl(struct finsh_parser* self);
  47. static struct finsh_node* proc_expr(struct finsh_parser* self);
  48. static struct finsh_node* proc_assign_expr(struct finsh_parser* self);
  49. static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self);
  50. static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self);
  51. static struct finsh_node* proc_and_expr(struct finsh_parser* self);
  52. static struct finsh_node* proc_shift_expr(struct finsh_parser* self);
  53. static struct finsh_node* proc_additive_expr(struct finsh_parser* self);
  54. static struct finsh_node* proc_multiplicative_expr(struct finsh_parser* self);
  55. static struct finsh_node* proc_cast_expr(struct finsh_parser* self);
  56. static struct finsh_node* proc_unary_expr(struct finsh_parser* self);
  57. static struct finsh_node* proc_postfix_expr(struct finsh_parser* self);
  58. static struct finsh_node* proc_primary_expr(struct finsh_parser* self);
  59. static struct finsh_node* proc_param_list(struct finsh_parser* self);
  60. static struct finsh_node* proc_expr_statement(struct finsh_parser* self);
  61. static struct finsh_node* make_sys_node(u_char type, struct finsh_node* node1,
  62. struct finsh_node* node2);
  63. /* check token */
  64. #define check_token(token, lex, type) if ( (token) != (type) ) \
  65. { \
  66. finsh_error_set(FINSH_ERROR_INVALID_TOKEN); \
  67. finsh_token_replay(lex); \
  68. }
  69. /* is the token a data type? */
  70. #define is_base_type(token) ((token) == finsh_token_type_void \
  71. || (token) == finsh_token_type_char \
  72. || (token) == finsh_token_type_short \
  73. || (token) == finsh_token_type_int \
  74. || (token) == finsh_token_type_long)
  75. /* get the next token */
  76. #define next_token(token, lex) (token) = finsh_token_token(lex)
  77. /* match a specified token */
  78. #define match_token(token, lex, type) next_token(token, lex); \
  79. check_token(token, lex, type)
  80. /*
  81. process for function and variable declaration.
  82. decl_variable -> type declaration_list ';'
  83. declarator_list -> declarator_list ',' declarator
  84. | declarator
  85. declarator -> identifier
  86. | identifier ASSIGN expr_assign
  87. */
  88. static struct finsh_node* proc_variable_decl(struct finsh_parser* self)
  89. {
  90. enum finsh_token_type token;
  91. enum finsh_type type;
  92. char id[FINSH_NAME_MAX + 1];
  93. struct finsh_node *node;
  94. struct finsh_node *end;
  95. struct finsh_node *assign;
  96. node = NULL;
  97. end = NULL;
  98. /* get type */
  99. type = proc_type(self);
  100. /*process id.*/
  101. if (proc_identifier(self, id) == 0)
  102. {
  103. /* if add variable failed */
  104. if (finsh_var_insert(id, type) < 0)
  105. {
  106. finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
  107. }
  108. }
  109. next_token(token, &(self->token));
  110. switch ( token )
  111. {
  112. case finsh_token_type_comma:/*',', it's a variable_list declaration.*/
  113. if (proc_identifier(self, id) == 0)
  114. {
  115. /* if add variable failed */
  116. if (finsh_var_insert(id, type) < 0)
  117. {
  118. finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
  119. }
  120. }
  121. next_token(token, &(self->token));
  122. if ( token == finsh_token_type_assign )
  123. {
  124. /* get the right side of assign expression */
  125. assign = proc_assign_expr(self);
  126. if (assign != NULL)
  127. {
  128. struct finsh_node* idnode;
  129. idnode = finsh_node_new_id(id);
  130. end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
  131. node = end;
  132. next_token(token, &(self->token));
  133. }
  134. }
  135. while ( token == finsh_token_type_comma )
  136. {
  137. if (proc_identifier(self, id) == 0)
  138. {
  139. /* if add variable failed */
  140. if (finsh_var_insert(id, type) < 0)
  141. {
  142. finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
  143. }
  144. }
  145. next_token(token, &(self->token));
  146. if ( token == finsh_token_type_assign )
  147. {
  148. /* get the right side of assign expression */
  149. assign = proc_assign_expr(self);
  150. if (assign != NULL)
  151. {
  152. struct finsh_node* idnode;
  153. idnode = finsh_node_new_id(id);
  154. /* make assign expression node */
  155. if (node != NULL)
  156. {
  157. finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
  158. end = finsh_node_sibling(end);
  159. }
  160. else
  161. {
  162. end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
  163. node = end;
  164. }
  165. next_token(token, &(self->token));
  166. }
  167. }
  168. }
  169. check_token(token, &(self->token), finsh_token_type_semicolon);
  170. return node;
  171. case finsh_token_type_assign:/*'=', it's a variable with assign declaration.*/
  172. {
  173. struct finsh_node *idnode;
  174. assign = proc_assign_expr(self);
  175. if (assign != NULL)
  176. {
  177. idnode = finsh_node_new_id(id);
  178. /* make assign expression node */
  179. end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
  180. node = end;
  181. next_token(token, &(self->token));
  182. }
  183. while ( token == finsh_token_type_comma )
  184. {
  185. if (proc_identifier(self, id) == 0)
  186. {
  187. /* if add variable failed */
  188. if (finsh_var_insert(id, type) < 0)
  189. {
  190. finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
  191. }
  192. }
  193. next_token(token, &(self->token));
  194. if (token == finsh_token_type_assign)
  195. {
  196. /* get the right side of assign expression */
  197. assign = proc_assign_expr(self);
  198. if (assign != NULL)
  199. {
  200. idnode = finsh_node_new_id(id);
  201. /* make assign expression node */
  202. if (node != NULL)
  203. {
  204. finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
  205. end = finsh_node_sibling(end);
  206. }
  207. else
  208. {
  209. end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
  210. node = end;
  211. }
  212. next_token(token, &(self->token));
  213. }
  214. }
  215. }
  216. check_token(token, &(self->token), finsh_token_type_semicolon);
  217. return node;
  218. }
  219. case finsh_token_type_semicolon:/*';', it's a variable declaration.*/
  220. return node;
  221. default:
  222. finsh_error_set(FINSH_ERROR_EXPECT_TYPE);
  223. return NULL;
  224. }
  225. }
  226. /*
  227. type -> type_prefix type_basic | type_basic
  228. type_prefix -> UNSIGNED
  229. type_basic -> VOID
  230. | CHAR
  231. | SHORT
  232. | INT
  233. | STRING
  234. */
  235. static enum finsh_type proc_type(struct finsh_parser* self)
  236. {
  237. enum finsh_type type;
  238. enum finsh_token_type token;
  239. /* set init type */
  240. type = finsh_type_unknown;
  241. next_token(token, &(self->token));
  242. if ( is_base_type(token) ) /* base_type */
  243. {
  244. switch (token)
  245. {
  246. case finsh_token_type_void:
  247. type = finsh_type_void;
  248. break;
  249. case finsh_token_type_char:
  250. type = finsh_type_char;
  251. break;
  252. case finsh_token_type_short:
  253. type = finsh_type_short;
  254. break;
  255. case finsh_token_type_int:
  256. type = finsh_type_int;
  257. break;
  258. case finsh_token_type_long:
  259. type = finsh_type_long;
  260. break;
  261. default:
  262. goto __return;
  263. }
  264. }
  265. else if ( token == finsh_token_type_unsigned ) /* unsigned base_type */
  266. {
  267. next_token(token, &(self->token));
  268. if ( is_base_type(token) )
  269. {
  270. switch (token)
  271. {
  272. case finsh_token_type_char:
  273. type = finsh_type_uchar;
  274. break;
  275. case finsh_token_type_short:
  276. type = finsh_type_ushort;
  277. break;
  278. case finsh_token_type_int:
  279. type = finsh_type_uint;
  280. break;
  281. case finsh_token_type_long:
  282. type = finsh_type_ulong;
  283. break;
  284. default:
  285. goto __return;
  286. }
  287. }
  288. else
  289. {
  290. finsh_token_replay(&(self->token));
  291. finsh_error_set(FINSH_ERROR_EXPECT_TYPE);
  292. }
  293. }
  294. else
  295. {
  296. goto __return;
  297. }
  298. /* parse for pointer */
  299. next_token(token, &(self->token));
  300. if (token == finsh_token_type_mul)
  301. {
  302. switch (type)
  303. {
  304. case finsh_type_void:
  305. type = finsh_type_voidp;
  306. break;
  307. case finsh_type_char:
  308. case finsh_type_uchar:
  309. type = finsh_type_charp;
  310. break;
  311. case finsh_type_short:
  312. case finsh_type_ushort:
  313. type = finsh_type_shortp;
  314. break;
  315. case finsh_type_int:
  316. case finsh_type_uint:
  317. type = finsh_type_intp;
  318. break;
  319. case finsh_type_long:
  320. case finsh_type_ulong:
  321. type = finsh_type_longp;
  322. break;
  323. default:
  324. type = finsh_type_voidp;
  325. break;
  326. }
  327. }
  328. else finsh_token_replay(&(self->token));
  329. return type;
  330. __return:
  331. finsh_token_replay(&(self->token));
  332. finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
  333. return type;
  334. }
  335. /*
  336. identifier -> IDENTIFIER
  337. */
  338. static int proc_identifier(struct finsh_parser* self, char* id)
  339. {
  340. enum finsh_token_type token;
  341. match_token(token, &(self->token), finsh_token_type_identifier);
  342. strncpy(id, (char*)self->token.string, FINSH_NAME_MAX);
  343. return 0;
  344. }
  345. /*
  346. statement_expr -> ';'
  347. | expr ';'
  348. */
  349. static struct finsh_node* proc_expr_statement(struct finsh_parser* self)
  350. {
  351. enum finsh_token_type token;
  352. struct finsh_node* expr;
  353. expr = NULL;
  354. next_token(token, &(self->token));
  355. if ( token != finsh_token_type_semicolon )
  356. {
  357. finsh_token_replay(&(self->token));
  358. expr = proc_expr(self);
  359. match_token(token, &(self->token), finsh_token_type_semicolon);
  360. }
  361. return expr;
  362. }
  363. /*
  364. expr -> expr_assign
  365. */
  366. static struct finsh_node* proc_expr(struct finsh_parser* self)
  367. {
  368. return proc_assign_expr(self);
  369. }
  370. /*
  371. expr_assign -> expr_inclusive_or
  372. | expr_unary ASSIGN expr_assign
  373. */
  374. static struct finsh_node* proc_assign_expr(struct finsh_parser* self)
  375. {
  376. enum finsh_token_type token;
  377. struct finsh_node* or;
  378. struct finsh_node* assign;
  379. or = proc_inclusive_or_expr(self);
  380. next_token(token, &(self->token));
  381. if (token == finsh_token_type_assign)
  382. {
  383. assign = proc_assign_expr(self);
  384. return make_sys_node(FINSH_NODE_SYS_ASSIGN, or, assign);
  385. }
  386. else finsh_token_replay(&(self->token));
  387. return or;
  388. }
  389. /*
  390. expr_inclusive_or -> expr_exclusive_or
  391. | expr_inclusive_or '|' expr_exclusive_or
  392. */
  393. static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self)
  394. {
  395. enum finsh_token_type token;
  396. struct finsh_node* xor;
  397. struct finsh_node* xor_new;
  398. xor = proc_exclusive_or_expr(self);
  399. next_token(token, &(self->token));
  400. while ( token == finsh_token_type_or )
  401. {
  402. xor_new = proc_exclusive_or_expr(self);
  403. if (xor_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  404. else xor = make_sys_node(FINSH_NODE_SYS_OR, xor, xor_new);
  405. next_token(token, &(self->token));
  406. }
  407. finsh_token_replay(&(self->token));
  408. return xor;
  409. }
  410. /*
  411. expr_exclusive_or -> expr_and
  412. | expr_exclusive '^' expr_and
  413. */
  414. static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self)
  415. {
  416. enum finsh_token_type token;
  417. struct finsh_node* and;
  418. struct finsh_node* and_new;
  419. and = proc_and_expr(self);
  420. next_token(token, &(self->token));
  421. while ( token == finsh_token_type_xor )
  422. {
  423. and_new = proc_and_expr(self);
  424. if (and_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  425. else and = make_sys_node(FINSH_NODE_SYS_XOR, and, and_new);
  426. next_token(token, &(self->token));
  427. }
  428. finsh_token_replay(&(self->token));
  429. return and;
  430. }
  431. /*
  432. expr_and -> expr_shift
  433. | expr_and '&' expr_shift
  434. */
  435. static struct finsh_node* proc_and_expr(struct finsh_parser* self)
  436. {
  437. enum finsh_token_type token;
  438. struct finsh_node* shift;
  439. struct finsh_node* shift_new;
  440. shift = proc_shift_expr(self);
  441. next_token(token, &(self->token));
  442. while ( token == finsh_token_type_and )
  443. {
  444. shift_new = proc_shift_expr(self);
  445. if (shift_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  446. else shift = make_sys_node(FINSH_NODE_SYS_AND, shift, shift_new);
  447. next_token(token, &(self->token));
  448. }
  449. finsh_token_replay(&(self->token));
  450. return shift;
  451. }
  452. /*
  453. expr_shift -> expr_additive
  454. | expr_shift '<<' expr_additive
  455. | expr_shift '>>' expr_additive
  456. */
  457. static struct finsh_node* proc_shift_expr(struct finsh_parser* self)
  458. {
  459. enum finsh_token_type token;
  460. struct finsh_node* add;
  461. struct finsh_node* add_new;
  462. add = proc_additive_expr(self);
  463. next_token(token, &(self->token));
  464. while ( token == finsh_token_type_shl || token == finsh_token_type_shr)
  465. {
  466. add_new = proc_additive_expr(self);
  467. if (add_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  468. else
  469. {
  470. switch (token)
  471. {
  472. case finsh_token_type_shl:
  473. add = make_sys_node(FINSH_NODE_SYS_SHL, add, add_new);
  474. break;
  475. case finsh_token_type_shr:
  476. add = make_sys_node(FINSH_NODE_SYS_SHR, add, add_new);
  477. break;
  478. default:
  479. finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  480. break;
  481. }
  482. }
  483. next_token(token, &(self->token));
  484. }
  485. finsh_token_replay(&(self->token));
  486. return add;
  487. }
  488. /*
  489. expr_additive -> expr_multiplicative
  490. | expr_additive SUB expr_multiplicative
  491. | expr_additive ADD expr_multiplicative
  492. */
  493. static struct finsh_node* proc_additive_expr(struct finsh_parser* self)
  494. {
  495. enum finsh_token_type token;
  496. struct finsh_node* mul;
  497. struct finsh_node* mul_new;
  498. mul = proc_multiplicative_expr(self);
  499. next_token(token, &(self->token));
  500. while ( token == finsh_token_type_sub || token == finsh_token_type_add )
  501. {
  502. mul_new = proc_multiplicative_expr(self);
  503. if (mul_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  504. else
  505. {
  506. switch (token)
  507. {
  508. case finsh_token_type_sub:
  509. mul = make_sys_node(FINSH_NODE_SYS_SUB, mul, mul_new);
  510. break;
  511. case finsh_token_type_add:
  512. mul = make_sys_node(FINSH_NODE_SYS_ADD, mul, mul_new);
  513. break;
  514. default:
  515. finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  516. break;
  517. }
  518. }
  519. next_token(token, &(self->token));
  520. }
  521. finsh_token_replay(&(self->token));
  522. return mul;
  523. }
  524. /*
  525. expr_multiplicative -> expr_cast
  526. | expr_multiplicative '*' expr_cast
  527. | expr_multiplicative '/' expr_cast
  528. | expr_multiplicative '%' expr_cast
  529. */
  530. static struct finsh_node* proc_multiplicative_expr(struct finsh_parser* self)
  531. {
  532. enum finsh_token_type token;
  533. struct finsh_node* cast;
  534. struct finsh_node* cast_new;
  535. cast = proc_cast_expr(self);
  536. next_token(token, &(self->token));
  537. while (token == finsh_token_type_mul ||
  538. token == finsh_token_type_div ||
  539. token == finsh_token_type_mod )
  540. {
  541. cast_new = proc_cast_expr(self);
  542. if (cast_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  543. else
  544. {
  545. switch (token)
  546. {
  547. case finsh_token_type_mul:
  548. cast = make_sys_node(FINSH_NODE_SYS_MUL, cast, cast_new);
  549. break;
  550. case finsh_token_type_div:
  551. cast = make_sys_node(FINSH_NODE_SYS_DIV, cast, cast_new);
  552. break;
  553. case finsh_token_type_mod:
  554. cast = make_sys_node(FINSH_NODE_SYS_MOD, cast, cast_new);
  555. break;
  556. default:
  557. finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  558. break;
  559. }
  560. }
  561. next_token(token, &(self->token));
  562. }
  563. finsh_token_replay(&(self->token));
  564. return cast;
  565. }
  566. /*
  567. 20060313, add recast parse
  568. expr_cast -> expr_unary
  569. | '(' type ')' expr_cast
  570. */
  571. static struct finsh_node* proc_cast_expr(struct finsh_parser* self)
  572. {
  573. enum finsh_token_type token;
  574. enum finsh_type type;
  575. struct finsh_node* cast;
  576. next_token(token, &(self->token));
  577. if (token == finsh_token_type_left_paren)
  578. {
  579. type = proc_type(self);
  580. match_token(token, &(self->token), finsh_token_type_right_paren);
  581. cast = proc_cast_expr(self);
  582. if (cast != NULL)
  583. {
  584. cast->data_type = type;
  585. return cast;
  586. }
  587. }
  588. finsh_token_replay(&(self->token));
  589. return proc_unary_expr(self);
  590. }
  591. /*
  592. 20050921, add '*' and '&'
  593. expr_unary -> expr_postfix
  594. | ADD expr_cast
  595. | INC expr_cast
  596. | SUB expr_cast
  597. | DEC expr_cast
  598. | '~' expr_cast
  599. | '*' expr_cast
  600. | '&' expr_cast
  601. */
  602. static struct finsh_node* proc_unary_expr(struct finsh_parser* self)
  603. {
  604. enum finsh_token_type token;
  605. struct finsh_node *cast;
  606. next_token(token, &(self->token));
  607. switch (token)
  608. {
  609. case finsh_token_type_add: /* + */
  610. cast = proc_cast_expr(self);
  611. return cast;
  612. case finsh_token_type_inc: /* ++ */
  613. cast = proc_cast_expr(self);
  614. return make_sys_node(FINSH_NODE_SYS_PREINC, cast, NULL);
  615. case finsh_token_type_sub: /* - */
  616. cast = proc_cast_expr(self);
  617. return make_sys_node(FINSH_NODE_SYS_SUB, finsh_node_new_long(0), cast);
  618. case finsh_token_type_dec: /* -- */
  619. cast = proc_cast_expr(self);
  620. return make_sys_node(FINSH_NODE_SYS_PREDEC, cast, NULL);
  621. case finsh_token_type_bitwise: /* ~ */
  622. cast = proc_cast_expr(self);
  623. return make_sys_node(FINSH_NODE_SYS_BITWISE, cast, NULL);
  624. case finsh_token_type_mul: /* * */
  625. cast = proc_cast_expr(self);
  626. return make_sys_node(FINSH_NODE_SYS_GETVALUE, cast, NULL);
  627. case finsh_token_type_and: /* & */
  628. cast = proc_cast_expr(self);
  629. return make_sys_node(FINSH_NODE_SYS_GETADDR, cast, NULL);
  630. default:
  631. finsh_token_replay(&(self->token));
  632. return proc_postfix_expr(self);
  633. }
  634. }
  635. /*
  636. expr_postfix -> expr_primary
  637. | expr_postfix INC
  638. | expr_postfix DEC
  639. | expr_postfix '(' param_list ')'
  640. */
  641. static struct finsh_node* proc_postfix_expr(struct finsh_parser* self)
  642. {
  643. enum finsh_token_type token;
  644. struct finsh_node* postfix;
  645. postfix = proc_primary_expr(self);
  646. next_token(token, &(self->token));
  647. while ( token == finsh_token_type_inc ||
  648. token == finsh_token_type_dec ||
  649. token == finsh_token_type_left_paren )
  650. {
  651. switch (token)
  652. {
  653. case finsh_token_type_inc :/* '++' */
  654. postfix = make_sys_node(FINSH_NODE_SYS_INC, postfix, NULL);
  655. break;
  656. case finsh_token_type_dec :/* '--' */
  657. postfix = make_sys_node(FINSH_NODE_SYS_DEC, postfix, NULL);
  658. break;
  659. case finsh_token_type_left_paren :/* '(' */
  660. {
  661. struct finsh_node* param_list;
  662. param_list = NULL;
  663. next_token(token, &(self->token));
  664. if (token != finsh_token_type_right_paren)
  665. {
  666. finsh_token_replay(&(self->token));
  667. param_list = proc_param_list(self);
  668. match_token(token, &(self->token), finsh_token_type_right_paren);
  669. }
  670. postfix = make_sys_node(FINSH_NODE_SYS_FUNC, postfix, param_list);
  671. }
  672. break;
  673. default:
  674. break;
  675. }
  676. next_token(token, &(self->token));
  677. }
  678. finsh_token_replay(&(self->token));
  679. return postfix;
  680. }
  681. /*
  682. expr_primary -> literal
  683. | '(' expr ')'
  684. | identifier
  685. */
  686. static struct finsh_node* proc_primary_expr(struct finsh_parser* self)
  687. {
  688. enum finsh_token_type token;
  689. struct finsh_node* expr;
  690. next_token(token, &(self->token));
  691. switch ( token )
  692. {
  693. case finsh_token_type_identifier:
  694. {
  695. char id[FINSH_NAME_MAX + 1];
  696. finsh_token_replay(&(self->token));
  697. proc_identifier(self, id);
  698. return finsh_node_new_id(id);
  699. }
  700. case finsh_token_type_left_paren:
  701. expr = proc_expr(self);
  702. match_token(token, &(self->token), finsh_token_type_right_paren);
  703. return expr;
  704. case finsh_token_type_value_int:
  705. return finsh_node_new_int(self->token.value.int_value);
  706. case finsh_token_type_value_long:
  707. return finsh_node_new_long(self->token.value.long_value);
  708. case finsh_token_type_value_char:
  709. return finsh_node_new_char(self->token.value.char_value);
  710. case finsh_token_type_value_string:
  711. return finsh_node_new_string((char*)self->token.string);
  712. case finsh_token_type_value_null:
  713. return finsh_node_new_ptr(NULL);
  714. default:
  715. finsh_error_set(FINSH_ERROR_INVALID_TOKEN);
  716. break;
  717. }
  718. return NULL;
  719. }
  720. /*
  721. param_list -> empty
  722. | expr_assign
  723. | param_list ',' expr_assign
  724. */
  725. static struct finsh_node* proc_param_list(struct finsh_parser* self)
  726. {
  727. enum finsh_token_type token;
  728. struct finsh_node *node, *assign;
  729. assign = proc_assign_expr(self);
  730. if (assign == NULL) return NULL;
  731. node = assign;
  732. next_token(token, &(self->token));
  733. while (token == finsh_token_type_comma )
  734. {
  735. finsh_node_sibling(assign) = proc_assign_expr(self);
  736. if (finsh_node_sibling(assign) != NULL) assign = finsh_node_sibling(assign);
  737. else finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
  738. next_token(token, &(self->token));
  739. }
  740. finsh_token_replay(&(self->token));
  741. return node;
  742. }
  743. /*
  744. make a new node as following tree:
  745. new_node
  746. |
  747. node1__
  748. \
  749. node2
  750. */
  751. static struct finsh_node* make_sys_node(u_char type, struct finsh_node* node1, struct finsh_node* node2)
  752. {
  753. struct finsh_node* node;
  754. node = finsh_node_allocate(type);
  755. if ((node1 != NULL) && (node != NULL))
  756. {
  757. finsh_node_child(node) = node1;
  758. finsh_node_sibling(node1) = node2;
  759. }
  760. else finsh_error_set(FINSH_ERROR_NULL_NODE);
  761. return node;
  762. }
  763. /*
  764. start -> statement_expr | decl_variable
  765. */
  766. void finsh_parser_run(struct finsh_parser* self, const u_char* string)
  767. {
  768. enum finsh_token_type token;
  769. struct finsh_node *node;
  770. node = NULL;
  771. /* init parser */
  772. self->parser_string = (u_char*)string;
  773. /* init token */
  774. finsh_token_init(&(self->token), self->parser_string);
  775. /* get next token */
  776. next_token(token, &(self->token));
  777. while (token != finsh_token_type_eof && token != finsh_token_type_bad)
  778. {
  779. switch (token)
  780. {
  781. case finsh_token_type_identifier:
  782. /* process expr_statement */
  783. finsh_token_replay(&(self->token));
  784. if (self->root != NULL)
  785. {
  786. finsh_node_sibling(node) = proc_expr_statement(self);
  787. if (finsh_node_sibling(node) != NULL)
  788. node = finsh_node_sibling(node);
  789. }
  790. else
  791. {
  792. node = proc_expr_statement(self);
  793. self->root = node;
  794. }
  795. break;
  796. default:
  797. if (is_base_type(token) || token == finsh_token_type_unsigned)
  798. {
  799. /* variable decl */
  800. finsh_token_replay(&(self->token));
  801. if (self->root != NULL)
  802. {
  803. finsh_node_sibling(node) = proc_variable_decl(self);
  804. if (finsh_node_sibling(node) != NULL)
  805. node = finsh_node_sibling(node);
  806. }
  807. else
  808. {
  809. node = proc_variable_decl(self);
  810. self->root = node;
  811. }
  812. }
  813. else
  814. {
  815. /* process expr_statement */
  816. finsh_token_replay(&(self->token));
  817. if (self->root != NULL)
  818. {
  819. finsh_node_sibling(node) = proc_expr_statement(self);
  820. if (finsh_node_sibling(node) != NULL)
  821. node = finsh_node_sibling(node);
  822. else next_token(token, &(self->token));
  823. }
  824. else
  825. {
  826. node = proc_expr_statement(self);
  827. self->root = node;
  828. }
  829. }
  830. break;
  831. }
  832. /* get next token */
  833. next_token(token, &(self->token));
  834. }
  835. }
  836. int finsh_parser_init(struct finsh_parser* self)
  837. {
  838. memset(self, 0, sizeof(struct finsh_parser));
  839. return 0;
  840. }