Hi, further debugging (gdb) uncovered two little coding errors (bugs).
The following is the corrected code.
-------------------
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#define token_delta 50
typedef char* pchar;
pchar* tokens;
int token_count = 0;
void tokenise(char* expression) {
  char ch;              /* character at iterator's position */
  char* atoken;         /* token to be added to token list  */
  char* start = NULL;   /* holds a char* to point to start of
multicharacter token */
  char* string_token;   /* holds multicharacter token */
  int char_count = 0;   /* keeps track of number of characters in
multicharacter token */
  int while_counter = 0;
  /* expr_len_and_null holds the total length of input string
including null terminator */
  int expr_len_and_null = strlen(expression) + 1;
  while (while_counter++ <= expr_len_and_null) {
    ch = *expression++;
    switch (ch) {
      case '(':
      case ')':
      case '^':
      case 'v':
      case '!':
      case '\0':
        if (start && char_count > 0) {
          string_token = malloc((char_count + 1)*sizeof(char));
          strncpy(string_token, start, char_count);
          tokens[token_count++] = string_token;
          start = NULL;
          char_count = 0;
        }
        if (ch == '\0') return;
        atoken = malloc(2*sizeof(char));
        atoken[0] = ch;
        atoken[1] = '\0';
        tokens[token_count++] = atoken;
        break;
      case '\n':
        break;
      default:
        if (start == NULL)
          start = expression - 1;
        char_count++;
    }
  }
}
void free_memory() {
  int k = token_count;
  while (--k >= 0) free(tokens[k]);
  free(tokens);
}
int main() {
  char input[101];
  tokens = malloc(token_delta*sizeof(char*));
  fgets(input, 100, stdin);
  tokenise(input);
  int k = -1;
  printf("token count is %d\n", token_count);
  while(++k < token_count)
    printf("%s\n", tokens[k]);
  free_memory();
  return 0;
}
On 05/07/2016, Edward Bartolo <edbarx@???> wrote:
> Hi,
>
> To improve my coding proficiency I am coding a simple parser for
> expressions like (Av!B)^(DvE). The parser's aim is to detect syntax
> errors in the expression.
>
> I have just completed the tokeniser. The main function calls the
> tokeniser and then lists the tokens for feedback. I have yet to code
> the parser which will use function recursion to do its syntax
> checking.
>
> This code is tested to work although it is still not protected against
> segmentation faults when the token number exceeds token_delta.
> Malloc's return value is not tested for validity. To improve the
> code's reliability both these situations have to be coded to make the
> program gracefully exit reporting an error to the user.
>
> [code]#include <stdio.h>
> #include <ctype.h>
> #include <stdlib.h>
> #include <string.h>
>
> #define token_delta 50
>
> typedef char* pchar;
> pchar* tokens;
> int token_count = 0;
>
> void tokenise(char* expression) {
>   char ch;              /* character at iterator's position */
>   char* atoken;         /* token to be added to token list  */
>   char* start = NULL;   /* holds a char* to point to start of
> multicharacter token */
>   char* string_token;   /* holds multicharacter token */
>   int char_count = 0;   /* keeps track of number of characters in
> multicharacter token */
>
>   int while_counter = 0;
>   /* expr_len_and_null holds the total length of input string
> including null terminator */
>   int expr_len_and_null = strlen(expression) + 1;
>   while (while_counter++ <= expr_len_and_null) {
>     ch = *expression++;
>     switch (ch) {
>       case '(':
>       case ')':
>       case '^':
>       case 'v':
>       case '!':
>       case '\0':
>         if (start && char_count > 0) {
>           string_token = malloc((char_count + 1)*sizeof(char));
>           strncpy(string_token, start, char_count);
>           tokens[token_count++] = string_token;
>           if (ch == '\0') return;
>
>           start = NULL;
>           char_count = 0;
>         }
>
>         atoken = malloc(2*sizeof(char));
>         atoken[0] = ch;
>         atoken[1] = '\0';
>         tokens[token_count++] = atoken;
>         break;
>
>       default:
>         if (start == NULL)
>           start = expression - 1;
>         char_count++;
>     }
>   }
> }
>
> void free_memory() {
>   int k = token_count;
>
>   while (--k >= 0) free(tokens[k]);
>   free(tokens);
> }
>
>
> int main() {
>   char input[101];
>
>   tokens = malloc(token_delta*sizeof(char*));
>   fgets(input, 100, stdin);
>   tokenise(input);
>
>   int k = -1;
>   printf("token count is %d\n", token_count);
>   while(++k < token_count)
>     if (k < token_count - 1)
>       printf("%s\n", tokens[k]);
>       else printf("%s", tokens[k]);
>
>   free_memory();
>
>   return 0;
> }[/code]
>