Class to support keywords.

J

Jason Heyes

I want to write a class that supports operations on keywords belonging to
the C++ programming language. The following program repeatedly prompts the
user for a keyword until 'explicit' is finally entered:

#include <iostream>
#include "KeyWord.h"

int main()
{
KeyWord word;
while (std::cin >> word && word != "explicit");
return 0;
}

What would a class that supports the functionality of KeyWord in the above
program look like?What are the details of the implementation of such a
class? How many changes to the implementation would be required if another
set of keywords was to be used instead?

I would appreciate help in the form of code as well as discussion. Thanks.
 
J

Jeff Schwab

Jason said:
I want to write a class that supports operations on keywords belonging to
the C++ programming language. The following program repeatedly prompts the
user for a keyword until 'explicit' is finally entered:

#include <iostream>
#include "KeyWord.h"

int main()
{
KeyWord word;
while (std::cin >> word && word != "explicit");
return 0;
}

What would a class that supports the functionality of KeyWord in the above
program look like?What are the details of the implementation of such a
class? How many changes to the implementation would be required if another
set of keywords was to be used instead?

I would appreciate help in the form of code as well as discussion. Thanks.

// KeyWord.h

#include <iostream>
#include <string>

typedef std::string KeyWord;
 
K

Karl Heinz Buchegger

Jason said:
I would appreciate help in the form of code as well as discussion. Thanks.

Maybe its just me.
But from your description, it is not clear to me what you want to achieve.
 
J

Jeff Schwab

Alf said:
* Jeff Schwab:



Well, you don't need <iostream> there.

Right you are. I copied that from the top of my "make sure it works
before I post it" file.

// KeyWord.h -- Second Edition

#include <string>

typedef std::string KeyWord;
 
J

Jerry Coffin

Jason said:
I want to write a class that supports operations on keywords belonging to
the C++ programming language. The following program repeatedly prompts the
user for a keyword until 'explicit' is finally entered:

#include <iostream>
#include "KeyWord.h"

int main()
{
KeyWord word;
while (std::cin >> word && word != "explicit");
return 0;
}

What would a class that supports the functionality of KeyWord in the above
program look like?What are the details of the implementation of such a
class? How many changes to the implementation would be required if another
set of keywords was to be used instead?

What you've shown so far doesn't seem to require anything that isn't
already present in std::string. You can look up details of its design
interface in the C++ standard (available from webstore.ansi.org). A
number of C++ standard libraries have source code available, making it
possible (if not necessarily easy) to study their implementations.

Changes to the class _should_ be required primarily if the definition
of the KIND of string that could constitute a key word changed, NOT
simply when the set of key words changed (e.g. keywords that can
included spaces would call for a different definition of operator>>
than std::string has). Of course, this is based on how you've used it
above -- different use might change the requirement(s) -- in
particular, it might be reasonable to have the Keyword class "know"
what's a keyword and what's not, in which case you'd have to do
_something_ to let it know -- but personally, I'd leave define the
class as an "engine" that used external data to define the set of key
words to be recognized.
 
J

Jason Heyes

Jerry Coffin said:
What you've shown so far doesn't seem to require anything that isn't
already present in std::string. You can look up details of its design
interface in the C++ standard (available from webstore.ansi.org). A
number of C++ standard libraries have source code available, making it
possible (if not necessarily easy) to study their implementations.

Changes to the class _should_ be required primarily if the definition
of the KIND of string that could constitute a key word changed, NOT
simply when the set of key words changed (e.g. keywords that can
included spaces would call for a different definition of operator>>
than std::string has). Of course, this is based on how you've used it
above -- different use might change the requirement(s) -- in
particular, it might be reasonable to have the Keyword class "know"
what's a keyword and what's not, in which case you'd have to do
_something_ to let it know -- but personally, I'd leave define the
class as an "engine" that used external data to define the set of key
words to be recognized.

I don't want to "tell" a KeyWord object the set of C++ keywords (e.g., for,
while, do, if, etc). It should already know. I would especially like to
extract a C++ keyword from a stream with complete ignorance (i.e., not
knowing the set of C++ keywords).
 
H

Howard

Jason Heyes said:
I don't want to "tell" a KeyWord object the set of C++ keywords (e.g.,
for, while, do, if, etc). It should already know. I would especially like
to extract a C++ keyword from a stream with complete ignorance (i.e., not
knowing the set of C++ keywords).

Umm, ok... but if you don't give your class the list of keywords that are
valid, then how is it supposed to know them??? There is no part of the
run-time library that includes that list for you, so it's impossible for
your class to know if a word is a "keyword" or not, unless you give it that
information... somehow!

The parsing engines in C++ compilers don't magically "know" what's a valid
C++ keyword; it's built into the parser somehow. One way to do that is to
hard-code all the possible keywords, and rules for when/how they can appear
and what they mean in that context. Another method is to use tools like lex
and yacc, which allow you to specify the keywords and grammar rules. But
that's a lot of work, and it takes a while to learn how to use such tools.

A simple, flexible model would be one where you call a member function of
your class to cause it to read a set of valid keywords from a file. Then,
to change what keywords are valid, all you'd need is a new file.

But you still haven't fully explained what you're trying to accomplish.
(Was this a homework problem, as suggested elsewhere?)

-Howard
 
T

Thomas Matthews

Jason said:
I want to write a class that supports operations on keywords belonging to
the C++ programming language. The following program repeatedly prompts the
user for a keyword until 'explicit' is finally entered:

#include <iostream>
#include "KeyWord.h"

int main()
{
KeyWord word;
while (std::cin >> word && word != "explicit");
return 0;
}

What would a class that supports the functionality of KeyWord in the above
program look like?What are the details of the implementation of such a
class? How many changes to the implementation would be required if another
set of keywords was to be used instead?

I would appreciate help in the form of code as well as discussion. Thanks.
using std::istream;
using std::eek:stream;

class KeyWord
{
public:

// Here is the declaration for the extraction operator.
friend istream& operator<<(istream&, Keyword& k);

// Might as well have the insertion operator too.
friend ostream& operator>>(ostream&, const Keyword&);

// The main() function requires the following operator:
bool operator!=(const char * text) const;

// If you have != you might as well have == too.
// (many implementations have != implemented in terms
// of ==.
bool operator==(const char * text) const;

// The main program indirectly states that there is a
// default (no parameter) constructor. The compiler
// can generate it for you, but you may want to be
// explicit and create one.
KeyWord(const char * new_text = 0);

// Don't forget the copy constructor too.
Keyword(const Keyword& kw);

// Yep, and the destructor:
virtual ~Keyword();

// If you declare the three above, you should also
// declare assignment:
Keyword& operator=(const Keyword& kw);
};

Well, this answers the first question, from observation
in the main() function.

Can you (the O.P.) post the implementation of these
functions?

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
J

Jason Heyes

Thomas Matthews said:
using std::istream;
using std::eek:stream;

class KeyWord
{
public:

// Here is the declaration for the extraction operator.
friend istream& operator<<(istream&, Keyword& k);

// Might as well have the insertion operator too.
friend ostream& operator>>(ostream&, const Keyword&);

// The main() function requires the following operator:
bool operator!=(const char * text) const;

// If you have != you might as well have == too.
// (many implementations have != implemented in terms
// of ==.
bool operator==(const char * text) const;

// The main program indirectly states that there is a
// default (no parameter) constructor. The compiler
// can generate it for you, but you may want to be
// explicit and create one.
KeyWord(const char * new_text = 0);

// Don't forget the copy constructor too.
Keyword(const Keyword& kw);

// Yep, and the destructor:
virtual ~Keyword();

// If you declare the three above, you should also
// declare assignment:
Keyword& operator=(const Keyword& kw);
};

Well, this answers the first question, from observation
in the main() function.

Can you (the O.P.) post the implementation of these
functions?

Someone at University helped me write an extractor that does the job:

std::istream &KeyWord::eek:perator>>(std::istream &is, KeyWord &keyword)
{
std::string s;
if (!(is >> s))
{
std::cout << "Failed to read string of KeyWord" << std::endl;
return is;
}

if (!(s == "do" || s == "while" || s == "explicit" /* || ... */))
{
std::cout << "String " << s << " does not describe a valid KeyWord"
<< std::endl;
is.setstate(is.failbit);
}

return is;
}

This isn't satisfactory due to the big if-statement. See, I would like to
write KeyWord classes for many other languages like Pascal, C, etc. I need
something more elegant than a giant if-statement.
 
K

Karl Heinz Buchegger

Jason said:
Someone at University helped me write an extractor that does the job:

std::istream &KeyWord::eek:perator>>(std::istream &is, KeyWord &keyword)
{
std::string s;
if (!(is >> s))
{
std::cout << "Failed to read string of KeyWord" << std::endl;
return is;
}

if (!(s == "do" || s == "while" || s == "explicit" /* || ... */))
{
std::cout << "String " << s << " does not describe a valid KeyWord"
<< std::endl;
is.setstate(is.failbit);
}

return is;
}

This isn't satisfactory due to the big if-statement. See, I would like to
write KeyWord classes for many other languages like Pascal, C, etc. I need
something more elegant than a giant if-statement.

Well, obviously the list of valid keywords must then come from elsewhere.
Eg. you can setup a std::vector or a std::map in the KeyWord class, which
contains all the valid keywords. The operator then checks if the just read
string is contained in that vector or map. If yes -> string is a valid
keyword.

How this vector is set up is completely left to your imagination. You can
eg. put them in in the constructor and have them hard coded in the source
file, or you can read them from a file or ...
 
T

Thomas Matthews

Jason said:
Someone at University helped me write an extractor that does the job:

std::istream &KeyWord::eek:perator>>(std::istream &is, KeyWord &keyword)
{
std::string s;
if (!(is >> s))
{
std::cout << "Failed to read string of KeyWord" << std::endl;
return is;
}

if (!(s == "do" || s == "while" || s == "explicit" /* || ... */))
{
std::cout << "String " << s << " does not describe a valid KeyWord"
<< std::endl;
is.setstate(is.failbit);
}

return is;
}

This isn't satisfactory due to the big if-statement. See, I would like to
write KeyWord classes for many other languages like Pascal, C, etc. I need
something more elegant than a giant if-statement.

Vectors and arrays.

/* in source file */
#include <string>
using std::string;

static const string keyword_list[] =
{
string("static"), string("const"),
string("using"), string("if"),
string("while"), string("do"),
string("goto"), string("for")
}
static const unsigned int Words_In_List =
sizeof(keyword_list) / sizeof(keyword_list[0]);

bool is_keyword(const string& word)
{
bool found = false;
for (unsigned int i = 0;
!found && (i < Words_In_List); ++i)
{
found = word == keyword_list;
}
return found;
}

If the keywords are sorted, you can use a
faster search, such as std::upper_bound,
std::lower_bound, or std::binary_search.

You may also want to use a vector, since
vectors can grow dynamically at run-time.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
R

Richard Herring

In message <[email protected]>, Jason Heyes
if (!(s == "do" || s == "while" || s == "explicit" /* || ... */))
{
std::cout << "String " << s << " does not describe a valid KeyWord"
<< std::endl;
is.setstate(is.failbit);
}

return is;
}

This isn't satisfactory due to the big if-statement. See, I would like to
write KeyWord classes for many other languages like Pascal, C, etc. I need
something more elegant than a giant if-statement.

Look up std::set, particularly its count() function.

If you want to associate behaviour with the keys, try std::map.
 
J

Jason Heyes

Karl Heinz Buchegger said:
Well, obviously the list of valid keywords must then come from elsewhere.
Eg. you can setup a std::vector or a std::map in the KeyWord class, which
contains all the valid keywords. The operator then checks if the just read
string is contained in that vector or map. If yes -> string is a valid
keyword.

How this vector is set up is completely left to your imagination. You can
eg. put them in in the constructor and have them hard coded in the source
file, or you can read them from a file or ...

Ok I am satisfied. Thanks for your help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,291
Messages
2,571,455
Members
48,132
Latest member
KatlynC08

Latest Threads

Top