// starts at comment const char *skip_comment(const char *s, const char *e) { int level = 0; char_class_t before = CC_NONE; const char *ptr = s; for(;;) { // move cursor past comment character, and record character class after it ptr++; if(ptr >= e) return e; char_class_t after; unsigned int length = 1; while((after = char_class(*ptr)) == CC_COMMENT) { length++; ptr++; if(ptr >= e) return e; } if(before == CC_NONE) { if(after != CC_NONE) { level++; } else if(level == 0) { if(length > 1) { // line comment while(ptr < e && *ptr && *ptr != '\n') ptr++; return ptr; } else { // just a lone comment char return s; } } } else if(after == CC_NONE) { level--; if(ptr >= e || !*ptr || level <= 0) return ptr; } // move cursor to next comment character, tracking character class before it ptr++; char_class_t cur = after; do { before = cur; ptr++; if(ptr >= e || !*ptr) return ptr; cur = char_class(*ptr); } while(cur != CC_COMMENT); } }
bool match_param_word(const char *pre, seg_t seg, csize_t *in, csize_t *out) { const char *end = seg_end(seg); const char *s = seg.s; while(*pre) { if(s >= end || *pre != *s) return false; s++; pre++; } switch(end - s) { case 2: if(char_class(s[1]) != CC_NUMERIC) return false; *out = s[1] - '0'; case 1: if(char_class(s[0]) != CC_NUMERIC) return false; *in = s[0] - '0'; case 0: return true; default: return false; } }
void mark_comments(char c, char *str) { char *ptr = str; char *e = str + strlen(str); while(*ptr) { char_class_t cc = char_class(*ptr); switch(cc) { case CC_NONE: ptr++; break; case CC_COMMENT: { char *start = ptr; ptr = (char *)skip_comment(ptr, e); if(ptr == start) { ptr++; } else { memset(start, c, ptr - start); } break; } default: while(char_class(*++ptr) != CC_NONE); } } }
/* * Remove trailing \r and \n chars and ensure * null termination. */ void buf_chomp (struct buffer *buf) { while (true) { char *last = (char *) BLAST (buf); if (!last) break; if (char_class (*last, CC_CRLF|CC_NULL)) { if (!buf_inc_len (buf, -1)) break; } else break; } buf_null_terminate (buf); }
int get_next_state(int state, char c, int *accept) { int col; int next; col = char_class(c); next = st_table[state][col]; #ifdef DEBUG printf("Input symbol: %c Row: %d Column: %d Next: %d \n",c,state,col,next); #endif /* The assert(int test) macro can be used to add run-time diagnostic to programs and to "defend" from producing unexpected results. assert() is a macro that expands to an if statement; if test evaluates to false (zero) , assert aborts the program (by calling abort()) and sends the following message on stderr: Assertion failed: test, file filename, line linenum The filename and linenum listed in the message are the source file name and line number where the assert macro appears. If you place the #define NDEBUG directive ("no debugging") in the source code before the #include <assert.h> directive, the effect is to comment out the assert statement. */ assert(next != IS); /* The other way to include diagnostics in a program is to use conditional preprocessing as shown bellow. It allows the programmer to send more details describing the run-time problem. Once the program is tested thoroughly #define DEBUG is commented out or #undef DEBUF is used - see the top of the file. */ #ifdef DEBUG if(next == IS){ printf("Scanner Error: Illegal state:\n"); printf("Input symbol: %c Row: %d Column: %d\n",c,state,col); exit(1); } #endif *accept = as_table[next]; return next; }
/********************************************************************************************************** Purpose: Gets the next state in the transition table Author: Svillen Ranev History/Versions: 1.0.0.0 Called functions: char_class() Parameters: int state, char c, int *accept Return value: int representing the next row(state) in the transition table **********************************************************************************************************/ int get_next_state(int state, char c, int *accept) { int col; int next; col = char_class(c); next = st_table[state][col]; #ifdef DEBUG printf("Input symbol: %c Row: %d Column: %d Next: %d \n",c,state,col,next); #endif assert(next != IS); #ifdef DEBUG if(next == IS){ printf("Scanner Error: Illegal state:\n"); printf("Input symbol: %c Row: %d Column: %d\n",c,state,col); exit(1); } #endif *accept = as_table[next]; return next; }
bool is_num(char const *str) { return char_class(str[0]) == CC_NUMERIC || (str[0] == '-' && char_class(str[1]) == CC_NUMERIC); }
static inline bool char_inc_exc (const char c, const unsigned int inclusive, const unsigned int exclusive) { return char_class (c, inclusive) && !char_class (c, exclusive); }