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]
>