segmentation fault (core dumped) in Lex/Bison- related to yyparse()

316 Views Asked by At

I saw a lot of "segmentation fault (core dumped)" errors but I'm still struggling to figure this error in my code. After debugging with gdb it says the fault from the call to yyparse() in my main() function in my yacc file. I didn't get any warnings related to this case before the program running. I don't know what else I'm doing wrong and I hope you could help me.

This is my AST lexer file:

%{
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define YYDEBUG 0
void yyerror(const char *);
extern char* yytext;

%}

%%
[ ]+ {printf("SPACE: start%send\n", yytext);}

boolean {printf("BOOLEAN: %s\n", yytext);yylval =mknode(0,0,"BOOLEAN");return BOOLEAN;}
true {printf("TRUE: %s\n", yytext);yylval =mknode(0,0,"TRUE");return TRUE;}
false {printf("FALSE: %s\n", yytext);yylval =mknode(0,0,"FALSE");return FALSE;}
procedure {printf("FUNCTION: %s\n", yytext);yylval =mknode(0,0,"FUNCTION");return FUNCTION;}
float {printf("FLOAT: %s\n", yytext);yylval =mknode(0,0,"FLOAT");return FLOAT;}
char {printf("CHAR: %s\n", yytext);yylval =mknode(0,0,"CHAR");return CHAR;}
integer {printf("INT: %s\n", yytext);yylval =mknode(0,0,"INT");return INT;}
string {printf("STRING: %s\n", yytext);yylval =mknode(0,0,"STRING");return STRING;}
intptr {printf("INTPTR: %s\n", yytext);yylval =mknode(0,0,"INTPTR");return INTPTR;}
charptr {printf("CHARPTR: %s\n", yytext);yylval =mknode(0,0,"CHARPTR");return CHARPTR;}
if {printf("COND: %s\n", yytext);yylval =mknode(0,0,"COND");return COND;}
else {printf("BLOCK: %s\n", yytext);yylval =mknode(0,0,"BLOCK");return BLOCK;}
while {printf("WHILE_COND: %s\n", yytext);yylval =mknode(0,0,"WHILE_COND");return WHILE_COND;}
var {printf("VARIABLE: %s\n", yytext);yylval =mknode(0,0,"VARIABLE");return VARIABLE;}
return {printf("RETURN: %s\n", yytext);yylval =mknode(0,0,"RETURN");return RETURN;}
null {printf("NL: %s\n", yytext);yylval =mknode(0,0,"NL");return NL;}
intarray  {printf("KEY_INTARRAY: %s\n", yytext);yylval =mknode(0,0,"KEY_INTARRAY");return KEY_INTARRAY;}

\&\& {printf("AND: %s\n", yytext);yylval =mknode(0,0,"AND");return AND;}
\/ {printf("DIVISION_OP: %s\n", yytext);yylval =mknode(0,0,"DIVISION_OP");return DIVISION_OP;}
\/\%.*\%\/ {printf("COMMENT: %s\n", yytext);yylval =mknode(0,0,"COMMENT");return COMMENT;}
\= {printf("ASSIGN: %s\n", yytext);yylval =mknode(0,0,"ASSIGN");return ASSIGN;}
\=\= {printf("EQUAL: %s\n", yytext);yylval =mknode(0,0,"EQUAL");return EQUAL;}
\> {printf("BIGGER_THEN: %s\n", yytext);yylval =mknode(0,0,"BIGGER_THEN");return BIGGER_THEN;}
\>\= {printf("BIGGER_OR_EQUAL: %s\n", yytext);yylval =mknode(0,0,"BIGGER_OR_EQUAL");return BIGGER_OR_EQUAL;}
\< {printf("SMALLER_THEN: %s\n", yytext);yylval =mknode(0,0,"SMALLER_THEN");return SMALLER_THEN;}
\<\= {printf("SMALLER_OR_EQUAL: %s\n", yytext);yylval =mknode(0,0,"SMALLER_OR_EQUAL");return SMALLER_OR_EQUAL;}
\- {printf("MINUS: %s\n", yytext);yylval =mknode(0,0,"MINUS");return MINUS;}
\! {printf("LOGICAL_NOT: %s\n", yytext);yylval =mknode(0,0,"LOGICAL_NOT");return LOGICAL_NOT;}
\!\= {printf("NOT_EQUAL: %s\n", yytext);yylval =mknode(0,0,"NOT_EQUAL");return NOT_EQUAL;}
\|\| {printf("OR: %s\n", yytext);yylval =mknode(0,0,"OR");return OR;}
\| {printf("ABS: %s\n", yytext);yylval =mknode(0,0,"ABS");return ABS;}
\+ {printf("PLUS: %s\n", yytext);yylval =mknode(0,0,"PLUS");return PLUS;}
\* {printf("MUL: %s\n", yytext);yylval =mknode(0,0,"MUL");return MUL;}
\& {printf("ADDRESS_OF: %s\n", yytext);yylval =mknode(0,0,"ADDRESS_OF");return ADDRESS_OF;}
\^ {printf("DEREFERANCE: %s\n", yytext);yylval =mknode(0,0,"DEREFERANCE");return DEREFERANCE;}
\( {printf("L_BRACKET: %s\n", yytext);yylval =mknode(0,0,"L_BRACKET");return L_BRACKET;}
\) {printf("R_BRACKET: %s\n", yytext);yylval =mknode(0,0,"R_BRACKET");return R_BRACKET;}
\[ {printf("L_STRING_INDEX: %s\n", yytext);yylval =mknode(0,0,"L_STRING_INDEX");return L_STRING_INDEX;}
\] {printf("R_STRING_INDEX: %s\n", yytext);yylval =mknode(0,0,"R_STRING_INDEX");return R_STRING_INDEX;}
\; {printf("EOS: %s\n", yytext);yylval =mknode(0,0,"EOS");return EOS;}
\{ {printf("OB: %s\n", yytext);yylval =mknode(0,0,"OB");return OB;}
\} {printf("CB: %s\n", yytext);yylval =mknode(0,0,"CB");return CB;}
\, {printf("COMMA: %s\n", yytext);yylval =mknode(0,0,"COMMA");return COMMA;}
\: {printf("VAR_DEC: %s\n", yytext);yylval =mknode(0,0,"VAR_DEC");return VAR_DEC;}
\_ {printf("UNDERSCORE: %s\n", yytext);yylval =mknode(0,0,"UNDERSCORE");return UNDERSCORE;}
\|[\-]*[0-9]+\| {printf("ABSULUTE_VALUE_OF_INT: %s\n", yytext);yylval =mknode(0,0,"ABSULUTE_VALUE_OF_INT");return ABSULUTE_VALUE_OF_INT;}
\|[a-zA-Z0-9]+\| {printf("DECLARED_LENGTH_OF_STRING: %s\n", yytext);yylval =mknode(0,0,"DECLARED_LENGTH_OF_STRING");return DECLARED_LENGTH_OF_STRING;}

[a-zA-Z]+[_]*[a-zA-Z0-9]* {printf("IDENTIFIER: %s\n", yytext);yylval =mknode(0,0,"IDENTIFIER");return IDENTIFIER;}
[\"][a-zA-Z0-9]+[\"] {printf("STRING_TYPE: %s\n", yytext);yylval =mknode(0,0,"STRING_TYPE");return STRING_TYPE;}
[\'].[\'] {printf("CHAR_TYPE: %s\n", yytext);yylval =mknode(0,0,"CHAR_TYPE");return CHAR_TYPE;}
[0-9]+[\.][0-9]+ {printf("FLOAT_CONST: %s\n", yytext);yylval =mknode(0,0,"FLOAT_CONST");return FLOAT_CONST;}
[\-][0-9]+[\.][0-9]+ {printf("FLOAT_CONST: %s\n", yytext);yylval =mknode(0,0,"FLOAT_CONST");return FLOAT_CONST;}
0|[1-9]+[0-9]* {printf("INTEGER_CONST: %s\n", yytext);yylval =mknode(0,0,"INTEGER_CONST");return INTEGER_CONST;}
[\-][1-9]+[0-9]* {printf("INTEGER_CONST: %s\n", yytext);yylval =mknode(0,0,"INTEGER_CONST");return INTEGER_CONST;}
0[x|X][0-9]+[a-fA-F0-9]*[a-fA-F0-9]* {printf("HEX_NUMBER: %s\n", yytext);yylval =mknode(0,0,"HEX_NUMBER");return HEX_NUMBER;}
[0][^xX][1-7]+[0-7]* {printf("OCTAL_NUMBER: %s\n", yytext);yylval =mknode(0,0,"OCTAL_NUMBER");return OCTAL_NUMBER;}
[0|1]+[b] {printf("BINARY_NUMBER: %s\n", yytext);yylval =mknode(0,0,"BINARY_NUMBER");return BINARY_NUMBER;}


\^\^ {printf("SYNTAX_ERROR: %s\n", yytext);yylval =mknode(0,0,"SYNTAX_ERROR");return SYNTAX_ERROR;}
[\']..+[\'] {printf("SYNTAX_ERROR: %s\n", yytext);yylval =mknode(0,0,"SYNTAX_ERROR");return SYNTAX_ERROR;}
\&[0-9]* {printf("LINKER_ERROR: %s\n", yytext);yylval =mknode(0,0,"LINKER_ERROR");return LINKER_ERROR;}
\&[a-zA-Z]+[\+|\-|\*|\/][a-zA-Z]+ {printf("LINKER_ERROR: %s\n", yytext);yylval =mknode(0,0,"LINKER_ERROR");return LINKER_ERROR;}
\&[^[[\"][a-zA-Z0-9]+[\"]\[0-9]+\]]] {printf("LINKER_ERROR: %s\n", yytext);yylval =mknode(0,0,"LINKER_ERROR");return LINKER_ERROR;}

[a-zA-Z]+[=][a-zA-Z]+[=] {printf("SYNTAX_ERROR: %s\n", yytext);yylval =mknode(0,0,"SYNTAX_ERROR");return SYNTAX_ERROR;}
\"\m\a\i\n\(\)\" {printf("CASE_SENSETIVE_ERROR: %s\n", yytext);yylval =mknode(0,0,"CASE_SENSETIVE_ERROR");return CASE_SENSETIVE_ERROR;}
%%

int yywrap(void) {
    return 1;
}

This is my AST yacc file:

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int yylex(void);
void yyerror(const char *);

typedef struct node{
        char *token;
    //int line_number;
        struct node *left;
        struct node *right;
} node;

#define YYSTYPE struct node *

node *mknode(node *left, node *right, char *token);
void printtree(node *tree);

%}

%error-verbose

%start program

%token BOOLEAN TRUE FALSE FUNCTION FLOAT CHAR INT STRING INTPTR CHARPTR DECL
%token L_BRACKET COND WHILE_COND BLOCK VARIABLE RETURN OB CB EOS FUNC_DECL_ERROR
%token AND DIVISION_OP COMMENT ASSIGN EQUAL BIGGER_THEN BIGGER_OR_EQUAL DECL_ERROR
%token SMALLER_THEN SMALLER_OR_EQUAL MINUS LOGICAL_NOT NOT_EQUAL OR PLUS DECL_LIST
%token ADDRESS_OF SEMANTIC_ERROR DEREFERANCE SYNTAX_ERROR PARAMETER_LIST KEY_INTARRAY
%token R_BRACKET L_STRING_INDEX R_STRING_INDEX COMMA VAR_DEC NL TYPE_MISMATCH_ERROR
%token UNDERSCORE ABSULUTE_VALUE_OF_INT DECLARED_LENGTH_OF_STRING IDENTIFIER
%token STRING_TYPE CHAR_TYPE FLOAT_CONST INTEGER_CONST HEX_NUMBER OCTAL_NUMBER
%token BINARY_NUMBER CASE_SENSETIVE_ERROR LINKER_ERROR RETURN_ERROR ABS

%left OR
%left AND
%left EQUAL NOT_EQUAL
%left BIGGER_THEN BIGGER_OR_EQUAL SMALLER_THEN SMALLER_OR_EQUAL
%left PLUS MINUS
%left MUL DIVISION_OP

%right ASSIGN
%right LOGICAL_NOT 

%nonassoc BLOCK

%%

program : functions { printtree($1); }
        ;

functions : functions function { $$=mknode($1,$2,"");}
        | /*none*/ { $$=0; }
        ;

function   : FUNCTION IDENTIFIER L_BRACKET f_params R_BRACKET RETURN type OB body CB
               {$1->left=$2; $1->right=$9; $$=$1; }
           ;

body       : var_decls func_decls stmts ret_stmt  
              {$1->left=$2; $1->right=$3; $3->left=$4; $$=$1;}
           ;

nest_block : stmts { $$ = $1; }
       ;

f_params   : f_params_  { $$ = $1; }
           |  /*none*/ { $$=0; }
           ;

f_params_  : param { $$ = $1; }
           ;

param      :  IDENTIFIER COMMA f_params_ { $1->left=$3; $$=$1; } | IDENTIFIER VAR_DEC type { $1->left=$3; $$=$1; } 
           ;

var_decls  : var_decls var_decl {$1->left=$2; $$ = $1;}
           | /*none*/ { $$=0; }
           ;

var_decl   : VARIABLE var_list VAR_DEC atype EOS {$1->left=$2; $1->right=$4; $$=$1;}
           ;

var_list   : var_list COMMA IDENTIFIER {$1->left=$3; $$=$1;}
           | IDENTIFIER {$$=$1;}
           ;

type       : BOOLEAN {$$=$1;}
           | INT {$$=$1;}
           ;

atype      : type {$$ = $1;}
           | KEY_INTARRAY L_STRING_INDEX integer R_STRING_INDEX {$$=$3;}
           ;

func_decls : func_decls function {$1->left=$2; $$ = $1;}
           | /*none*/ { $$=0; }
           ;

stmts      : stmts stmt {$1->left=$2; $$ = $1;}
           | /*none*/ { $$=0; }
           ;

stmt       : assignment {$$ = $1;}
           | fct_call {$$ = $1;}
           | COND L_BRACKET expr R_BRACKET OB nest_block CB {$$=mknode($3,$6,"");}
           | COND L_BRACKET expr R_BRACKET OB nest_block CB BLOCK OB nest_block CB      
                                    {$5->left=$1; $5->right=$6; $1->left=$2; $2->left=$3;$2->right=$4; $6->left=$7; $$=$1;}
           ;

opt_assign : assignment {$$ = $1;}
           | /*none*/ { $$=0; }
           ;

ret_stmt   : RETURN expr EOS {$$=$2; }
           ;

assignment : IDENTIFIER ASSIGN expr EOS { $2->left=$1; $2->right=$3; $$=$2;/*$$=mknode($1,$3,"");*/}
       | IDENTIFIER L_STRING_INDEX expr R_STRING_INDEX ASSIGN expr EOS {$1->left=$2; $1->right=$3; $3->left=$4; $3->right=$5; $5->left=$6; $5->right=$7; $$=$1;}
           ;

fct_call   : IDENTIFIER ASSIGN IDENTIFIER L_BRACKET expr_list R_BRACKET EOS     
                {$2->left=$1; $2->left=$3; $$=mknode($2,$5,"");}
       | IDENTIFIER L_STRING_INDEX expr R_STRING_INDEX ASSIGN IDENTIFIER L_BRACKET expr_list R_BRACKET EOS
                {$2->left=$1; $2->right=$3; $4->left=$6; $4->right=$8; $$=mknode($2,$4,"");}
           ;

expr_list  : expr_list_ expr { $1->left=$2; $$ = $1; }
       | /*none*/ { $$=0; }
       ;

expr_list_ : expr_list_ expr COMMA  { $1->left=$2; $$ = $1; }
       | /*none*/ { $$=0; }
       ;

expr       : expr PLUS expr  {$$=mknode($1,$3,"+");}
           | expr MINUS expr {$$=mknode($1,$3,"-");}
           | expr MUL expr  {$$=mknode($1,$3,"*");}
           | expr DIVISION_OP expr   {$$=mknode($1,$3,"/");}
           | expr AND expr {$$=mknode($1,$3,"||");}
           | expr OR expr  {$$=mknode($1,$3,"+");}
           | expr NOT_EQUAL expr  {$$=mknode($1,$3,"!=");}
           | expr EQUAL expr  {$$=mknode($1,$3,"==");}
           | expr BIGGER_OR_EQUAL expr {$$=mknode($1,$3,">=");}
           | expr BIGGER_THEN expr {$$=mknode($1,$3,">");}
           | expr SMALLER_THEN expr {$$=mknode($1,$3,"<");}
           | expr SMALLER_OR_EQUAL expr {$$=mknode($1,$3,"<=");}
           | LOGICAL_NOT expr {$$=$2;}
           | MINUS expr  {$$=$2;} %prec LOGICAL_NOT
           | literal {$$ = $1;}
           | IDENTIFIER {$$ = $1;}
           | IDENTIFIER L_STRING_INDEX expr R_STRING_INDEX {$$=mknode($1,$3,"");}
           | L_BRACKET expr R_BRACKET {$$ = $2;}
           | ABS expr ABS { $$=$2; }
           ;

literal    : integer {$$=$1;}
           | TRUE    {$$=$1;}
           | FALSE   {$$=$1;}
           ;

integer    : INTEGER_CONST {$$=$1;}
           | HEX_NUMBER  {$$=$1;}
           | BINARY_NUMBER  {$$=$1;}
           | OCTAL_NUMBER {$$=$1;}
           ;

%%
#include "lex.yy.c"

int main (void) {yyparse(); return 0;}

node *mknode(node *left, node *right, char *token)
{

 node *newnode = (node *)malloc(sizeof(node));
 char *newstr = (char *)malloc(sizeof(token)+1);
 strcpy(newstr,token);
 newnode->left = left;    
 newnode->right = right;
 newnode->token = newstr;
 return newnode;
}

void printtree(node *tree){

  if(!tree)
    return;

  if (tree->left || tree->right)
    printf("(");

  printf(" %s ", tree->token);

  if (tree->left)
    printtree(tree->left);
  if (tree->right)
    printtree(tree->right);

  if (tree->left || tree->right)
    printf(")");
}

extern int yylineno;

void yyerror(const char *s) {
    fprintf(stderr, "line %d: %s\n", yylineno, s);
}

NOTICE that the error appears just after the program traverse all the right grammar. Then I need to print the tree in preorder (That is the printtree function) but it seems like crush before it.

Thanks in advance for any help.

0

There are 0 best solutions below