Professional Documents
Culture Documents
Parser Common.c
Parser Common.c
h"
/* Reads contents of file into character buffer */
int fileread(char **ptrDest,const char *fileName,int *bytesRead)
{
int nbytes; /* Total number of bytes read from file */
int nread; /* Bytes read by one call to fread() */
int count; /* Number of times memory was allocated */
int offset; /* Offset from start of buffer */
const int BUF_STEP_SZ = 256;
char *oldbuffer;
char *buffer = NULL;
FILE *fp;
assert(buffer == NULL);
fp = fopen(fileName,"rb"); /* rb mode for compatibility with non PO
SIX systems */
if(!fp)
{
perror(fileName);
return 1;
}
count = 0;
nbytes = 0;
for(; ; count++)
{
if(feof(fp))
{
fclose(fp);
break;
}
oldbuffer = buffer; /* store pointer to memory alloc
ated so far */
buffer = (char*)realloc(buffer,(count+1)*BUF_STEP_SZ);
/* Increase size of buffer */
if(!buffer)
{
printf("\nError: Unable to allocate memory.");
free(oldbuffer);
fclose(fp);
return 1;
}
offset = count*BUF_STEP_SZ;
nread = fread(buffer+offset,sizeof(char),BUF_STEP_SZ,fp);
if(nread == 0)
{
if(ferror(fp))
{
perror(fileName);
fclose(fp);
free(buffer);
return 1;
}
}
nbytes += nread;
}
*bytesRead = nbytes;
*ptrDest = buffer;
return 0;
}
}
return array;
}
/*
* Tests if a string is nullable
* Arg1 = A production body.
* Arg2 = Grammar table.
* Arg3 = Number of variables in the grammar table
* Arg4 = Array of all tokens.
*/
_Bool isNullable(char *body,struct prodList **table,int no_of_variables,char *to
kens)
{
int i;
int lastindex = 0;
_Bool retval = true;
int j;
char *next;
if( strncmp(body,"epsilon",7) == 0) /* If body contains nothing but
epsilon */
{
return true;
}
for(i=0; ;i++)
{
next = getNextSymbol(body,&lastindex);
if( next == NULL) break;
if(isToken(next,tokens)) /* If symbol is a token, body ca
n not be nullable */
{
retval = false;
break;
}
else /* If symbol is a variable */
{
j = indexOf(next,table,no_of_variables); /* Index
of this variable in the grammar table */
assert(j>=0);
if(table[j]->nullable == false)
{
retval = false;
break;
}
}
}
return retval;
}
/*
* Returns next symbol from an array holding a production body.
* A
*/
char *getNextSymbol(char *body,int *lastindex)
{
int i,j;
char *retval = NULL;
int len;
if(body[*lastindex] == '\0') /* No more symbols to extract ? Return N
ULL */
{
return retval;
}
for (i = *lastindex ; i<strlen(body) ; i++)
{
if(body[i] != ' ') break;
}
for(j=i+1; j<strlen(body) ;j++)
{
if(body[j] == ' ') break;
}
len = j-i+1;
retval = (char*)malloc(sizeof(char) * (len + 1));
strncpy(retval,body+i,len);
retval[len] = '\0';
(*lastindex) = j;
if(strcmp (retval,"") == 0) return NULL; /* Never return an empt
y string */
return retval;
}
return true;
}
return -1;
}
/*
* Add a new element (string) to a space separated set of strings if it not alre
ady in the set.
* Arg1 = set
* Arg2 = element to add
* Arg3 = Used to indicate if the set changed as a result of this call
*/
char *addToSet(char *set, char * element, int *changed)
{
char *retval = set;
#ifdef DEBUG
printf("\nset = %s ; element = %s ; ",set,element);
#endif
else
{
/* If element to be removed is empty, do nothing */
if(element == NULL)
{
changes = 0;
}
else
{
/* Find the offset of element in set */
int j = strlen(set)-strlen(element)+1;
for(i=0 ; i < j ; i++)
{
//
if(strncmp(set+i,element,strlen(element)) == 0)
{
index = i;
break;
}
}
/* If element not found in set */
if(index == -1) changes = 0;
/* If element found in set, extract subsets before and a
fter of set and merge them*/
/* Index is the offset at which element was found */
else
{
before = strndup(set,index);
after = strdup(set+index+strlen(element));
ret = before;
ret = strcat(ret,after);
changes = 1;
}
}
if(setchanged) *setchanged = changes;
//printf("Returning %-s",ret);
return ret;
}
/*
* Writes Parse Table to a file
* @PARAM: Parse Table Structure.
* @TODO: Use XML instead of proprietary format when saving to file.
*/