Simplified parse tree listener handling.

No need to use shared_ptr for management. Listeners are, like the other main classes (parser, lexer, input stream etc.) provided by the application and hence managed there.
This commit is contained in:
Mike Lischke 2016-06-17 10:22:19 +02:00
parent dd48c0fbd5
commit 4a7ec859aa
9 changed files with 31 additions and 31 deletions

View File

@ -72,7 +72,7 @@ int main(int argc, const char* argv[]) {
This example assumes your grammar contains a parser rule named `key` for which the enterKey function was generated. The `Ref<>` template is an alias for `std::shared_ptr<>` to simplify the runtime source code which often makes use of smart pointers. This example assumes your grammar contains a parser rule named `key` for which the enterKey function was generated. The `Ref<>` template is an alias for `std::shared_ptr<>` to simplify the runtime source code which often makes use of smart pointers.
### Specialities of this ANTLR target ## Specialities of this ANTLR target
There are a couple of things that only the C++ ANTLR target has to deal with. They are described here. There are a couple of things that only the C++ ANTLR target has to deal with. They are described here.

View File

@ -305,7 +305,7 @@ BasicListener(X) ::= <<
@parser::definitions { @parser::definitions {
class LeafListener : public TBaseListener { class LeafListener : public TBaseListener {
public: public:
virtual void visitTerminal(Ref\<tree::TerminalNode> const& node) override { virtual void visitTerminal(tree::TerminalNode *node) override {
std::cout \<\< node->getSymbol()->getText() \<\< std::endl; std::cout \<\< node->getSymbol()->getText() \<\< std::endl;
} }
}; };

View File

@ -13,13 +13,13 @@ public class TestListeners extends BaseCppTest {
public void testBasic() throws Exception { public void testBasic() throws Exception {
mkdir(tmpdir); mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(491); StringBuilder grammarBuilder = new StringBuilder(480);
grammarBuilder.append("grammar T;\n"); grammarBuilder.append("grammar T;\n");
grammarBuilder.append("\n"); grammarBuilder.append("\n");
grammarBuilder.append("@parser::definitions {\n"); grammarBuilder.append("@parser::definitions {\n");
grammarBuilder.append("class LeafListener : public TBaseListener {\n"); grammarBuilder.append("class LeafListener : public TBaseListener {\n");
grammarBuilder.append("public:\n"); grammarBuilder.append("public:\n");
grammarBuilder.append(" virtual void visitTerminal(Ref<tree::TerminalNode> const& node) override {\n"); grammarBuilder.append(" virtual void visitTerminal(tree::TerminalNode *node) override {\n");
grammarBuilder.append(" std::cout << node->getSymbol()->getText() << std::endl;\n"); grammarBuilder.append(" std::cout << node->getSymbol()->getText() << std::endl;\n");
grammarBuilder.append(" }\n"); grammarBuilder.append(" }\n");
grammarBuilder.append("};\n"); grammarBuilder.append("};\n");

View File

@ -1083,7 +1083,7 @@
276E5CD11CDB57AA003FF4B4 /* Predicate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Predicate.h; sourceTree = "<group>"; }; 276E5CD11CDB57AA003FF4B4 /* Predicate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Predicate.h; sourceTree = "<group>"; };
276E5CD41CDB57AA003FF4B4 /* NoViableAltException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NoViableAltException.cpp; sourceTree = "<group>"; wrapsLines = 0; }; 276E5CD41CDB57AA003FF4B4 /* NoViableAltException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NoViableAltException.cpp; sourceTree = "<group>"; wrapsLines = 0; };
276E5CD51CDB57AA003FF4B4 /* NoViableAltException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NoViableAltException.h; sourceTree = "<group>"; wrapsLines = 0; }; 276E5CD51CDB57AA003FF4B4 /* NoViableAltException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NoViableAltException.h; sourceTree = "<group>"; wrapsLines = 0; };
276E5CD61CDB57AA003FF4B4 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Parser.cpp; sourceTree = "<group>"; }; 276E5CD61CDB57AA003FF4B4 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Parser.cpp; sourceTree = "<group>"; wrapsLines = 0; };
276E5CD71CDB57AA003FF4B4 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = "<group>"; }; 276E5CD71CDB57AA003FF4B4 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = "<group>"; };
276E5CD81CDB57AA003FF4B4 /* ParserInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParserInterpreter.cpp; sourceTree = "<group>"; wrapsLines = 0; }; 276E5CD81CDB57AA003FF4B4 /* ParserInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParserInterpreter.cpp; sourceTree = "<group>"; wrapsLines = 0; };
276E5CD91CDB57AA003FF4B4 /* ParserInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserInterpreter.h; sourceTree = "<group>"; wrapsLines = 0; }; 276E5CD91CDB57AA003FF4B4 /* ParserInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserInterpreter.h; sourceTree = "<group>"; wrapsLines = 0; };

View File

@ -77,8 +77,7 @@ void Parser::TraceListener::exitEveryRule(ParserRuleContext *ctx) {
<< ", LT(1)=" << outerInstance->_input->LT(1)->getText() << std::endl; << ", LT(1)=" << outerInstance->_input->LT(1)->getText() << std::endl;
} }
const Ref<Parser::TrimToSizeListener> Parser::TrimToSizeListener::INSTANCE = Parser::TrimToSizeListener Parser::TrimToSizeListener::INSTANCE;
std::make_shared<Parser::TrimToSizeListener>();
void Parser::TrimToSizeListener::enterEveryRule(ParserRuleContext * /*ctx*/) { void Parser::TrimToSizeListener::enterEveryRule(ParserRuleContext * /*ctx*/) {
} }
@ -99,6 +98,7 @@ Parser::Parser(TokenStream *input) {
} }
Parser::~Parser() { Parser::~Parser() {
delete _tracer;
} }
void Parser::reset() { void Parser::reset() {
@ -166,21 +166,21 @@ void Parser::setTrimParseTree(bool trimParseTrees) {
if (getTrimParseTree()) { if (getTrimParseTree()) {
return; return;
} }
addParseListener(TrimToSizeListener::INSTANCE); addParseListener(&TrimToSizeListener::INSTANCE);
} else { } else {
removeParseListener(TrimToSizeListener::INSTANCE); removeParseListener(&TrimToSizeListener::INSTANCE);
} }
} }
bool Parser::getTrimParseTree() { bool Parser::getTrimParseTree() {
return std::find(getParseListeners().begin(), getParseListeners().end(), TrimToSizeListener::INSTANCE) != getParseListeners().end(); return std::find(getParseListeners().begin(), getParseListeners().end(), &TrimToSizeListener::INSTANCE) != getParseListeners().end();
} }
std::vector<Ref<tree::ParseTreeListener>> Parser::getParseListeners() { std::vector<tree::ParseTreeListener *> Parser::getParseListeners() {
return _parseListeners; return _parseListeners;
} }
void Parser::addParseListener(Ref<tree::ParseTreeListener> const& listener) { void Parser::addParseListener(tree::ParseTreeListener *listener) {
if (!listener) { if (!listener) {
throw NullPointerException("listener"); throw NullPointerException("listener");
} }
@ -188,7 +188,7 @@ void Parser::addParseListener(Ref<tree::ParseTreeListener> const& listener) {
this->_parseListeners.push_back(listener); this->_parseListeners.push_back(listener);
} }
void Parser::removeParseListener(Ref<tree::ParseTreeListener> const& listener) { void Parser::removeParseListener(tree::ParseTreeListener *listener) {
if (!_parseListeners.empty()) { if (!_parseListeners.empty()) {
auto it = std::find(_parseListeners.begin(), _parseListeners.end(), listener); auto it = std::find(_parseListeners.begin(), _parseListeners.end(), listener);
if (it != _parseListeners.end()) { if (it != _parseListeners.end()) {
@ -627,11 +627,12 @@ void Parser::setTrace(bool trace) {
if (!trace) { if (!trace) {
if (_tracer) if (_tracer)
removeParseListener(_tracer); removeParseListener(_tracer);
_tracer.reset(); delete _tracer;
_tracer = nullptr;
} else { } else {
if (_tracer) if (_tracer)
removeParseListener(_tracer); // Just in case this is triggered multiple times. removeParseListener(_tracer); // Just in case this is triggered multiple times.
_tracer = std::make_shared<TraceListener>(this); _tracer = new TraceListener(this);
addParseListener(_tracer); addParseListener(_tracer);
} }
} }
@ -648,5 +649,6 @@ void Parser::InitializeInstanceFields() {
_syntaxErrors = 0; _syntaxErrors = 0;
_matchedEOF = false; _matchedEOF = false;
_input = nullptr; _input = nullptr;
_tracer = nullptr;
} }

View File

@ -59,7 +59,7 @@ namespace antlr4 {
class TrimToSizeListener : public tree::ParseTreeListener { class TrimToSizeListener : public tree::ParseTreeListener {
public: public:
static const Ref<TrimToSizeListener> INSTANCE; static TrimToSizeListener INSTANCE;
virtual ~TrimToSizeListener() {}; virtual ~TrimToSizeListener() {};
@ -149,7 +149,7 @@ namespace antlr4 {
/// using the default <seealso cref="Parser.TrimToSizeListener"/> during the parse process. </returns> /// using the default <seealso cref="Parser.TrimToSizeListener"/> during the parse process. </returns>
virtual bool getTrimParseTree(); virtual bool getTrimParseTree();
virtual std::vector<Ref<tree::ParseTreeListener>> getParseListeners(); virtual std::vector<tree::ParseTreeListener *> getParseListeners();
/// <summary> /// <summary>
/// Registers {@code listener} to receive events during the parsing process. /// Registers {@code listener} to receive events during the parsing process.
@ -179,7 +179,7 @@ namespace antlr4 {
/// <param name="listener"> the listener to add /// <param name="listener"> the listener to add
/// </param> /// </param>
/// <exception cref="NullPointerException"> if {@code} listener is {@code null} </exception> /// <exception cref="NullPointerException"> if {@code} listener is {@code null} </exception>
virtual void addParseListener(Ref<tree::ParseTreeListener> const& listener); virtual void addParseListener(tree::ParseTreeListener *listener);
/// <summary> /// <summary>
/// Remove {@code listener} from the list of parse listeners. /// Remove {@code listener} from the list of parse listeners.
@ -190,7 +190,7 @@ namespace antlr4 {
/// <seealso cref= #addParseListener /// <seealso cref= #addParseListener
/// </seealso> /// </seealso>
/// <param name="listener"> the listener to remove </param> /// <param name="listener"> the listener to remove </param>
virtual void removeParseListener(Ref<tree::ParseTreeListener> const& listener); virtual void removeParseListener(tree::ParseTreeListener *listener);
/// <summary> /// <summary>
/// Remove all parse listeners. /// Remove all parse listeners.
@ -433,12 +433,10 @@ namespace antlr4 {
/// <seealso cref= #setBuildParseTree </seealso> /// <seealso cref= #setBuildParseTree </seealso>
bool _buildParseTrees; bool _buildParseTrees;
/// <summary>
/// The list of <seealso cref="ParseTreeListener"/> listeners registered to receive /// The list of <seealso cref="ParseTreeListener"/> listeners registered to receive
/// events during the parse. /// events during the parse.
/// </summary>
/// <seealso cref= #addParseListener </seealso> /// <seealso cref= #addParseListener </seealso>
std::vector<Ref<tree::ParseTreeListener>> _parseListeners; std::vector<tree::ParseTreeListener *> _parseListeners;
/// <summary> /// <summary>
/// The number of syntax errors reported during parsing. This value is /// The number of syntax errors reported during parsing. This value is
@ -463,7 +461,7 @@ namespace antlr4 {
/// later call to setTrace(false). The listener itself is /// later call to setTrace(false). The listener itself is
/// implemented as a parser listener so this field is not directly used by /// implemented as a parser listener so this field is not directly used by
/// other parser methods. /// other parser methods.
Ref<TraceListener> _tracer; TraceListener *_tracer;
void InitializeInstanceFields(); void InitializeInstanceFields();
}; };

View File

@ -58,10 +58,10 @@ ParserRuleContext::ParserRuleContext(std::weak_ptr<ParserRuleContext> parent, in
: RuleContext(parent, invokingStateNumber) { : RuleContext(parent, invokingStateNumber) {
} }
void ParserRuleContext::enterRule(Ref<tree::ParseTreeListener> const& /*listener*/) { void ParserRuleContext::enterRule(tree::ParseTreeListener * /*listener*/) {
} }
void ParserRuleContext::exitRule(Ref<tree::ParseTreeListener> const& /*listener*/) { void ParserRuleContext::exitRule(tree::ParseTreeListener * /*listener*/) {
} }
Ref<tree::TerminalNode> ParserRuleContext::addChild(Ref<tree::TerminalNode> const& t) { Ref<tree::TerminalNode> ParserRuleContext::addChild(Ref<tree::TerminalNode> const& t) {

View File

@ -110,8 +110,8 @@ namespace antlr4 {
// Double dispatch methods for listeners // Double dispatch methods for listeners
virtual void enterRule(Ref<tree::ParseTreeListener> const& listener); virtual void enterRule(tree::ParseTreeListener *listener);
virtual void exitRule(Ref<tree::ParseTreeListener> const& listener); virtual void exitRule(tree::ParseTreeListener *listener);
/// Does not set parent link; other add methods do that. /// Does not set parent link; other add methods do that.
virtual Ref<tree::TerminalNode> addChild(Ref<tree::TerminalNode> const& t); virtual Ref<tree::TerminalNode> addChild(Ref<tree::TerminalNode> const& t);

View File

@ -1026,12 +1026,12 @@ CaptureNextTokenTypeHeader(d) ::= "<! Required but unused. !>"
CaptureNextTokenType(d) ::= "<d.varName> = _input->LA(1);" CaptureNextTokenType(d) ::= "<d.varName> = _input->LA(1);"
ListenerDispatchMethodHeader(method) ::= << ListenerDispatchMethodHeader(method) ::= <<
virtual void <if (method.isEnter)>enter<else>exit<endif>Rule(Ref\<tree::ParseTreeListener> const& listener) override; virtual void <if (method.isEnter)>enter<else>exit<endif>Rule(tree::ParseTreeListener *listener) override;
>> >>
ListenerDispatchMethod(method) ::= << ListenerDispatchMethod(method) ::= <<
void <parser.name>::<struct.name>::<if (method.isEnter)>enter<else>exit<endif>Rule(Ref\<tree::ParseTreeListener> const& listener) { void <parser.name>::<struct.name>::<if (method.isEnter)>enter<else>exit<endif>Rule(tree::ParseTreeListener *listener) {
auto parserListener = std::dynamic_pointer_cast\<<parser.grammarName>Listener>(listener); auto parserListener = dynamic_cast\<<parser.grammarName>Listener *>(listener);
if (parserListener) if (parserListener != nullptr)
parserListener-><if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">(this); parserListener-><if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">(this);
} }
>> >>