Members

Technology Zones

IBM Learning Center

Articles

Hosted By

MaximumASP

Info

This resource has not currently been approved, and is not currently linked to from our directory of resources. It is being displayed here for preview by the author and moderators only.
Rated
Read 275 times

Contents

Related Categories

The use of the code analysis library OpenC++: modifications, improvements, error corrections - 7. Partial correction of the processing of "bool r = a < 1 || b > (int) 2;" type expressions.

AndreyKarpov

7. Partial correction of the processing of "bool r = a < 1 || b > (int) 2;" type expressions.

There is an error in OpenC++ related to the processing of some expressions which are wrongly taken for templates. For example, in a string "bool r = a < 1 || b > (int) 2;" "a" variable will be taken for a template name and then a lot of troubles with syntactical analysis will follow? Full correction of this error requires great changes and is not realized by now. We offer you a temporary solution excluding the major part of errors. Further the functions are given which may be added or modified.

bool VivaParser::MaybeTypeNameOrClassTemplate(Token &token) {
  if (m_env == NULL) {
    return true;
  }
  const char *ptr = token.GetPtr();
  ptrdiff_t len = token.GetLen();
  Bind *bind;
  bool isType = m_env->LookupType(ptr, len, bind);
  return isType;
}
static bool isOperatorInTemplateArg(ptrdiff_t t) {
  return t == AssignOp || t == EqualOp || t == LogOrOp ||
         t == LogAndOp || t == IncOp || t == RelOp;
}
/*
  template.args : '<' any* '>'
  template.args must be followed by '(' or '::'
*/
bool Parser::isTemplateArgs()
{
    ptrdiff_t i = 0;
    ptrdiff_t t = lex->LookAhead(i++);
    if(t == '<'){
        ptrdiff_t n = 1;
        while(n > 0){
            ptrdiff_t u = lex->LookAhead(i++);
           /*
            TODO. :(
            Fixing: bool r = a < 1 || b > (int) 2;
            We'll correct not all the cases but it will be better anyway.
            Editing method. If an identifier is found near the operator, it is 
            obviously not a template because only a type or a constant 
            expression may stay inside the brackets.
            An example which doesn't work anyway:
            r = a < fooi() || 1 > (int) b;
            
            Unfortunately, the following expression is processed incorrectly now,              
            but such cases are fewer than corrected ones.
            template <int z>
            unsigned TFoo(unsigned a) {
            return a + z;
            }
            enum EEnum { EE1, EE2 };
            b = TFoo < EE1 && EE2 > (2);
            */
            
            ptrdiff_t next = lex->LookAhead(i);
            if (u == Identifier &&
                isOperatorInTemplateArg(next))
              return false;
            if (isOperatorInTemplateArg(u) &&
                next == Identifier)
              return false;
            if(u == '<')
                ++n;
            else if(u == '>')
                --n;
            else if(u == '('){
                ptrdiff_t m = 1;
                while(m > 0){
                    ptrdiff_t v = lex->LookAhead(i++);
                    if(v == '(')
                        ++m;
                    else if(v == ')')
                        --m;
                    else if(v == '\0' || v == ';' || v == '}')
                        return false;
                }
            }
            else if(u == '\0' || u == ';' || u == '}')
                return false;
        }
        t = lex->LookAhead(i);
        return bool(t == Scope || t == '(');
    }
    return false;
}

Comments