cparsingbisonlex

AST creation segfaults when input string input is larger than 9


Test Ouputs:

./parse -r
/[123456]/
Accepted!
./parse -r
/[1234567]/
zsh: segmentation fault (core dumped)  ./parse -r

This is my flex rule for the token. \[^?([^\\\]]|\\.)*\] {yylval.value = strdup(yytext); return TOKEN_RANGE; }

Which, gets passed to bison that passes it to add to the AST. range: TOKEN_RANGE {$$ = CreateAstLeaf(RANGE,$1);};

Below are the functions that create the AST.

ast_t *CreateAstNode(node_t type, ast_t *node_l, ast_t *node_r) {
  ast_t *new_node = malloc(sizeof(ast_t));
  if (!new_node) {
    perror("Out of space.");
    exit(1);
  }

  new_node->type = type;
  new_node->node_l = node_l;
  new_node->node_r = node_r;
  return new_node;
}

ast_t *CreateAstLeaf(node_t type, char *val) {
  ast_t *new_leaf = malloc(sizeof(ast_t));
  if (!new_leaf) {
    perror("Out of space.");
    exit(1);
  }

  if (val == NULL) {
    printf("No string recieved.\n");
    exit(1);
  }

  new_leaf->type = type;
  new_leaf->value = calloc(strlen(val) + 1, sizeof(char));
  strcpy(new_leaf->value, val);
  // printf("CREATNG:\tTYPE:%2d | VALUE: %5s\n", new_leaf->type,
  // new_leaf->value);

  return new_leaf;
}

I have already tested the tree creation and traversal and works correctly, but this only happened as I started creating the AST. As a string such as this /"this is a literal"/ got parsed correctly. I believe there is some confusion as to how yytext is used on my part.


Solution

  • Found the error, was treating all nodes the same even though the struct has an enum.

    typedef struct ast {
      node_t type;
      union {
        struct {
          struct ast *node_l;
          struct ast *node_r;
        };
        char *value;
      };
    } ast_t;
    
    

    So,when the eval function reached a leaf node it was trying to access a string rather than a pointer to another node. Fix it by handling the eval function better.