:: Re: [DNG] Studying C as told. (For …
Etusivu
Poista viesti
Vastaa
Lähettäjä: Edward Bartolo
Päiväys:  
Vastaanottaja: dng
Aihe: Re: [DNG] Studying C as told. (For help)
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]
>