Implementing a restricted C langage (Lex-Yacc-C++)

S

steve

Hello !

I have a special need implementing a lexical parser. I have a C
restricted grammar, in which I accept such operations as (3<3.5) or
(s<"string"). My problem is that I meet some conception problem. I
would like Yacc to simply operate $$=$1+$3 on my following Node
objects. I tryed to overload operators so that NodeInt n1 < NodeLong n2
automatically get the right values with getValue() function but C++
spec forbids template virtual methods.
Could you please advise a design or a track to unlock me please ?
Thanks in advance,

Steve

class Node {
protected:
int type;

public:
Node();
~Node();
virtual int comparison(Node* n2) = 0;
int operator < (Node& n2); // call comparison(n2)

template <typename T>
virtual T getValue();
};

class NodeString : public Node {
private:
char* s;

public:
NodeString(void* p);
~NodeString();
int comparison(Node* n2); /* may operate
* this->getValue() < n2.getValue()
* strcmp(this->getValue(), n2.getValue())
* strcmp(this->getValue(),
* itoa(n2.getValue()))
*/


char* getValue();
};


class NodeLong : public Node {
private:
long l;

public:
NodeLong(void* p);
~NodeLong();
int comparison(Node* n2);
double getValue();
};
 
D

David Harmon

On 18 Oct 2006 06:29:01 -0700 in comp.lang.c++, "steve"
virtual int comparison(Node* n2) = 0;
int operator < (Node& n2); // call comparison(n2)

template <typename T>
virtual T getValue();

Even if the template were accepted, it would not solve your problem.
The template would just give you the equivalent of writing two
member functions,
virtual int getValue();
virtual string getValue();
but that won't go because you cannot overload on return type. The
same issue viewed from the other side is that when you get down to
///
int comparison(Node* n2); /* may operate
* this->getValue() < n2.getValue()
* strcmp(this->getValue(), n2.getValue())
* strcmp(this->getValue(),
* itoa(n2.getValue()))
*/
/// then the compiler still could not choose which getvalue() to
call or which of those comparisons to apply.

The complication is that you need to choose method based on the
dynamic type of _both_ left and right operands. Look up "double
dispatch". BTW, you forgot the
strcmp(itoa(this->getvalue), n2.getvalue())
case, so there really are four involved.

I suppose you have only the two derived classes and that it will
never become many derived classes, so then the solution is not too
complicated.

Replace comparison with two functions:
virtual bool comp_string(NodeString* n2);
virtual bool comp_long(NodeLong* n2);

Make operator< virtual also. Then,
int NodeString::eek:perator < (Node& n2) {
return n2.comp_string(*this);
}
and
int NodeLong::eek:perator < (Node& n2) {
return n2.comp_long(*this);
}

Finally,
bool NodeString::comp_string(NodeString* n2) {
return strcmp(n2->s, s);
}
bool NodeString::comp_long(NodeLong* n2) {
return strcmp(itoa(n2->l), s);
}
bool NodeLong::comp_string(NodeString* n2) {
return strcmp(n2->s, itoa(l));
}
bool NodeLong::comp_long(NodeLong* n2)
return n2->l < l;
}

Notice that the n1 and n2 sides get switched during the call to
comp_*(). Fixup the bool return to what you really wanted. Replace
n2->member with getLong() and getString() as you prefer. Change all
those pointers to const references! Fix any bugs I left for you.

Do not listen to any proposal using typeid() or dynamic_cast<>().
That's the cowards way out!
 

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
473,981
Messages
2,570,188
Members
46,733
Latest member
LonaMonzon

Latest Threads

Top