.\" .\" UCSD p-System cross compiler .\" Copyright (C) 2006, 2007, 2012 Peter Miller .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or (at .\" you option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU .\" General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License along .\" with this program. If not, see .\" .ad l .hy 0 Compilers and Factories, 11
Back Next

Method

To get the assignment correct, we assume an idenitifier is on the right hand side (that happens more often), and to turn it into a left hand side if needed. But there is a right way and a wrong way....
expression
    : expression ASSIGN expression
        { $$ = context->expression_assign($1, $3); }
expression
    : expression ASSIGN expression
        { $$ = $1->assignment_factory($3); }
expression *
translator::expression_assign(expression *lhs,
    expression *rhs)
{
    if (lhs is an integer variable)
    {
        return expression_assign_integer_factory(
            lhs->get address, rhs);
    }
    if (lhs is an integer array element)
    {
        return expression_assign_integer_factory(
            lhs->get address, rhs);
    }
    if (lhs is a string variable)
    {
        return expression_assign_string_factory(
            lhs->get address, rhs);
    }
    etc etc etc
    yyerror("left hand side of assignment inappropriate");
    return new expression_error();
}
class expression
{
    blah blah
public:
    virtual expression *assignment_factory(expression *rhs);
    blah blah
};
expression *
expression::assignment_factory(expression *rhs)
{
    yyerror("left hand side of assignment inappropriate");
    return new expression_error();
}
No downcasts required.

(Note similarity to “switch (lhs->e_id)” in counter example.)

.\" vim: set ts=8 sw=4 et :