Beispiel #1
0
// 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);
  }
}
Beispiel #2
0
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;
  }
}
Beispiel #3
0
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);
    }
  }
}
Beispiel #4
0
/*
 * 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);
}
Beispiel #5
0
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;
}
Beispiel #6
0
/**********************************************************************************************************
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;
}
Beispiel #7
0
bool is_num(char const *str) {
  return char_class(str[0]) == CC_NUMERIC ||
    (str[0] == '-' && char_class(str[1]) == CC_NUMERIC);
}
Beispiel #8
0
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);
}