forked from jasder/antlr
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:
parent
dd48c0fbd5
commit
4a7ec859aa
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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; };
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
>>
|
>>
|
||||||
|
|
Loading…
Reference in New Issue