ANTLR4 Version 4.5.4 CPP target: Compile problem with visitors

477 views
Skip to first unread message

Marcel Schaible

unread,
Jul 21, 2016, 1:53:37 PM7/21/16
to antlr-di...@googlegroups.com
Hi,

we are trying to use vistors with the new cpp runtime target. Our custom vistor class is defined like this:

class MyVisitor : public MyBaseVisitor<int>

Visual Studio 2015 produces the following error:

2>antlr-parser\runtime\src\tree\abstractparsetreevisitor.h(70): error C2664: 'bool antlr4::tree::AbstractParseTreeVisitor<T>::shouldVisitNextChild(antlr4::tree::RuleNode *,T)': cannot convert argument 2 from 'int *' to 'int'
2>                 with
2>                 [
2>                     T=int
2>                 ]
2>         antlr-parser\runtime\src\tree\abstractparsetreevisitor.h(70): note: There is no context in which this conversion is possible
2>         antlr-parser\runtime\src\tree\abstractparsetreevisitor.h(66): note: while compiling class template member function 'int *antlr4::tree::AbstractParseTreeVisitor<T>::visitChildren(antlr4::tree::RuleNode *)'
2>                 with
2>                 [
2>                     T=int
2>                 ]
2>         antlr-parser\demo\generated\tinypl90cbasevisitor.h(18): note: see reference to class template instantiation 'antlr4::tree::AbstractParseTreeVisitor<T>' being compiled
2>                 with
2>                 [
2>                     T=int
2>                 ]
2>         antlr-parser\demo\windows\antlr4-cpp-demo\main.cpp(31): note: see reference to class template instantiation 'MyBaseVisitor<int>' being compiled
2>

With the Java runtime I would define a visitor class like this:

public class MyOwnVisitor extends MyBaseVisitor<ST> implements MyVisitor<ST>


Can anyone give a short example how this is intended to work in C++?


Any idea or hint is appreciated ;-)

Thanks for your help

Marcel

Mike Lischke

unread,
Jul 29, 2016, 3:55:55 AM7/29/16
to antlr-di...@googlegroups.com
Hey Marcel,

we trying to use vistors with the new cpp runtime target. Our custom vistor class is defined like this:

class ShipItWinnerVisitor : public TinyPL90CBaseVisitor<int>

Visual Studio 2015 produces the following error:

2>antlr-parser\runtime\src\tree\abstractparsetreevisitor.h(70): error C2664: 'bool antlr4::tree::AbstractParseTreeVisitor<T>::shouldVisitNextChild(antlr4::tree::RuleNode *,T)': cannot convert argument 2 from 'int *' to 'int'
2>                 with
2>                 [
2>                     T=int
2>                 ]
2>         antlr-parser\runtime\src\tree\abstractparsetreevisitor.h(70): note: There is no context in which this conversion is possible
2>         antlr-parser\runtime\src\tree\abstractparsetreevisitor.h(66): note: while compiling class template member function 'int *antlr4::tree::AbstractParseTreeVisitor<T>::visitChildren(antlr4::tree::RuleNode *)'
2>                 with
2>                 [
2>                     T=int
2>                 ]
2>         antlr-parser\demo\generated\tinypl90cbasevisitor.h(18): note: see reference to class template instantiation 'antlr4::tree::AbstractParseTreeVisitor<T>' being compiled
2>                 with
2>                 [
2>                     T=int
2>                 ]
2>         antlr-parser\demo\windows\antlr4-cpp-demo\main.cpp(31): note: see reference to class template instantiation 'TinyPL90CBaseVisitor<int>' being compiled
2>

I think there is a problem in the C++ runtime. Probably introduced by the automatic Java-to-C++ convertor and never been corrected. Anyway, in Java the ParseTreeVisitor class returns the same type in all visitor methods as it was parameterized to, while in C++ the return values are pointers to the parameterized type. I'll change this so that the ParseTreeVisitor class behaves the same in C++ (similar for the code generation).

Mike Lischke

unread,
Jul 31, 2016, 7:37:24 AM7/31/16
to antlr-di...@googlegroups.com
I have now reworked the visitor handling in a way that doesn't require virtual template functions (which would be the natural translation of the Java generics code). Instead there is now a small Any class (similar like boost::any) which is used to return results from visits (hence no templates needed anymore for visitors). I checked that with a very simple test visitor for my MySQL grammar:

class TestParseVisitor : public MySQLParserBaseVisitor {

  virtual Any visitSelect_item(MySQLParser::Select_itemContext *context) override {
    Any result = visitChildren(context);
    std::cout << "Expression result: " << result.as<int>() << std::endl;
    return result;
  }

  virtual Any visitAdditive_expression(MySQLParser::Additive_expressionContext *context) override {
    Any result = visit(context->children[0].get());
    size_t i = 1;
    while (i < context->children.size()) {
      std::string op = context->children[i++]->getText();
      Any right = visit(context->children[i++].get());
      if (op == "+")
        result = result.as<int>() + right.as<int>();
      else
        result = result.as<int>() - right.as<int>();
    }
    return result;
  }

  virtual Any visitMultiplicative_expression(MySQLParser::Multiplicative_expressionContext *context) override {
    Any result = visit(context->children[0].get());
    size_t i = 1;
    while (i < context->children.size()) {
      std::string op = context->children[i++]->getText();
      Any right = visit(context->children[i++].get());
      switch (op[0]) {
        case '*':
          result = result.as<int>() * right.as<int>();
          break;
        case '/':
        case 'd': // DIV
        case 'D':
          result = result.as<int>() / right.as<int>();
          break;
        case '%':
        case 'm': // MOD
        case 'M':
          result = result.as<int>() % right.as<int>();
        break;
      }
    }
    return result;
  }

  virtual Any visitExpression_list_with_parentheses(MySQLParser::Expression_list_with_parenthesesContext *context) override {
    return visit(context->expression_list().get());
  }

  virtual Any visitLiteral(MySQLParser::LiteralContext *context) override
  {
    return std::atoi(context->start->getText().c_str());
  }
};

The ANLTR 4.5.4 snapshot jar as well as all other packages on my homepage (source code, prebuilt libraries) have been updated to include this and other recent changes.

Reply all
Reply to author
Forward
0 new messages