/* (C) Copyright 2008 Nick Mudge * This code can be freely copied and modified. */ #include "symbol_table.c" #include /* Chars */ #define ALPHA 0 #define DIGIT 1 #define WHITE_SPACE 3 #define ERROR_CHAR 127 /* Tokens */ #define IDENTIFIER 1 #define NUM 2 #define KEYWORD 3 #define TOKEN_END 126 #define ERROR_TOKEN 127 #define INITIALIZE_TABLE(table, function) if(table[0] == 0) function(table) /* variable: a(ad)* a = a-z, A-Z, _ d = 0-9 operators: + - * / = numbers: 0-9 */ typedef struct token { char value; Entry *symbol_entry; } Token; extern char *input; extern char *input_beginning; extern Token token; extern Token look_ahead_token; Symbol_table *symbol_table; Token return_token(void); void initialize_char_set(char char_set[]) { int i; for(i = 0; i < 127; i++) { if((i > 64 && i < 91) || (i > 96 && i < 123)) char_set[i] = ALPHA; else if (i > 47 && i < 58) char_set[i] = DIGIT; else if (i == ' ' || i == '\t' || i == '\n') char_set[i] = WHITE_SPACE; else char_set[i] = ERROR_CHAR; } } void la(void) { if(token.value == 0 && token.symbol_entry == NULL) { token = return_token(); look_ahead_token = return_token(); } else { token = look_ahead_token; look_ahead_token = return_token(); } } Token return_token(void) { static char char_set[128]; int state; char *lexeme_end; char *possible_identifier_beginning; char string_symbol_table_buffer; Token token; state = 0; possible_identifier_beginning = NULL; INITIALIZE_TABLE(char_set, initialize_char_set); if(input < input_beginning) { token.symbol_entry = NULL; token.value = TOKEN_END; return token; } for(; input >= input_beginning; input--) { if(state == 0 && char_set[(int)*input] == WHITE_SPACE) { continue; } if(state == 0 && (char_set[(int)*input] == ALPHA || char_set[(int)*input] == DIGIT)) { lexeme_end = input + 1; string_symbol_table_buffer = *lexeme_end; state = 1; } if(state == 2 || char_set[(int)*input] == ALPHA) { if(possible_identifier_beginning == NULL) { possible_identifier_beginning = input; state = 2; } if(input-1 < input_beginning || (char_set[(int)*(input-1)] != ALPHA && char_set[(int)*(input-1)] != DIGIT)) { if(char_set[(int)*input] == DIGIT) input = possible_identifier_beginning; *lexeme_end = '\0'; token.symbol_entry = add_to_symbol_table(input); *lexeme_end = string_symbol_table_buffer; if(token.symbol_entry->keyword == TRUE) token.value = KEYWORD; else token.value = IDENTIFIER; input--; return token; } } else if(char_set[(int)*input] == DIGIT) { if(input-1