gs_token.c
上传用户:mei_mei897
上传日期:2007-01-05
资源大小:82k
文件大小:16k
源码类别:

手机短信编程

开发平台:

Unix_Linux

  1. /* -------------------------------------------------------------------- */
  2. /* SMS Client, send messages to mobile phones and pagers */
  3. /* */
  4. /* gs_token.c */
  5. /* */
  6. /*  Copyright (C) 1997,1998 Angelo Masci */
  7. /* */
  8. /*  This library is free software; you can redistribute it and/or */
  9. /*  modify it under the terms of the GNU Library General Public */
  10. /*  License as published by the Free Software Foundation; either */
  11. /*  version 2 of the License, or (at your option) any later version. */
  12. /* */
  13. /*  This library is distributed in the hope that it will be useful, */
  14. /*  but WITHOUT ANY WARRANTY; without even the implied warranty of */
  15. /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU */
  16. /*  Library General Public License for more details. */
  17. /* */
  18. /*  You should have received a copy of the GNU Library General Public */
  19. /*  License along with this library; if not, write to the Free */
  20. /*  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  21. /* */
  22. /*  You can contact the author at this e-mail address: */
  23. /* */
  24. /*  angelo@styx.demon.co.uk */
  25. /* */
  26. /* -------------------------------------------------------------------- */
  27. /* $Id$
  28.    -------------------------------------------------------------------- */
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <ctype.h>
  32. #include <stdlib.h>
  33. #include "common.h"
  34. #include "logfile.h"
  35. #include "gs_token.h"
  36. #include "gs_list.h"
  37. /* -------------------------------------------------------------------- */
  38. TOKEN_ID
  39. null_tok,
  40. eof_tok,
  41. assignment_tok,
  42. lparen_tok,
  43. rparen_tok,
  44. lcurly_tok,
  45. rcurly_tok,
  46. comma_tok,
  47. dot_tok,
  48. semicolon_tok;
  49. struct init_token_struct
  50. {
  51. TOKEN_ID 
  52. *var;
  53. char *str;
  54. int type;
  55. int type_ptr;
  56. void *ptr;
  57. } init_token_table[] =
  58. {
  59. { &null_tok,  "<NULL>",  T_SPECIAL, 0, NULL },
  60. { &eof_tok,  "<EOF>",  T_SPECIAL, 0, NULL },
  61. { &assignment_tok,  "=",  T_SPECIAL, 0, NULL },
  62. { &lparen_tok,  "(",  T_SPECIAL, 0, NULL },
  63. { &rparen_tok,  ")",  T_SPECIAL, 0, NULL },
  64. { &lcurly_tok,  "{",  T_SPECIAL, 0, NULL },
  65. { &rcurly_tok,  "}",  T_SPECIAL, 0, NULL },
  66. { &comma_tok,  ",",  T_SPECIAL, 0, NULL },
  67. { &dot_tok,  ".",  T_SPECIAL, 0, NULL },
  68. { &semicolon_tok,  ";",  T_SPECIAL, 0, NULL },
  69. { NULL,  NULL,  T_SPECIAL, 0, NULL }
  70. };
  71. static TOKEN_ID
  72. token_pushed = NULL;
  73. static TOKEN_HEAP
  74. builtin = { NULL };
  75. static FILE *parser_fp = stdin;
  76. /* -------------------------------------------------------------------- */
  77. #define MAX_CHARACTER_STACK 512
  78. static char character_stack[MAX_CHARACTER_STACK];
  79. static int  character_stack_top = -1;
  80. /* -------------------------------------------------------------------- */
  81. static int get_next_character(void);
  82. static int is_valid_identifier_character(int character);
  83. static int push_character(int character);
  84. static int pop_character(void);
  85. static int escape_char(void);
  86. /* -------------------------------------------------------------------- */
  87. /* -------------------------------------------------------------------- */
  88. int gs_open(char *file)
  89. {
  90. parser_fp = fopen(file, "r");
  91. if (parser_fp == NULL)
  92. { return -1;
  93. }
  94. return 0;
  95. }
  96. /* -------------------------------------------------------------------- */
  97. /* -------------------------------------------------------------------- */
  98. int gs_close(void)
  99. {
  100. if (fileno(stdin) == fileno(parser_fp))
  101. { return 0;
  102. }
  103. return fclose(parser_fp);
  104. }
  105. /* -------------------------------------------------------------------- */
  106. /* If we have pushed back a character then return it, else */
  107. /* return the next character. */
  108. /* -------------------------------------------------------------------- */
  109. static int get_next_character(void)
  110. {
  111. int  character;
  112. character = pop_character();
  113. if (character != -1)
  114. { return character;
  115. }
  116. return fgetc(parser_fp);
  117. }
  118. /* -------------------------------------------------------------------- */
  119. /* -------------------------------------------------------------------- */
  120. static int push_character(int character)
  121. {
  122. if (character_stack_top +1 >= MAX_CHARACTER_STACK)
  123. {
  124. return -1;
  125. }
  126. character_stack_top++;
  127. character_stack[character_stack_top] = character;
  128. return 0;
  129. }
  130. /* -------------------------------------------------------------------- */
  131. /* -------------------------------------------------------------------- */
  132. static int pop_character(void)
  133. {
  134. int character;
  135. if (character_stack_top == -1)
  136. { return -1;
  137. }
  138. character = character_stack[character_stack_top];
  139. character_stack_top--;
  140. return character;
  141. }
  142. /* -------------------------------------------------------------------- */
  143. /* -------------------------------------------------------------------- */
  144. void push_back_token(TOKEN_ID token)
  145. { token_pushed = token;
  146. }
  147. /* -------------------------------------------------------------------- */
  148. /* -------------------------------------------------------------------- */
  149. static int is_valid_identifier_character(int character)
  150. {
  151. if ((isalpha(character)) || (character == '_'))
  152. { return TRUE;
  153. }
  154. return FALSE;
  155. }
  156. /* -------------------------------------------------------------------- */
  157. /* -------------------------------------------------------------------- */
  158. static int escape_char(void)
  159. {
  160. int  character, 
  161. escaped_character;
  162. character = get_next_character();
  163. if (character == 'a')
  164. { escaped_character = 'f';
  165. }
  166. else
  167. if (character == 'b')
  168. { escaped_character = 'b';
  169. }
  170. else
  171. if (character == 'f')
  172. { escaped_character = 'f';
  173. }
  174. else
  175. if (character == 'n')
  176. { escaped_character = 'n';
  177. }
  178. else
  179. if (character == 'r')
  180. { escaped_character = 'r';
  181. }
  182. else
  183. if (character == 't')
  184. { escaped_character = 't';
  185. }
  186. else
  187. if (character == 'v')
  188. { escaped_character = 'v';
  189. }
  190. else
  191. if (character == 'x')
  192. {
  193. int low_nibble,
  194. high_nibble,
  195. high_character,
  196. low_character;
  197. character = get_next_character();
  198. high_character = character;
  199. if (isxdigit(character))
  200. {
  201. if ((character >= '0') && (character <= '9'))
  202. {
  203. high_nibble = (character - '0') << 4;
  204. }
  205. else
  206. if ((character >= 'a') && (character <= 'f'))
  207. {
  208. high_nibble = (10 + (character - 'a')) << 4;
  209. }
  210. else
  211. { high_nibble = (10 + (character - 'A')) << 4;
  212. }
  213. character = get_next_character();
  214. low_character = character;
  215. if (isxdigit(character))
  216. {
  217. if ((character >= '0') && (character <= '9'))
  218. {
  219. low_nibble = (character - '0');
  220. }
  221. else
  222. if ((character >= 'a') && (character <= 'f'))
  223. {
  224. low_nibble = (10 + (character - 'a'));
  225. }
  226. else
  227. { low_nibble = (10 + (character - 'A'));
  228. }
  229. escaped_character = high_nibble + low_nibble;
  230. }
  231. else
  232. {
  233. /* Error */
  234. push_character('x');
  235. push_character(high_character);
  236. push_character(low_character);
  237. escaped_character = '\';
  238. }
  239. }
  240. else
  241. {
  242. /* Error */
  243. push_character('x');
  244. push_character(high_character);
  245. escaped_character = '\';
  246. }
  247. }
  248. else
  249. if (character == '\')
  250. { escaped_character = '\';
  251. }
  252. else
  253. if (character == '"')
  254. { escaped_character = '"';
  255. }
  256. else
  257. if (character == ''')
  258. { escaped_character = ''';
  259. }
  260. else
  261. {
  262. /* Error */
  263. push_character(character);
  264. escaped_character = '\';
  265. }
  266. return escaped_character;
  267. }
  268. /* -------------------------------------------------------------------- */
  269. /* -------------------------------------------------------------------- */
  270. TOKEN_ID get_next_token(TOKEN_HEAP *heap)
  271. {
  272. char   str[1024],
  273. *str_ptr;
  274. int  character;
  275. TOKEN_ID
  276. token_id;
  277. if (token_pushed != NULL)
  278. {
  279. token_id = token_pushed;
  280. token_pushed = NULL;
  281. return token_id;
  282. }
  283. character = get_next_character();
  284. /* ---------------------------- */
  285. /* Throw away any whitespace  */
  286. /* ---------------------------- */
  287. while (isspace(character))
  288. { character = get_next_character();
  289. }
  290. /* ---------------------------- */
  291. /* Identifier */
  292. /* ---------------------------- */
  293. if (is_valid_identifier_character(character))
  294. {
  295. str_ptr = str;
  296. while (is_valid_identifier_character(character))
  297. {
  298. *str_ptr++ = character;
  299.  character = get_next_character();
  300. }
  301. *str_ptr = '';
  302. push_character(character);
  303. lprintf(LOG_VERYVERBOSE, "Found Identifier '%s'n", str);
  304. token_id = add_token(heap, str, T_IDENTIFIER, NULL);
  305. }
  306. else
  307. if (character == '"') 
  308. {
  309. character = get_next_character();
  310. str_ptr = str;
  311. while ((character != '"') && (character != EOF))
  312. {
  313. if (character == '\')
  314. {
  315. *str_ptr++ = escape_char();
  316. }
  317. else
  318. { *str_ptr++ = character;
  319. }
  320. character = get_next_character();
  321. }
  322. *str_ptr = '';
  323. if (character == '"')
  324. {
  325. lprintf(LOG_VERYVERBOSE, "Found Identifier '%s'n", str);
  326. token_id = add_token(heap, str, T_STRING, NULL);
  327. }
  328. else
  329. { token_id = null_tok;
  330. }
  331. }
  332. else
  333. if (character == ''') 
  334. {
  335. character = get_next_character();
  336. str_ptr = str;
  337. while ((character != ''') && (character != EOF))
  338. {
  339. *str_ptr++ = character;
  340.  character = get_next_character();
  341. }
  342. *str_ptr = '';
  343. if (character == ''')
  344. {
  345. lprintf(LOG_VERYVERBOSE, "Found Identifier '%s'n", str);
  346. token_id = add_token(heap, str, T_STRING, NULL);
  347. }
  348. else
  349. { token_id = null_tok;
  350. }
  351. }
  352. else
  353. if (character == '=')
  354. { token_id = assignment_tok;
  355. }
  356. else
  357. if (character == '(')
  358. { token_id = lparen_tok;
  359. }
  360. else
  361. if (character == ')')
  362. { token_id = rparen_tok;
  363. }
  364. else
  365. if (character == '{')
  366. { token_id = lcurly_tok;
  367. }
  368. else
  369. if (character == '}')
  370. { token_id = rcurly_tok;
  371. }
  372. else
  373. if (character == ',')
  374. { token_id = comma_tok;
  375. }
  376. else
  377. if (character == '.')
  378. { token_id = dot_tok;
  379. }
  380. else
  381. if (character == ';')
  382. { token_id = semicolon_tok;
  383. }
  384. else
  385. if (character == EOF)
  386. { token_id = eof_tok;
  387. }
  388. else
  389. { token_id = null_tok;
  390. }
  391. lprintf(LOG_VERYVERBOSE, "Token id = %pn", token_id);
  392. return token_id;
  393. }
  394. /* -------------------------------------------------------------------- */
  395. /* Add token searches the token heap for 'str' */
  396. /* -------------------------------------------------------------------- */
  397. TOKEN_ID add_token(TOKEN_HEAP *heap, char *str, int type, void *ptr)
  398. {
  399. TOKEN_ID
  400. token;
  401. lprintf(LOG_VERYVERBOSE, "Entering add_token()n");
  402. heap->list = add_token_list_item(heap->list, &token, str, type, 0, ptr);
  403. lprintf(LOG_VERYVERBOSE, "returning %pn", token);
  404. return token;
  405. }
  406. /* -------------------------------------------------------------------- */
  407. /* -------------------------------------------------------------------- */
  408. char *get_token_strvalue(TOKEN_HEAP *heap, TOKEN_ID token_id)
  409. { return token_id->str;
  410. }
  411. /* -------------------------------------------------------------------- */
  412. /* -------------------------------------------------------------------- */
  413. char *get_token_strtype(TOKEN_HEAP *heap, TOKEN_ID token_id)
  414. { return "UNKNOWN";
  415. }
  416. /* -------------------------------------------------------------------- */
  417. /* -------------------------------------------------------------------- */
  418. int get_token_type(TOKEN_HEAP *heap, TOKEN_ID token_id)
  419. { return token_id->type;
  420. }
  421. /* -------------------------------------------------------------------- */
  422. /* -------------------------------------------------------------------- */
  423. int get_token_indirect_type(TOKEN_HEAP *heap, TOKEN_ID token_id)
  424. { return token_id->ptr_type;
  425. }
  426. /* -------------------------------------------------------------------- */
  427. /* -------------------------------------------------------------------- */
  428. char *get_token_indirect_string(TOKEN_HEAP *heap, TOKEN_ID token_id)
  429. { return token_id->ptr;
  430. }
  431. /* -------------------------------------------------------------------- */
  432. /* -------------------------------------------------------------------- */
  433. TOKEN_HEAP *get_token_indirect_dictionary(TOKEN_HEAP *heap, TOKEN_ID token_id)
  434. { return (TOKEN_HEAP *)token_id->ptr;
  435. }
  436. /* -------------------------------------------------------------------- */
  437. /* -------------------------------------------------------------------- */
  438. TOKEN_HEAP *get_token_indirect_list(TOKEN_HEAP *heap, TOKEN_ID token_id)
  439. { return (TOKEN_HEAP *)token_id->ptr;
  440. }
  441. /* -------------------------------------------------------------------- */
  442. /* -------------------------------------------------------------------- */
  443. void token_assign_value(TOKEN_HEAP *heap, TOKEN_ID token_id, char *string)
  444. {
  445. token_id->ptr_type = TP_STRING;
  446. token_id->ptr      = string;
  447. }
  448. /* -------------------------------------------------------------------- */
  449. /* -------------------------------------------------------------------- */
  450. void token_assign_dictionary(TOKEN_HEAP *heap, TOKEN_ID token_id, TOKEN_HEAP *dictionary)
  451. {
  452. token_id->ptr_type = TP_DICTIONARY;
  453. token_id->ptr      = dictionary;
  454. }
  455. /* -------------------------------------------------------------------- */
  456. /* -------------------------------------------------------------------- */
  457. void token_assign_list(TOKEN_HEAP *heap, TOKEN_ID token_id, TOKEN_HEAP *list)
  458. {
  459. token_id->ptr_type = TP_LIST;
  460. token_id->ptr      = list;
  461. }
  462. /* -------------------------------------------------------------------- */
  463. /* Add our reserved tokens to the reserved builtin heap. */
  464. /* if builtin heap has been filled by an earlier call just */
  465. /* return from this function. */
  466. /* -------------------------------------------------------------------- */
  467. void init_builtin_heap(void)
  468. {
  469. int  i;
  470. if (builtin.list == NULL)
  471. {
  472. for (i=0; init_token_table[i].var != NULL; i++)
  473. {
  474. *(init_token_table[i].var) = add_token(&builtin, 
  475.                                        init_token_table[i].str,
  476.                                        init_token_table[i].type,
  477.                                        init_token_table[i].ptr);
  478. }
  479. }
  480. }
  481. /* -------------------------------------------------------------------- */
  482. /* -------------------------------------------------------------------- */
  483. void init_heap(TOKEN_HEAP *heap)
  484. {
  485. heap->list = NULL;
  486. }
  487. /* -------------------------------------------------------------------- */
  488. /* -------------------------------------------------------------------- */
  489. TOKEN_HEAP *generate_new_heap(void)
  490. {
  491. TOKEN_HEAP
  492. *heap;
  493. heap = (TOKEN_HEAP *)malloc(sizeof(TOKEN_HEAP));
  494. if (heap == NULL)
  495. { return heap;
  496. }
  497. init_heap(heap);
  498. return heap;
  499. }
  500. /* -------------------------------------------------------------------- */
  501. /* -------------------------------------------------------------------- */
  502. void dump_heap(TOKEN_HEAP *heap, char *name)
  503. {
  504. TOKEN_LIST
  505. *item;
  506. TOKEN_ID
  507. token;
  508. fprintf(stdout, " %s = { n", name);
  509. item = heap->list;
  510. while(item != NULL)
  511. {
  512. token = item->token;
  513. if (get_token_type(heap, token) == T_IDENTIFIER)
  514. {
  515. if (get_token_indirect_type(heap, token) == TP_STRING)
  516. {
  517. fprintf(stdout, "%s = %sn", 
  518.         get_token_strvalue(heap, token),
  519.         get_token_indirect_string(heap, token));
  520. }
  521. else
  522. if (get_token_indirect_type(heap, token) == TP_DICTIONARY)
  523. {
  524. dump_heap(get_token_indirect_dictionary(heap, token), 
  525.             get_token_strvalue(heap, token));
  526. }
  527. else
  528. if (get_token_indirect_type(heap, token) == TP_LIST)
  529. {
  530. dump_heap(get_token_indirect_list(heap, token), 
  531.             get_token_strvalue(heap, token));
  532. }
  533. }
  534. item = item->next;
  535. }
  536. fprintf(stdout, " }n");
  537. }
  538. /* -------------------------------------------------------------------- */
  539. /* -------------------------------------------------------------------- */
  540. void free_heap(TOKEN_HEAP *heap)
  541. {
  542. TOKEN_LIST
  543. *item,
  544. *prev_item;
  545. TOKEN_ID
  546. token;
  547. item = heap->list;
  548. while(item != NULL)
  549. {
  550. token = item->token;
  551. if (get_token_type(heap, token) == T_IDENTIFIER)
  552. {
  553. if (get_token_indirect_type(heap, token) == TP_DICTIONARY)
  554. {
  555. free_heap(get_token_indirect_dictionary(heap, token));
  556. }
  557. else
  558. if (get_token_indirect_type(heap, token) == TP_LIST)
  559. {
  560. free_heap(get_token_indirect_list(heap, token));
  561. }
  562. }
  563. prev_item = item;
  564. item = item->next;
  565. free(prev_item->token->str);
  566. free(prev_item->token);
  567. free(prev_item);
  568. }
  569. }