gs_token.c
上传用户:mei_mei897
上传日期:2007-01-05
资源大小:82k
文件大小:16k
- /* -------------------------------------------------------------------- */
- /* SMS Client, send messages to mobile phones and pagers */
- /* */
- /* gs_token.c */
- /* */
- /* Copyright (C) 1997,1998 Angelo Masci */
- /* */
- /* This library is free software; you can redistribute it and/or */
- /* modify it under the terms of the GNU Library General Public */
- /* License as published by the Free Software Foundation; either */
- /* version 2 of the License, or (at your option) any later version. */
- /* */
- /* This library is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
- /* Library General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU Library General Public */
- /* License along with this library; if not, write to the Free */
- /* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* You can contact the author at this e-mail address: */
- /* */
- /* angelo@styx.demon.co.uk */
- /* */
- /* -------------------------------------------------------------------- */
- /* $Id$
- -------------------------------------------------------------------- */
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include "common.h"
- #include "logfile.h"
- #include "gs_token.h"
- #include "gs_list.h"
- /* -------------------------------------------------------------------- */
- TOKEN_ID
- null_tok,
- eof_tok,
- assignment_tok,
- lparen_tok,
- rparen_tok,
- lcurly_tok,
- rcurly_tok,
- comma_tok,
- dot_tok,
- semicolon_tok;
- struct init_token_struct
- {
- TOKEN_ID
- *var;
- char *str;
- int type;
- int type_ptr;
- void *ptr;
- } init_token_table[] =
- {
- { &null_tok, "<NULL>", T_SPECIAL, 0, NULL },
- { &eof_tok, "<EOF>", T_SPECIAL, 0, NULL },
- { &assignment_tok, "=", T_SPECIAL, 0, NULL },
- { &lparen_tok, "(", T_SPECIAL, 0, NULL },
- { &rparen_tok, ")", T_SPECIAL, 0, NULL },
- { &lcurly_tok, "{", T_SPECIAL, 0, NULL },
- { &rcurly_tok, "}", T_SPECIAL, 0, NULL },
- { &comma_tok, ",", T_SPECIAL, 0, NULL },
- { &dot_tok, ".", T_SPECIAL, 0, NULL },
- { &semicolon_tok, ";", T_SPECIAL, 0, NULL },
- { NULL, NULL, T_SPECIAL, 0, NULL }
- };
- static TOKEN_ID
- token_pushed = NULL;
- static TOKEN_HEAP
- builtin = { NULL };
- static FILE *parser_fp = stdin;
- /* -------------------------------------------------------------------- */
- #define MAX_CHARACTER_STACK 512
- static char character_stack[MAX_CHARACTER_STACK];
- static int character_stack_top = -1;
- /* -------------------------------------------------------------------- */
- static int get_next_character(void);
- static int is_valid_identifier_character(int character);
- static int push_character(int character);
- static int pop_character(void);
- static int escape_char(void);
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- int gs_open(char *file)
- {
- parser_fp = fopen(file, "r");
- if (parser_fp == NULL)
- { return -1;
- }
- return 0;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- int gs_close(void)
- {
- if (fileno(stdin) == fileno(parser_fp))
- { return 0;
- }
- return fclose(parser_fp);
- }
- /* -------------------------------------------------------------------- */
- /* If we have pushed back a character then return it, else */
- /* return the next character. */
- /* -------------------------------------------------------------------- */
- static int get_next_character(void)
- {
- int character;
- character = pop_character();
- if (character != -1)
- { return character;
- }
- return fgetc(parser_fp);
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- static int push_character(int character)
- {
- if (character_stack_top +1 >= MAX_CHARACTER_STACK)
- {
- return -1;
- }
- character_stack_top++;
- character_stack[character_stack_top] = character;
- return 0;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- static int pop_character(void)
- {
- int character;
- if (character_stack_top == -1)
- { return -1;
- }
- character = character_stack[character_stack_top];
- character_stack_top--;
- return character;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- void push_back_token(TOKEN_ID token)
- { token_pushed = token;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- static int is_valid_identifier_character(int character)
- {
- if ((isalpha(character)) || (character == '_'))
- { return TRUE;
- }
- return FALSE;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- static int escape_char(void)
- {
- int character,
- escaped_character;
- character = get_next_character();
- if (character == 'a')
- { escaped_character = 'f';
- }
- else
- if (character == 'b')
- { escaped_character = 'b';
- }
- else
- if (character == 'f')
- { escaped_character = 'f';
- }
- else
- if (character == 'n')
- { escaped_character = 'n';
- }
- else
- if (character == 'r')
- { escaped_character = 'r';
- }
- else
- if (character == 't')
- { escaped_character = 't';
- }
- else
- if (character == 'v')
- { escaped_character = 'v';
- }
- else
- if (character == 'x')
- {
- int low_nibble,
- high_nibble,
- high_character,
- low_character;
- character = get_next_character();
- high_character = character;
- if (isxdigit(character))
- {
- if ((character >= '0') && (character <= '9'))
- {
- high_nibble = (character - '0') << 4;
- }
- else
- if ((character >= 'a') && (character <= 'f'))
- {
- high_nibble = (10 + (character - 'a')) << 4;
- }
- else
- { high_nibble = (10 + (character - 'A')) << 4;
- }
- character = get_next_character();
- low_character = character;
- if (isxdigit(character))
- {
- if ((character >= '0') && (character <= '9'))
- {
- low_nibble = (character - '0');
- }
- else
- if ((character >= 'a') && (character <= 'f'))
- {
- low_nibble = (10 + (character - 'a'));
- }
- else
- { low_nibble = (10 + (character - 'A'));
- }
- escaped_character = high_nibble + low_nibble;
- }
- else
- {
- /* Error */
- push_character('x');
- push_character(high_character);
- push_character(low_character);
- escaped_character = '\';
- }
- }
- else
- {
- /* Error */
- push_character('x');
- push_character(high_character);
- escaped_character = '\';
- }
- }
- else
- if (character == '\')
- { escaped_character = '\';
- }
- else
- if (character == '"')
- { escaped_character = '"';
- }
- else
- if (character == ''')
- { escaped_character = ''';
- }
- else
- {
- /* Error */
- push_character(character);
- escaped_character = '\';
- }
- return escaped_character;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- TOKEN_ID get_next_token(TOKEN_HEAP *heap)
- {
- char str[1024],
- *str_ptr;
- int character;
- TOKEN_ID
- token_id;
-
- if (token_pushed != NULL)
- {
- token_id = token_pushed;
- token_pushed = NULL;
- return token_id;
- }
- character = get_next_character();
- /* ---------------------------- */
- /* Throw away any whitespace */
- /* ---------------------------- */
- while (isspace(character))
- { character = get_next_character();
- }
- /* ---------------------------- */
- /* Identifier */
- /* ---------------------------- */
- if (is_valid_identifier_character(character))
- {
- str_ptr = str;
- while (is_valid_identifier_character(character))
- {
- *str_ptr++ = character;
- character = get_next_character();
- }
- *str_ptr = ' ';
- push_character(character);
-
- lprintf(LOG_VERYVERBOSE, "Found Identifier '%s'n", str);
- token_id = add_token(heap, str, T_IDENTIFIER, NULL);
- }
- else
- if (character == '"')
- {
- character = get_next_character();
- str_ptr = str;
- while ((character != '"') && (character != EOF))
- {
- if (character == '\')
- {
- *str_ptr++ = escape_char();
- }
- else
- { *str_ptr++ = character;
- }
- character = get_next_character();
- }
- *str_ptr = ' ';
- if (character == '"')
- {
- lprintf(LOG_VERYVERBOSE, "Found Identifier '%s'n", str);
- token_id = add_token(heap, str, T_STRING, NULL);
- }
- else
- { token_id = null_tok;
- }
- }
- else
- if (character == ''')
- {
- character = get_next_character();
- str_ptr = str;
- while ((character != ''') && (character != EOF))
- {
- *str_ptr++ = character;
- character = get_next_character();
- }
- *str_ptr = ' ';
- if (character == ''')
- {
- lprintf(LOG_VERYVERBOSE, "Found Identifier '%s'n", str);
- token_id = add_token(heap, str, T_STRING, NULL);
- }
- else
- { token_id = null_tok;
- }
- }
- else
- if (character == '=')
- { token_id = assignment_tok;
- }
- else
- if (character == '(')
- { token_id = lparen_tok;
- }
- else
- if (character == ')')
- { token_id = rparen_tok;
- }
- else
- if (character == '{')
- { token_id = lcurly_tok;
- }
- else
- if (character == '}')
- { token_id = rcurly_tok;
- }
- else
- if (character == ',')
- { token_id = comma_tok;
- }
- else
- if (character == '.')
- { token_id = dot_tok;
- }
- else
- if (character == ';')
- { token_id = semicolon_tok;
- }
- else
- if (character == EOF)
- { token_id = eof_tok;
- }
- else
- { token_id = null_tok;
- }
- lprintf(LOG_VERYVERBOSE, "Token id = %pn", token_id);
- return token_id;
- }
- /* -------------------------------------------------------------------- */
- /* Add token searches the token heap for 'str' */
- /* -------------------------------------------------------------------- */
- TOKEN_ID add_token(TOKEN_HEAP *heap, char *str, int type, void *ptr)
- {
- TOKEN_ID
- token;
- lprintf(LOG_VERYVERBOSE, "Entering add_token()n");
- heap->list = add_token_list_item(heap->list, &token, str, type, 0, ptr);
- lprintf(LOG_VERYVERBOSE, "returning %pn", token);
- return token;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- char *get_token_strvalue(TOKEN_HEAP *heap, TOKEN_ID token_id)
- { return token_id->str;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- char *get_token_strtype(TOKEN_HEAP *heap, TOKEN_ID token_id)
- { return "UNKNOWN";
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- int get_token_type(TOKEN_HEAP *heap, TOKEN_ID token_id)
- { return token_id->type;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- int get_token_indirect_type(TOKEN_HEAP *heap, TOKEN_ID token_id)
- { return token_id->ptr_type;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- char *get_token_indirect_string(TOKEN_HEAP *heap, TOKEN_ID token_id)
- { return token_id->ptr;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- TOKEN_HEAP *get_token_indirect_dictionary(TOKEN_HEAP *heap, TOKEN_ID token_id)
- { return (TOKEN_HEAP *)token_id->ptr;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- TOKEN_HEAP *get_token_indirect_list(TOKEN_HEAP *heap, TOKEN_ID token_id)
- { return (TOKEN_HEAP *)token_id->ptr;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- void token_assign_value(TOKEN_HEAP *heap, TOKEN_ID token_id, char *string)
- {
- token_id->ptr_type = TP_STRING;
- token_id->ptr = string;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- void token_assign_dictionary(TOKEN_HEAP *heap, TOKEN_ID token_id, TOKEN_HEAP *dictionary)
- {
- token_id->ptr_type = TP_DICTIONARY;
- token_id->ptr = dictionary;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- void token_assign_list(TOKEN_HEAP *heap, TOKEN_ID token_id, TOKEN_HEAP *list)
- {
- token_id->ptr_type = TP_LIST;
- token_id->ptr = list;
- }
- /* -------------------------------------------------------------------- */
- /* Add our reserved tokens to the reserved builtin heap. */
- /* if builtin heap has been filled by an earlier call just */
- /* return from this function. */
- /* -------------------------------------------------------------------- */
- void init_builtin_heap(void)
- {
- int i;
- if (builtin.list == NULL)
- {
- for (i=0; init_token_table[i].var != NULL; i++)
- {
- *(init_token_table[i].var) = add_token(&builtin,
- init_token_table[i].str,
- init_token_table[i].type,
- init_token_table[i].ptr);
- }
- }
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- void init_heap(TOKEN_HEAP *heap)
- {
- heap->list = NULL;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- TOKEN_HEAP *generate_new_heap(void)
- {
- TOKEN_HEAP
- *heap;
- heap = (TOKEN_HEAP *)malloc(sizeof(TOKEN_HEAP));
- if (heap == NULL)
- { return heap;
- }
- init_heap(heap);
- return heap;
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- void dump_heap(TOKEN_HEAP *heap, char *name)
- {
- TOKEN_LIST
- *item;
-
- TOKEN_ID
- token;
- fprintf(stdout, " %s = { n", name);
- item = heap->list;
- while(item != NULL)
- {
- token = item->token;
- if (get_token_type(heap, token) == T_IDENTIFIER)
- {
- if (get_token_indirect_type(heap, token) == TP_STRING)
- {
- fprintf(stdout, "%s = %sn",
- get_token_strvalue(heap, token),
- get_token_indirect_string(heap, token));
- }
- else
- if (get_token_indirect_type(heap, token) == TP_DICTIONARY)
- {
- dump_heap(get_token_indirect_dictionary(heap, token),
- get_token_strvalue(heap, token));
- }
- else
- if (get_token_indirect_type(heap, token) == TP_LIST)
- {
- dump_heap(get_token_indirect_list(heap, token),
- get_token_strvalue(heap, token));
- }
- }
- item = item->next;
- }
- fprintf(stdout, " }n");
- }
- /* -------------------------------------------------------------------- */
- /* -------------------------------------------------------------------- */
- void free_heap(TOKEN_HEAP *heap)
- {
- TOKEN_LIST
- *item,
- *prev_item;
-
- TOKEN_ID
- token;
- item = heap->list;
- while(item != NULL)
- {
- token = item->token;
- if (get_token_type(heap, token) == T_IDENTIFIER)
- {
- if (get_token_indirect_type(heap, token) == TP_DICTIONARY)
- {
- free_heap(get_token_indirect_dictionary(heap, token));
- }
- else
- if (get_token_indirect_type(heap, token) == TP_LIST)
- {
- free_heap(get_token_indirect_list(heap, token));
- }
- }
- prev_item = item;
- item = item->next;
- free(prev_item->token->str);
- free(prev_item->token);
- free(prev_item);
- }
- }