/* Lexical analyzer. */ #include #include #include #include #define __LEXER__ #include "lexer.h" FILE *istr; #define EOFch '\0' #define TOKLEN 1024 char linebuf[TOKLEN], *line; char token[TOKLEN]; char lexerror[TOKLEN]; int len; int pos; int linenum; void lexer_init(FILE * f) { istr = f; line = NULL; linenum = 0; lexer_readToken(); } static char * lexer_error(char *s, char *v) { if (v == NULL) v = tok; sprintf(lexerror, "Line %d: %s ('%s')\n", linenum, s, v); return lexerror; } void lexer_readALine() { int i; if (line = fgets(linebuf, 1024, istr)) { pos = 0; linenum++; } } char lexer_readChar() { if (line == NULL || pos >= strlen(line)) { lexer_readALine(); pos = 0; } if (line == NULL) return EOFch; return line[pos++]; } void lexer_unreadChar() { pos--; } int lexer_isSpace(char c) { return (c == ' ' || c == '\t'); } int lexer_isTokenChar(char c) { return (c == ',' || c == ';' || c == '\n' || c == '\r' || c == '[' || c == ']' || c == '#' || c == '='); } void lexer_readAToken() { char c; int string = 0; len = 0; do { c = lexer_readChar(); } while (c != EOFch && lexer_isSpace(c)); if (c != EOFch && c == '\"') { string = 1; c = lexer_readChar(); } while (c != EOFch && (string ? c != '\"' : !lexer_isSpace(c))) { if (!string && lexer_isTokenChar(c)) { if (len == 0) token[len++] = c; else lexer_unreadChar(); token[len] = 0; tok = token; return; } else { token[len++] = c; c = lexer_readChar(); } } if (c == EOFch) if (len == 0) { token[0] = 0; tok = token; return; } else if (len == 1 && lexer_isTokenChar(token[0])) { token[len] = 0; tok = token; return; } else; else if (!string) lexer_unreadChar(); tok = token; token[len] = 0; } void lexer_readToken() { while (tok == NULL) { lexer_readAToken(); } } void lexer_consumeToken() { if (tok == NULL) { lexer_readToken(); if (tok == NULL) logger(LOG_COMMANDS | LOG_FATAL, (lexer_error("Reached premature end-of-file", NULL)); } else lexer_readToken(); tok = NULL; lexer_readToken(); } int lexer_compareToken(char *t) { lexer_readToken(); if (strcmp(t, tok) == 0) { lexer_consumeToken(); lexer_readToken(); return 1;} else return 0;} void lexer_matchToken(char *t, char *s) { if (!lexer_compareToken(t)) logger(LOG_FATAL | LOG_COMMANDS, (lexer_error(s, tok));}