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.
### 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.

View File

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

View File

@ -13,13 +13,13 @@ public class TestListeners extends BaseCppTest {
public void testBasic() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(491);
StringBuilder grammarBuilder = new StringBuilder(480);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::definitions {\n");
grammarBuilder.append("class LeafListener : public TBaseListener {\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(" }\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>"; };
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; };
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>"; };
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; };

View File

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

View File

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

View File

@ -58,10 +58,10 @@ ParserRuleContext::ParserRuleContext(std::weak_ptr<ParserRuleContext> parent, in
: 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) {

View File

@ -110,8 +110,8 @@ namespace antlr4 {
// Double dispatch methods for listeners
virtual void enterRule(Ref<tree::ParseTreeListener> const& listener);
virtual void exitRule(Ref<tree::ParseTreeListener> const& listener);
virtual void enterRule(tree::ParseTreeListener *listener);
virtual void exitRule(tree::ParseTreeListener *listener);
/// Does not set parent link; other add methods do that.
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);"
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) ::= <<
void <parser.name>::<struct.name>::<if (method.isEnter)>enter<else>exit<endif>Rule(Ref\<tree::ParseTreeListener> const& listener) {
auto parserListener = std::dynamic_pointer_cast\<<parser.grammarName>Listener>(listener);
if (parserListener)
void <parser.name>::<struct.name>::<if (method.isEnter)>enter<else>exit<endif>Rule(tree::ParseTreeListener *listener) {
auto parserListener = dynamic_cast\<<parser.grammarName>Listener *>(listener);
if (parserListener != nullptr)
parserListener-><if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">(this);
}
>>