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.
|
||||
|
||||
### 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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
>>
|
||||
|
|
Loading…
Reference in New Issue