Iam trying to compile a file of the following format by making a parser in bison
LOCATION house
NAME "House"
DESCRIPTION "You are standing\nin front of your house.\nPaths lead towards east and west."
east flag
west forest
LOCATION obelisk
NAME "Obelisk"
DESCRIPTION "A big obelisk is\nstanding before you. You can either go east or west or south."
south flag
east flag
west treasure
My parser has a function
int find(char *id) {
int i;
for(i=0;i<nLoc;i++) {
if(strcmp(id,tmp_idList[i]) == 0){
printf(tmp_idList[0]);
printf(" i = %d returned",i);
return i;
}
}
printf("Copying...");
strcpy(tmp_idList[nLoc],id);
printf("%d %s",nLoc,tmp_idList[nLoc]);
nLoc++;
printf(" nloc-1 = %d returned",nLoc-1);
return (nLoc-1);
}
It uses
char tmp_idList[60][100];
Grammar is (relevant here )
locnSpec : tok_LOCN tok_IDENT nameSpec descrSpec exitList
{int k = find($2);
locList[k].name = strdup(tmp_name);
locList[k].descr = strdup(tmp_descr);
memcpy(locList[k].exits,
tmp_exit,
4*sizeof(int));}
Now when i run this code, somehow
tmpidList[0]
is getting populated with a junk value as shown below in the output
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\MY PC\Desktop\final>bison -d -o compile.c adv6.y
C:\Users\MY PC\Desktop\final>gcc -o compile compile.c lex.yy.c
C:\Users\MY PC\Desktop\final>compile<toy.al
Copying...0 flag nloc-1 = 0 returned
Copying...1 forest nloc-1 = 1 returned
Copying...2 house nloc-1 = 2 returned
flag i = 0 returned // OK HERE
flag i = 0 returned
Copying...3 treasure nloc-1 = 3 returned
Copying...4 obelisk nloc-1 = 4 returned
Copying...5 marsh nloc-1 = 5 returned
nd west. i = 4 returned // JUNK HERE
Copying...6 flag nloc-1 = 6 returned
nd west. i = 1 returned
nd west. i = 3 returned
t. i = 4 returned
t. i = 2 returned
t. i = 4 returned
t. i = 6 returned
t. i = 5 returned
t. i = 2 returned
t. i = 3 returned
t. i = 1 returned t. i = 2 returned
C:\Users\MY PC\Desktop\final>
As a cue when i tried allocating memory via malloc
char* tmp_idList[20]
...
tmp_idList[nLoc] = malloc(strlen(id) +1 )
it worked fine till flag was there in tmp_idList[0] but stopped working and there was a memory error in compile.exe.
does anyone has clue on what is happening? if you want more information , i can provide. i really need help for my college project.
One note. Your
findfunction might be calledintern. What it does is reduce a string token to a numeric atom. If it has not seen the string before, it returns a new atom, but it if it is called twice with the same string, it returns the same atom each time. This is called interning which originated in the Lisp language.You have some issues in that code since your symbols have space for 100 character names, but you are not checking this, and just using blind strcpy.
Now about this grammar rule:
locnSpec : tok_LOCN tok_IDENT nameSpec descrSpec exitList
{int k = find($2);
locList[k].name = strdup(tmp_name);
locList[k].descr = strdup(tmp_descr);
memcpy(locList[k].exits,
tmp_exit,
4*sizeof(int));}
What if a location spec occurs twice for the same location? You just leak this memory by overwriting
locList[k].name. You might want to free the old value that was there before. If these structures are initialized to null/zeros, you can do this:free(locList[k].name);
locList[k].name = strdup(tmp_name);
Secondly, where do these
tmp_nameandtmp_descrvariables come from? Are these globals that were stuffed with values during the reduction of thenamesSpecanddescrSpecnonterminal symbols?That’s a nasty approach; you really should be using the Yacc stack to return semantic values and refer to them via $3, $4 and $5.
As for the corruption problem you’re chasing; it is quite possibly a static array overrun. You are not doing any bounds checking on anything.
The gist of the problem is this:
If you access
array1beyond its end, you will likely trash some other variable, like perhapsarray2, depending on how things are laid out in the run-time image.One thing you can do, in the absence of more advanced debugging tools, is to step through the code in the debugger and monitor the contents of the overwritten variable. Try to catch the program “red handed” changing that value.
Secondly, the contents of that trashed array should give you a clue about where that material came from! It appears to be a fragment of text, which can be traced back to your input, and from there you can trace where that part of the input is handled in your parsing machine.