Reputation: 41
I am trying to build a parser for arithmetic expression using yacc. I have also included some semantic actions with it. But whenever I run the code it shows segmentation fault(core dumped). Please Help. This is my yacc file.
%{
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int yylex();
void yyerror(const char *s);
int temp[100];
char var[2]="t0";
char label[2]="L1";
%}
%union
{
struct attributes
{
char code[100];
char addr[100];
char op[2];
}type_id;
char ch;
}
%start L
%token ID NUM WHILE OR AND NOT True False Do end GE LE EE NE UMINUS
%right '='
%left AND OR
%left '<' '>' LE GE NE
%left '+''-'
%left '*''/'
%right UMINUS
%left '!'
%type<type_id>L
%type<type_id>E
%type<ch>ID
%type<ch>NUM
%%
%%
#include "lex.yy.c"
int main()
{
printf("Enter the exp: ");
yyparse();
}
This is my Lex file.
alpha [A-Za-z]
digit [0-9]
%%
[ \t\n]
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
. return yytext[0];
%%
When I compile my file I get this:
rome@rome-VirtualBox:~/Desktop/CompDesin$ gcc y.tab.c -ll -ly
test.y: In function ‘yyparse’:
test.y:48:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:49:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:50:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:50:36: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
strcat(temp,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:51:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"=");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:52:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:53:52: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
strcpy($$.code,temp);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:60:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:61:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:62:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:63:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:64:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$$.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:65:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"=");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:66:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:67:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"+");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:68:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:69:53: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
strcpy($$.code,temp);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:74:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy($$.addr,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:78:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy($$.addr,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
rome@rome-VirtualBox:~/Desktop/CompDesin$ gcc y.tab.c -ll -ly
test.y: In function ‘yyparse’:
test.y:48:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:49:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:50:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:50:36: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Wint-conversion]
strcat(temp,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:51:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"=");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:52:31: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:53:52: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
strcpy($$.code,temp);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:60:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:61:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:62:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.code);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:63:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"\n");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:64:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$$.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:65:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"=");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:66:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$1.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:67:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,"+");
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:68:32: warning: passing argument 1 of ‘strcat’ from incompatible pointer type [-Wincompatible-pointer-types]
strcat(temp,$3.addr);
^~~~
In file included from test.y:4:0:
/usr/include/string.h:129:14: note: expected ‘char * restrict’ but argument is of type ‘int *’
extern char *strcat (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:69:53: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
strcpy($$.code,temp);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:74:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy($$.addr,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
test.y:78:53: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy($$.addr,$1);
^
In file included from test.y:4:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^~~~~~
And when I run my file i get this error:
rome@rome-VirtualBox:~/Desktop/CompDesin$ ./a.out
Enter the exp: a=b+c
Segmentation fault (core dumped)
Upvotes: 1
Views: 190
Reputation: 27126
There are multiple problems:
Two notes:
keep in mind, that strings in C are terminated with a NUL byte and therefore the character arrays need to be dimensioned accordingly
for some of them the compiler warns you, it is a good idea to pay attention to the compiler warnings
Let's go through the different issues quickly:
Like Paul R and bruno noted correctly temp should be char array and the dimensions of var and label arrays are too small
then it still crashes, because ID and NUM are
defined as
%type<ch>ID
%type<ch>NUM
and ch is:
char ch;
in the %union statement.
The crashes occur because you define strcat(temp,$1);
on line 50. $1 represents a single character, but your code tries to interpret this as a NUL-terminated string (char * pointer). You have similar cases on lines 74 and 78 with strcpy($$.addr,$1);
. As mentioned earlier, the compiler warns you about this. This provokes undefined behavior, which in your case manifests itself in a segmentation error.
You could correct this e.g. to strncat(temp,&$1,1);
to use only one character but in comments you write that your number of characters to be copied will differ and will depend on the input.
Therefore change the definition perhaps in %union to something like:
char strval[100];
Then adapt:
%type<strval>ID
%type<strval>NUM
Set the values in the scanner
It would no longer crash now, but it would not work as intended because the values are not set in the scanner. There only the type (ID or NUM) is determined, but the associated value is not set.
There it should look like:
{digit}+ {
strcpy(yylval.strval, yytext);
return NUM;
}
{alpha}({alpha}|{digit})* {
strcpy(yylval.strval, yytext);
return ID;
}
Scanner
You are currently including the "lex.yy.c" file in the .y file, like so:
#include "lex.yy.c"
I would rather do it the other way around. Remove it from there and instead make an include of the yacc generated "y.tab.h" in the .l file. So the beginning of the .l file could look like this:
%{
#include "y.tab.h"
%}
alpha [A-Za-z]
...
The commands for building would be (might differ a little bit on your platform):
flex scanner.l
yacc -d grammar.y
cc -Wall -Wextra y.tab.c lex.yy.c -ll
Finally, an input like
a=bb+c+4711
would produce an output like:
t0=bb+c
t1=t0+4711
Further possible improvements
Once this works as desired, you can either think about dynamically allocating memory for values, as recommended by rici in the comments section, or limit the length of values to ensure that they are not written beyond the end of fixed-size buffers.
Upvotes: 2