views:

187

answers:

3

Hello guys I'm facing some problems on the lexical analysis of my compiler I had declared the following pointer

char *words[29]={
     "program",
     "label",
     "integer",
     "word",
     "char",
     "byte",
     "shortint",
     "logint",
     "real",
     "single",
     "double",
     "string",
     "boolean",
     "var",
     "procedure",
     "function",
     "begin",
     "end",
     "if",
     "then",
     "else",
     "or",
     "and",
     "div",
     "not",
     "do",
     "while",
     "mod"
};
char message[30];

and then I tried to use it in a function

   for(handle=0;(&words[handle] != NULL);handle++)
   {
    message = &words[handle];
    if(!strcmp(token,message))
     message='words';
   }

But I'm receiving the following errors when trying to execute:

regarding (line message = &words[handle];) : warning C4047: '=' : 'char [30]' differs in levels of indirection from 'char ** '

regarding (line message = &words[handle];) : error C2106: '=' : left operand must be l-value

regarding (line message='words';) : error C2015: too many characters in constant

regarding (line message='words';) : error C2106: '=' : left operand must be l-value

can't I work with pointers that way? Do you have any suggestions?

+3  A: 

Three things:

  1. The ampersands (&) are extraneous. The type of words[handle] is char *, i.e. a string, so right there you have what you need. You don't need to take the address of that char *.

  2. You cannot directly assign to message with = as it is an array. C is not a very fancy language. You can either change message to char *message, so it is a pointer rather than an array; or you can use the strcpy(dst, src) function to copy to it, like so: strcpy(message, "words").

  3. Your for loop looks for a NULL pointer in the words array so it knows when to stop--but you don't have NULL in the array! You need to add NULL to the end. As written there are only regular strings so the loop will never find the null pointer it is looking for and will go charging off into uncharted zones of memory.

Hope that helps!

John Kugelman
It helped a lot, thanks!
+3  A: 

You have a number of errors there:

  • instead of &words[handle], use words[handle]
  • what are you trying to do by message = 'words'? There are at least 3 errors here: the string uses double quotes, not single quotes; message is a constant, you can't change it; to copy strings, you need to use strcpy(), not just = operator
  • strcmp() returns 0, if the strings are equal; you need to reverse your logic
  • you forgot to include NULL at the end of your array
Igor Krivokon
+2  A: 

You have a number of problems with your code. First of all, you should declare your array of keywords as const char *words[]. It's bad practice to declare string constants as char *, without the const; it's only allowed so that legacy code still compiles.

You shouldn't specify the array size of 29 in the declaration, since it's fragile. You should just use empty brackets and let the compiler figure out the array size. You can get the size of the array by doing sizeof(words)/sizeof(words[0]), which will still be correct even if you add or delete elements from words.

Next, your for loop is never going to terminate (although it will almost assuredly segfault at some point). Taking the address of a value will never yield the null pointer, so &words[handle] != NULL will always be true. The proper way to iterate through the loop is to just count the number of entries:

for(handle = 0; handle < sizeof(words)/sizeof(words[0]); handle++)

message is declared as an array of characters. Arrays aren't assignable, i.e. they are not lvalues. If you want to assign to an array, you have to explicitly copy data into it with something such as strcpy() (not recommended except in select cases, due to potential buffer overflows), strncpy(), memcpy(), or strncpy_s() (available only on Windows).

In this case, though, you don't want an array at all -- you just want to assign a pointer. Declare message as a const char * instead. With message declared properly, you would do:

const char *message;
...
message = words[handle];
if(!strcmp(token, message))
    message = "words";

In the final statement there, you should use double quotes around words to make it a string constant. Single quotes are for single character constants (e.g. 'A'). Although they technically can contain more than one character, the endianness of the resulting integer constant is implementation-defined, and they're not what you want in this case.

I'm also not quite sure what you're trying to do with the message = "words"; line. If you're trying to do some clever trick with the words variable, stop right now, it's not going to work. C doesn't have any sort of reflection.

Adam Rosenfield