Another refactoring round.
- Removed a few unused classes. - More raw pointers to smart pointers conversion: RuleContext, ParserRuleContext, ParseTree, Token, ParseTreeWalker, Tree... - BitSet is now used directly instead of all those dynamic allocations and is a derived class instead of a composite. - Replced ATNState equals with == operator overload. - Correct wrong iterator over ATNConfigsets. - Added utilitiy function that mimics Java's generic toString().
This commit is contained in:
parent
6f344b376b
commit
eb0241f767
|
@ -20,26 +20,31 @@ using namespace org::antlr::v4::runtime;
|
|||
|
||||
int main(int argc, const char * argv[]) {
|
||||
|
||||
/*
|
||||
ANTLRInputStream input(L"<foo><conquer>");
|
||||
ANTLRInputStream input(L"a");
|
||||
TLexer lexer(&input);
|
||||
CommonTokenStream tokens(&lexer);
|
||||
|
||||
TParser parser(&tokens);
|
||||
std::shared_ptr<tree::ParseTree> tree = parser.main();
|
||||
std::wcout << tree->toStringTree(&parser);
|
||||
*/
|
||||
|
||||
ANTLRInputStream input(L"ab");
|
||||
TestLexer lexer(&input);
|
||||
CommonTokenStream tokens(&lexer);
|
||||
for (auto token : tokens.getTokens()) {
|
||||
std::cout << token << std::endl;
|
||||
std::wcout << token->toString() << std::endl;
|
||||
}
|
||||
std::wcout << tree->toStringTree(&parser);
|
||||
|
||||
/*
|
||||
ANTLRInputStream input(L"1");
|
||||
TLexer lexer(&input);
|
||||
CommonTokenStream tokens(&lexer);
|
||||
|
||||
TParser parser(&tokens);
|
||||
std::shared_ptr<tree::ParseTree> tree = parser.main();
|
||||
|
||||
for (auto token : tokens.getTokens()) {
|
||||
std::wcout << token->toString() << std::endl;
|
||||
}
|
||||
|
||||
TestParser parser(&tokens);
|
||||
std::shared_ptr<tree::ParseTree> tree = parser.main();
|
||||
std::wcout << tree->toStringTree(&parser);
|
||||
|
||||
std::wcout << tree->toStringTree(&parser) << std::endl;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -375,10 +375,6 @@
|
|||
27C6687A1C9584B60021E494 /* LexerDFASerializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C6686B1C9584B60021E494 /* LexerDFASerializer.cpp */; };
|
||||
27C6687B1C9584B60021E494 /* LexerDFASerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 27C6686C1C9584B60021E494 /* LexerDFASerializer.h */; };
|
||||
27C6687C1C9584B60021E494 /* LexerDFASerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 27C6686C1C9584B60021E494 /* LexerDFASerializer.h */; };
|
||||
27C668AA1C9584FA0021E494 /* EqualityComparator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C668841C9584FA0021E494 /* EqualityComparator.cpp */; };
|
||||
27C668AB1C9584FA0021E494 /* EqualityComparator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C668841C9584FA0021E494 /* EqualityComparator.cpp */; };
|
||||
27C668AC1C9584FA0021E494 /* EqualityComparator.h in Headers */ = {isa = PBXBuildFile; fileRef = 27C668851C9584FA0021E494 /* EqualityComparator.h */; };
|
||||
27C668AD1C9584FA0021E494 /* EqualityComparator.h in Headers */ = {isa = PBXBuildFile; fileRef = 27C668851C9584FA0021E494 /* EqualityComparator.h */; };
|
||||
27C668B21C9584FA0021E494 /* Interval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C668881C9584FA0021E494 /* Interval.cpp */; };
|
||||
27C668B31C9584FA0021E494 /* Interval.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C668881C9584FA0021E494 /* Interval.cpp */; };
|
||||
27C668B41C9584FA0021E494 /* Interval.h in Headers */ = {isa = PBXBuildFile; fileRef = 27C668891C9584FA0021E494 /* Interval.h */; };
|
||||
|
@ -572,8 +568,8 @@
|
|||
27C6666B1C9584050021E494 /* CharStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CharStream.h; path = ../../runtime/CharStream.h; sourceTree = SOURCE_ROOT; };
|
||||
27C6666C1C9584050021E494 /* CommonToken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommonToken.cpp; path = ../../runtime/CommonToken.cpp; sourceTree = SOURCE_ROOT; };
|
||||
27C6666D1C9584050021E494 /* CommonToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommonToken.h; path = ../../runtime/CommonToken.h; sourceTree = SOURCE_ROOT; };
|
||||
27C6666E1C9584050021E494 /* CommonTokenFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommonTokenFactory.cpp; path = ../../runtime/CommonTokenFactory.cpp; sourceTree = SOURCE_ROOT; };
|
||||
27C6666F1C9584050021E494 /* CommonTokenFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommonTokenFactory.h; path = ../../runtime/CommonTokenFactory.h; sourceTree = SOURCE_ROOT; };
|
||||
27C6666E1C9584050021E494 /* CommonTokenFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommonTokenFactory.cpp; path = ../../runtime/CommonTokenFactory.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C6666F1C9584050021E494 /* CommonTokenFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommonTokenFactory.h; path = ../../runtime/CommonTokenFactory.h; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C666701C9584050021E494 /* CommonTokenStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommonTokenStream.cpp; path = ../../runtime/CommonTokenStream.cpp; sourceTree = SOURCE_ROOT; };
|
||||
27C666711C9584050021E494 /* CommonTokenStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommonTokenStream.h; path = ../../runtime/CommonTokenStream.h; sourceTree = SOURCE_ROOT; };
|
||||
27C666721C9584050021E494 /* ConsoleErrorListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConsoleErrorListener.cpp; path = ../../runtime/ConsoleErrorListener.cpp; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -586,7 +582,7 @@
|
|||
27C666791C9584050021E494 /* Exceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Exceptions.h; path = ../../runtime/Exceptions.h; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C6667A1C9584050021E494 /* FailedPredicateException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FailedPredicateException.cpp; path = ../../runtime/FailedPredicateException.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C6667B1C9584050021E494 /* FailedPredicateException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FailedPredicateException.h; path = ../../runtime/FailedPredicateException.h; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C6667D1C9584050021E494 /* InputMismatchException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputMismatchException.cpp; path = ../../runtime/InputMismatchException.cpp; sourceTree = SOURCE_ROOT; };
|
||||
27C6667D1C9584050021E494 /* InputMismatchException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputMismatchException.cpp; path = ../../runtime/InputMismatchException.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C6667E1C9584050021E494 /* InputMismatchException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InputMismatchException.h; path = ../../runtime/InputMismatchException.h; sourceTree = SOURCE_ROOT; };
|
||||
27C6667F1C9584050021E494 /* InterpreterRuleContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InterpreterRuleContext.cpp; path = ../../runtime/InterpreterRuleContext.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C666801C9584050021E494 /* InterpreterRuleContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InterpreterRuleContext.h; path = ../../runtime/InterpreterRuleContext.h; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -603,12 +599,12 @@
|
|||
27C6668B1C9584050021E494 /* ListTokenSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ListTokenSource.h; path = ../../runtime/ListTokenSource.h; sourceTree = SOURCE_ROOT; };
|
||||
27C6668C1C9584050021E494 /* NoViableAltException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NoViableAltException.cpp; path = ../../runtime/NoViableAltException.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C6668D1C9584050021E494 /* NoViableAltException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NoViableAltException.h; path = ../../runtime/NoViableAltException.h; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C6668E1C9584050021E494 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Parser.cpp; path = ../../runtime/Parser.cpp; sourceTree = SOURCE_ROOT; };
|
||||
27C6668F1C9584050021E494 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = ../../runtime/Parser.h; sourceTree = SOURCE_ROOT; };
|
||||
27C6668E1C9584050021E494 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Parser.cpp; path = ../../runtime/Parser.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C6668F1C9584050021E494 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = ../../runtime/Parser.h; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C666901C9584050021E494 /* ParserInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParserInterpreter.cpp; path = ../../runtime/ParserInterpreter.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C666911C9584050021E494 /* ParserInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParserInterpreter.h; path = ../../runtime/ParserInterpreter.h; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C666921C9584050021E494 /* ParserRuleContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParserRuleContext.cpp; path = ../../runtime/ParserRuleContext.cpp; sourceTree = SOURCE_ROOT; };
|
||||
27C666931C9584050021E494 /* ParserRuleContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParserRuleContext.h; path = ../../runtime/ParserRuleContext.h; sourceTree = SOURCE_ROOT; };
|
||||
27C666921C9584050021E494 /* ParserRuleContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParserRuleContext.cpp; path = ../../runtime/ParserRuleContext.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C666931C9584050021E494 /* ParserRuleContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParserRuleContext.h; path = ../../runtime/ParserRuleContext.h; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C666941C9584050021E494 /* ProxyErrorListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProxyErrorListener.cpp; path = ../../runtime/ProxyErrorListener.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C666951C9584050021E494 /* ProxyErrorListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProxyErrorListener.h; path = ../../runtime/ProxyErrorListener.h; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
27C666961C9584050021E494 /* RecognitionException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecognitionException.cpp; path = ../../runtime/RecognitionException.cpp; sourceTree = SOURCE_ROOT; wrapsLines = 0; };
|
||||
|
@ -733,8 +729,6 @@
|
|||
27C6686A1C9584B60021E494 /* DFAState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFAState.h; sourceTree = "<group>"; };
|
||||
27C6686B1C9584B60021E494 /* LexerDFASerializer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LexerDFASerializer.cpp; sourceTree = "<group>"; };
|
||||
27C6686C1C9584B60021E494 /* LexerDFASerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LexerDFASerializer.h; sourceTree = "<group>"; };
|
||||
27C668841C9584FA0021E494 /* EqualityComparator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EqualityComparator.cpp; sourceTree = "<group>"; };
|
||||
27C668851C9584FA0021E494 /* EqualityComparator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EqualityComparator.h; sourceTree = "<group>"; };
|
||||
27C668881C9584FA0021E494 /* Interval.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Interval.cpp; sourceTree = "<group>"; };
|
||||
27C668891C9584FA0021E494 /* Interval.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Interval.h; sourceTree = "<group>"; };
|
||||
27C6688A1C9584FA0021E494 /* IntervalSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntervalSet.cpp; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
|
@ -760,7 +754,7 @@
|
|||
27C669731C9585B80021E494 /* ErrorNodeImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorNodeImpl.cpp; sourceTree = "<group>"; };
|
||||
27C669741C9585B80021E494 /* ErrorNodeImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ErrorNodeImpl.h; sourceTree = "<group>"; };
|
||||
27C669751C9585B80021E494 /* ParseTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseTree.cpp; sourceTree = "<group>"; };
|
||||
27C669761C9585B80021E494 /* ParseTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseTree.h; sourceTree = "<group>"; };
|
||||
27C669761C9585B80021E494 /* ParseTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseTree.h; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
27C669771C9585B80021E494 /* ParseTreeListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseTreeListener.cpp; sourceTree = "<group>"; };
|
||||
27C669781C9585B80021E494 /* ParseTreeListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseTreeListener.h; sourceTree = "<group>"; };
|
||||
27C669791C9585B80021E494 /* ParseTreeProperty.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseTreeProperty.cpp; sourceTree = "<group>"; };
|
||||
|
@ -783,7 +777,7 @@
|
|||
27C6698A1C9585B80021E494 /* Trees.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Trees.h; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
27C669F01C958AB30021E494 /* Chunk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Chunk.cpp; path = pattern/Chunk.cpp; sourceTree = "<group>"; };
|
||||
27C669F11C958AB30021E494 /* ParseTreeMatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParseTreeMatch.cpp; path = pattern/ParseTreeMatch.cpp; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
27C669F21C958AB30021E494 /* ParseTreePattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParseTreePattern.cpp; path = pattern/ParseTreePattern.cpp; sourceTree = "<group>"; };
|
||||
27C669F21C958AB30021E494 /* ParseTreePattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParseTreePattern.cpp; path = pattern/ParseTreePattern.cpp; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
27C669F31C958AB30021E494 /* ParseTreePatternMatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParseTreePatternMatcher.cpp; path = pattern/ParseTreePatternMatcher.cpp; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
27C669F41C958AB30021E494 /* RuleTagToken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RuleTagToken.cpp; path = pattern/RuleTagToken.cpp; sourceTree = "<group>"; };
|
||||
27C669F51C958AB30021E494 /* TagChunk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TagChunk.cpp; path = pattern/TagChunk.cpp; sourceTree = "<group>"; };
|
||||
|
@ -791,7 +785,7 @@
|
|||
27C669F71C958AB30021E494 /* TokenTagToken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TokenTagToken.cpp; path = pattern/TokenTagToken.cpp; sourceTree = "<group>"; };
|
||||
27C669F81C958AB30021E494 /* Chunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Chunk.h; path = pattern/Chunk.h; sourceTree = "<group>"; };
|
||||
27C669F91C958AB30021E494 /* ParseTreeMatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParseTreeMatch.h; path = pattern/ParseTreeMatch.h; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
27C669FA1C958AB30021E494 /* ParseTreePattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParseTreePattern.h; path = pattern/ParseTreePattern.h; sourceTree = "<group>"; };
|
||||
27C669FA1C958AB30021E494 /* ParseTreePattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParseTreePattern.h; path = pattern/ParseTreePattern.h; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
27C669FB1C958AB30021E494 /* ParseTreePatternMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParseTreePatternMatcher.h; path = pattern/ParseTreePatternMatcher.h; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
27C669FC1C958AB30021E494 /* RuleTagToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RuleTagToken.h; path = pattern/RuleTagToken.h; sourceTree = "<group>"; };
|
||||
27C669FD1C958AB30021E494 /* TagChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TagChunk.h; path = pattern/TagChunk.h; sourceTree = "<group>"; };
|
||||
|
@ -1003,8 +997,6 @@
|
|||
27C6687D1C9584E90021E494 /* misc */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
27C668841C9584FA0021E494 /* EqualityComparator.cpp */,
|
||||
27C668851C9584FA0021E494 /* EqualityComparator.h */,
|
||||
27C668881C9584FA0021E494 /* Interval.cpp */,
|
||||
27C668891C9584FA0021E494 /* Interval.h */,
|
||||
27C6688A1C9584FA0021E494 /* IntervalSet.cpp */,
|
||||
|
@ -1357,7 +1349,6 @@
|
|||
27C667BD1C95846E0021E494 /* ATNConfigSet.h in Headers */,
|
||||
27C667F51C95846E0021E494 /* EpsilonTransition.h in Headers */,
|
||||
27C667F91C95846E0021E494 /* LexerATNConfig.h in Headers */,
|
||||
27C668AD1C9584FA0021E494 /* EqualityComparator.h in Headers */,
|
||||
27C669031C9585230021E494 /* BitSet.h in Headers */,
|
||||
27C6673B1C9584050021E494 /* TokenStreamRewriter.h in Headers */,
|
||||
27C668171C95846E0021E494 /* PlusBlockStartState.h in Headers */,
|
||||
|
@ -1479,7 +1470,6 @@
|
|||
27C6685A1C95846E0021E494 /* TokensStartState.h in Headers */,
|
||||
27C668561C95846E0021E494 /* StarLoopEntryState.h in Headers */,
|
||||
27C667B41C95846E0021E494 /* ATN.h in Headers */,
|
||||
27C668AC1C9584FA0021E494 /* EqualityComparator.h in Headers */,
|
||||
27C669AD1C9585B80021E494 /* RuleNode.h in Headers */,
|
||||
27C668771C9584B60021E494 /* DFAState.h in Headers */,
|
||||
27C6680A1C95846E0021E494 /* NotSetTransition.h in Headers */,
|
||||
|
@ -1749,7 +1739,6 @@
|
|||
27C668351C95846E0021E494 /* RuleStartState.cpp in Sources */,
|
||||
27C66A0B1C958AB30021E494 /* TagChunk.cpp in Sources */,
|
||||
272415E51CB54C09007E056A /* UnbufferedTokenStream.cpp in Sources */,
|
||||
27C668AB1C9584FA0021E494 /* EqualityComparator.cpp in Sources */,
|
||||
27C666FF1C9584050021E494 /* LexerInterpreter.cpp in Sources */,
|
||||
27C667FF1C95846E0021E494 /* LL1Analyzer.cpp in Sources */,
|
||||
27C6673D1C9584050021E494 /* UnbufferedCharStream.cpp in Sources */,
|
||||
|
@ -1819,7 +1808,6 @@
|
|||
27C666B61C9584050021E494 /* ANTLRInputStream.cpp in Sources */,
|
||||
27C666F41C9584050021E494 /* IntStream.cpp in Sources */,
|
||||
27C667D61C95846E0021E494 /* AtomTransition.cpp in Sources */,
|
||||
27C668AA1C9584FA0021E494 /* EqualityComparator.cpp in Sources */,
|
||||
27C667E21C95846E0021E494 /* BlockEndState.cpp in Sources */,
|
||||
27C669BB1C9585B80021E494 /* Tree.cpp in Sources */,
|
||||
27C6673C1C9584050021E494 /* UnbufferedCharStream.cpp in Sources */,
|
||||
|
|
|
@ -41,6 +41,7 @@ fragment LETTER : [a-zA-Z\u0080-\u00FF_] ;
|
|||
LessThan: '<' -> pushMode(Mode1);
|
||||
GreaterThan: '>' -> popMode;
|
||||
Equal: '=';
|
||||
And: 'and';
|
||||
|
||||
Colon: ':';
|
||||
Semicolon: ';';
|
||||
|
|
|
@ -45,13 +45,13 @@ void doAfter() {
|
|||
}
|
||||
|
||||
main: divide and_? conquer;
|
||||
divide : LessThan and_ GreaterThan {doesItBlend()}?;
|
||||
and_ @init{ doInit(); } @after { doAfter(); } : ID ;
|
||||
divide : ID (and_ GreaterThan)? {doesItBlend()}?;
|
||||
and_ @init{ doInit(); } @after { doAfter(); } : And ;
|
||||
|
||||
conquer:
|
||||
divide+
|
||||
| {doesItBlend()}? and_ { myAction(); }
|
||||
| conquer LessThan* divide
|
||||
| ID (LessThan* divide)??
|
||||
;
|
||||
|
||||
// Unused rule to demonstrate some of the special features.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
grammar Test;
|
||||
|
||||
main: ID;
|
||||
main: ID ID;
|
||||
|
||||
ID: [a..z]+;
|
||||
ID: [a-z]+;
|
||||
|
|
|
@ -28,7 +28,7 @@ CLASSPATH=../../../tool/resources/:ST-4.0.8.jar:../../../tool/target/classes:../
|
|||
|
||||
# Minimal lexer + parser.
|
||||
java -cp $CLASSPATH org.antlr.v4.Tool -Dlanguage=Cpp -no-listener -no-visitor -o generated/ -package antlrcpptest Test.g4
|
||||
#java -cp $CLASSPATH org.antlr.v4.Tool -Dlanguage=Java -listener -visitor -o generated/ Test.g4
|
||||
java -cp $CLASSPATH org.antlr.v4.Tool -Dlanguage=Java -listener -visitor -o generated/ Test.g4
|
||||
|
||||
# A more complete lexer/parser set + listeners.
|
||||
java -cp $CLASSPATH org.antlr.v4.Tool -Dlanguage=Cpp -listener -visitor -o generated/ -package antlrcpptest TLexer.g4 TParser.g4
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace runtime {
|
|||
/// the reporting of an error. It is null in the case where
|
||||
/// the parser was able to recover in line without exiting the
|
||||
/// surrounding rule. </param>
|
||||
virtual void syntaxError(IRecognizer *recognizer, Token *offendingSymbol, size_t line, int charPositionInLine,
|
||||
virtual void syntaxError(IRecognizer *recognizer, TokenRef offendingSymbol, size_t line, int charPositionInLine,
|
||||
const std::wstring &msg, std::exception_ptr e) = 0;
|
||||
|
||||
/// <summary>
|
||||
|
@ -108,7 +108,7 @@ namespace runtime {
|
|||
/// <param name="configs"> the ATN configuration set where the ambiguity was
|
||||
/// determined </param>
|
||||
virtual void reportAmbiguity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex, bool exact,
|
||||
antlrcpp::BitSet *ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) = 0;
|
||||
const antlrcpp::BitSet &ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// This method is called when an SLL conflict occurs and the parser is about
|
||||
|
@ -131,7 +131,7 @@ namespace runtime {
|
|||
/// <param name="configs"> the ATN configuration set where the SLL conflict was
|
||||
/// detected </param>
|
||||
virtual void reportAttemptingFullContext(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
antlrcpp::BitSet *conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) = 0;
|
||||
const antlrcpp::BitSet &conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by the parser when a full-context prediction has a
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace runtime {
|
|||
/// <param name="recognizer"> the parser instance </param>
|
||||
/// <exception cref="RecognitionException"> if the error strategy was not able to
|
||||
/// recover from the unexpected input symbol </exception>
|
||||
virtual Token *recoverInline(Parser *recognizer) = 0;
|
||||
virtual TokenRef recoverInline(Parser *recognizer) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// This method is called to recover from exception {@code e}. This method is
|
||||
|
|
|
@ -40,9 +40,13 @@ using namespace org::antlr::v4::runtime;
|
|||
|
||||
void BailErrorStrategy::recover(Parser *recognizer, const RecognitionException &e) {
|
||||
std::exception_ptr exception = std::make_exception_ptr(e);
|
||||
for (ParserRuleContext *context = recognizer->getContext(); context != nullptr; context = context->getParent()) {
|
||||
ParserRuleContextRef context = recognizer->getContext();
|
||||
do {
|
||||
context->exception = exception;
|
||||
}
|
||||
if (context->getParent().expired())
|
||||
break;
|
||||
context = context->getParent().lock();
|
||||
} while (true);
|
||||
|
||||
try {
|
||||
std::rethrow_exception(exception); // Throw the exception to be able to catch and rethrow nested.
|
||||
|
@ -51,14 +55,17 @@ void BailErrorStrategy::recover(Parser *recognizer, const RecognitionException &
|
|||
}
|
||||
}
|
||||
|
||||
Token *BailErrorStrategy::recoverInline(Parser *recognizer) {
|
||||
|
||||
TokenRef BailErrorStrategy::recoverInline(Parser *recognizer) {
|
||||
InputMismatchException e(recognizer);
|
||||
for (ParserRuleContext *context = recognizer->getContext();
|
||||
context != nullptr;
|
||||
context = context->getParent()) {
|
||||
context->exception = std::make_exception_ptr(e);
|
||||
}
|
||||
std::exception_ptr exception = std::make_exception_ptr(e);
|
||||
|
||||
ParserRuleContextRef context = recognizer->getContext();
|
||||
do {
|
||||
context->exception = exception;
|
||||
if (context->getParent().expired())
|
||||
break;
|
||||
context = context->getParent().lock();
|
||||
} while (true);
|
||||
|
||||
try {
|
||||
throw e;
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace runtime {
|
|||
/// Make sure we don't attempt to recover inline; if the parser
|
||||
/// successfully recovers, it won't throw an exception.
|
||||
/// </summary>
|
||||
virtual Token *recoverInline(Parser *recognizer) override;
|
||||
virtual TokenRef recoverInline(Parser *recognizer) override;
|
||||
|
||||
/// <summary>
|
||||
/// Make sure we don't attempt to recover from problems in subrules. </summary>
|
||||
|
|
|
@ -34,16 +34,16 @@
|
|||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
void BaseErrorListener::syntaxError(IRecognizer *recognizer, Token *offendingSymbol, size_t line, int charPositionInLine,
|
||||
void BaseErrorListener::syntaxError(IRecognizer *recognizer, TokenRef offendingSymbol, size_t line, int charPositionInLine,
|
||||
const std::wstring &msg, std::exception_ptr e) {
|
||||
}
|
||||
|
||||
void BaseErrorListener::reportAmbiguity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
bool exact, antlrcpp::BitSet *ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
bool exact, const antlrcpp::BitSet &ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
}
|
||||
|
||||
void BaseErrorListener::reportAttemptingFullContext(Parser *recognizer, dfa::DFA *dfa, size_t startIndex,
|
||||
size_t stopIndex, antlrcpp::BitSet *conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
size_t stopIndex, const antlrcpp::BitSet &conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
}
|
||||
|
||||
void BaseErrorListener::reportContextSensitivity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
|
|
|
@ -44,14 +44,14 @@ namespace runtime {
|
|||
|
||||
class BaseErrorListener : public ANTLRErrorListener {
|
||||
|
||||
virtual void syntaxError(IRecognizer *recognizer, Token *offendingSymbol, size_t line, int charPositionInLine,
|
||||
virtual void syntaxError(IRecognizer *recognizer, TokenRef offendingSymbol, size_t line, int charPositionInLine,
|
||||
const std::wstring &msg, std::exception_ptr e) override;
|
||||
|
||||
virtual void reportAmbiguity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex, bool exact,
|
||||
antlrcpp::BitSet *ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
const antlrcpp::BitSet &ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
|
||||
virtual void reportAttemptingFullContext(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
antlrcpp::BitSet *conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
const antlrcpp::BitSet &conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
|
||||
virtual void reportContextSensitivity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
int prediction, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
|
|
|
@ -34,25 +34,23 @@
|
|||
#include "RuleContext.h"
|
||||
#include "Interval.h"
|
||||
#include "Exceptions.h"
|
||||
#include "CPPUtils.h"
|
||||
|
||||
#include "BufferedTokenStream.h"
|
||||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
using namespace antlrcpp;
|
||||
|
||||
BufferedTokenStream::BufferedTokenStream(TokenSource *tokenSource) {
|
||||
BufferedTokenStream::BufferedTokenStream(TokenSource *tokenSource) : _tokenSource(tokenSource){
|
||||
InitializeInstanceFields();
|
||||
if (tokenSource == nullptr) {
|
||||
throw NullPointerException("tokenSource cannot be null");
|
||||
}
|
||||
this->tokenSource = tokenSource;
|
||||
}
|
||||
|
||||
TokenSource *BufferedTokenStream::getTokenSource() const {
|
||||
return tokenSource;
|
||||
TokenSource* BufferedTokenStream::getTokenSource() const {
|
||||
return _tokenSource;
|
||||
}
|
||||
|
||||
size_t BufferedTokenStream::index() {
|
||||
return p;
|
||||
return _p;
|
||||
}
|
||||
|
||||
ssize_t BufferedTokenStream::mark() {
|
||||
|
@ -69,11 +67,11 @@ void BufferedTokenStream::reset() {
|
|||
|
||||
void BufferedTokenStream::seek(size_t index) {
|
||||
lazyInit();
|
||||
p = adjustSeekIndex(index);
|
||||
_p = adjustSeekIndex(index);
|
||||
}
|
||||
|
||||
size_t BufferedTokenStream::size() {
|
||||
return tokens.size();
|
||||
return _tokens.size();
|
||||
}
|
||||
|
||||
void BufferedTokenStream::consume() {
|
||||
|
@ -81,13 +79,13 @@ void BufferedTokenStream::consume() {
|
|||
throw IllegalStateException("cannot consume EOF");
|
||||
}
|
||||
|
||||
if (sync(p + 1)) {
|
||||
p = adjustSeekIndex(p + 1);
|
||||
if (sync(_p + 1)) {
|
||||
_p = adjustSeekIndex(_p + 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool BufferedTokenStream::sync(size_t i) {
|
||||
size_t n = i - tokens.size() + 1; // how many more elements we need?
|
||||
size_t n = i - _tokens.size() + 1; // how many more elements we need?
|
||||
|
||||
if (n > 0) {
|
||||
size_t fetched = fetch(n);
|
||||
|
@ -98,18 +96,18 @@ bool BufferedTokenStream::sync(size_t i) {
|
|||
}
|
||||
|
||||
size_t BufferedTokenStream::fetch(size_t n) {
|
||||
if (fetchedEOF) {
|
||||
if (_fetchedEOF) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
Token *t = tokenSource->nextToken();
|
||||
if (dynamic_cast<WritableToken*>(t) != nullptr) {
|
||||
(static_cast<WritableToken*>(t))->setTokenIndex((int)tokens.size());
|
||||
TokenRef t = _tokenSource->nextToken();
|
||||
if (is<WritableToken>(t)) {
|
||||
(std::dynamic_pointer_cast<WritableToken>(t))->setTokenIndex((int)_tokens.size());
|
||||
}
|
||||
tokens.push_back(t);
|
||||
_tokens.push_back(t);
|
||||
if (t->getType() == EOF) {
|
||||
fetchedEOF = true;
|
||||
_fetchedEOF = true;
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
@ -117,30 +115,30 @@ size_t BufferedTokenStream::fetch(size_t n) {
|
|||
return n;
|
||||
}
|
||||
|
||||
Token *BufferedTokenStream::get(size_t i) const {
|
||||
if (i >= tokens.size()) {
|
||||
TokenRef BufferedTokenStream::get(size_t i) const {
|
||||
if (i >= _tokens.size()) {
|
||||
throw IndexOutOfBoundsException(std::string("token index ") +
|
||||
std::to_string(i) +
|
||||
std::string(" out of range 0..") +
|
||||
std::to_string(tokens.size() - 1));
|
||||
std::to_string(_tokens.size() - 1));
|
||||
}
|
||||
return tokens[i];
|
||||
return _tokens[i];
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::get(size_t start, size_t stop) {
|
||||
std::vector<Token*> subset;
|
||||
std::vector<TokenRef> BufferedTokenStream::get(size_t start, size_t stop) {
|
||||
std::vector<TokenRef> subset;
|
||||
|
||||
lazyInit();
|
||||
|
||||
if (tokens.empty()) {
|
||||
if (_tokens.empty()) {
|
||||
return subset;
|
||||
}
|
||||
|
||||
if (stop >= tokens.size()) {
|
||||
stop = tokens.size() - 1;
|
||||
if (stop >= _tokens.size()) {
|
||||
stop = _tokens.size() - 1;
|
||||
}
|
||||
for (size_t i = start; i <= stop; i++) {
|
||||
Token *t = tokens[i];
|
||||
TokenRef t = _tokens[i];
|
||||
if (t->getType() == EOF) {
|
||||
break;
|
||||
}
|
||||
|
@ -153,14 +151,14 @@ ssize_t BufferedTokenStream::LA(ssize_t i) {
|
|||
return LT(i)->getType();
|
||||
}
|
||||
|
||||
Token *BufferedTokenStream::LB(size_t k) {
|
||||
if (k > p) {
|
||||
TokenRef BufferedTokenStream::LB(size_t k) {
|
||||
if (k > _p) {
|
||||
return nullptr;
|
||||
}
|
||||
return tokens[(size_t)(p - k)];
|
||||
return _tokens[(size_t)(_p - k)];
|
||||
}
|
||||
|
||||
Token *BufferedTokenStream::LT(ssize_t k) {
|
||||
TokenRef BufferedTokenStream::LT(ssize_t k) {
|
||||
lazyInit();
|
||||
if (k == 0) {
|
||||
return nullptr;
|
||||
|
@ -169,14 +167,14 @@ Token *BufferedTokenStream::LT(ssize_t k) {
|
|||
return LB((size_t)-k);
|
||||
}
|
||||
|
||||
size_t i = (size_t)((ssize_t)p + k - 1);
|
||||
size_t i = (size_t)((ssize_t)_p + k - 1);
|
||||
sync(i);
|
||||
if (i >= tokens.size()) { // return EOF token
|
||||
// EOF must be last token
|
||||
return tokens.back();
|
||||
if (i >= _tokens.size()) { // return EOF token
|
||||
// EOF must be last token
|
||||
return _tokens.back();
|
||||
}
|
||||
|
||||
return tokens[i];
|
||||
return _tokens[i];
|
||||
}
|
||||
|
||||
size_t BufferedTokenStream::adjustSeekIndex(size_t i) {
|
||||
|
@ -192,60 +190,55 @@ void BufferedTokenStream::lazyInit() {
|
|||
void BufferedTokenStream::setup() {
|
||||
_needSetup = false;
|
||||
sync(0);
|
||||
p = adjustSeekIndex(0);
|
||||
_p = adjustSeekIndex(0);
|
||||
}
|
||||
|
||||
void BufferedTokenStream::setTokenSource(TokenSource *tokenSource) {
|
||||
this->tokenSource = tokenSource;
|
||||
tokens.clear();
|
||||
_tokenSource = tokenSource;
|
||||
_tokens.clear();
|
||||
_needSetup = true;
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::getTokens() {
|
||||
return tokens;
|
||||
std::vector<TokenRef> BufferedTokenStream::getTokens() {
|
||||
return _tokens;
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::getTokens(int start, int stop) {
|
||||
return getTokens(start, stop, nullptr);
|
||||
std::vector<TokenRef> BufferedTokenStream::getTokens(int start, int stop) {
|
||||
return getTokens(start, stop, std::vector<int>());
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::getTokens(int start, int stop, std::vector<int> *types) {
|
||||
std::vector<TokenRef> BufferedTokenStream::getTokens(int start, int stop, const std::vector<int> &types) {
|
||||
lazyInit();
|
||||
if (start < 0 || stop >= (int)tokens.size() || stop < 0 || (int)start >= (int)tokens.size()) {
|
||||
if (start < 0 || stop >= (int)_tokens.size() || stop < 0 || start >= (int)_tokens.size()) {
|
||||
throw IndexOutOfBoundsException(std::string("start ") +
|
||||
std::to_string(start) +
|
||||
std::string(" or stop ") +
|
||||
std::to_string(stop) +
|
||||
std::string(" not in 0..") +
|
||||
std::to_string(tokens.size() - 1));
|
||||
std::to_string(_tokens.size() - 1));
|
||||
}
|
||||
|
||||
std::vector<TokenRef> filteredTokens;
|
||||
|
||||
if (start > stop) {
|
||||
return std::vector<Token*>();
|
||||
return filteredTokens;
|
||||
}
|
||||
|
||||
// list = tokens[start:stop]:{T t, t.getType() in types}
|
||||
std::vector<Token*> filteredTokens = std::vector<Token*>();
|
||||
for (size_t i = (size_t)start; i <= (size_t)stop; i++) {
|
||||
Token *tok = tokens[i];
|
||||
TokenRef tok = _tokens[i];
|
||||
|
||||
if (types == nullptr) {
|
||||
if (types.empty() || std::find(types.begin(), types.end(), tok->getType()) != types.end()) {
|
||||
filteredTokens.push_back(tok);
|
||||
} else {
|
||||
if (types == nullptr || std::find(types->begin(), types->end(), tok->getType()) != types->end()) {
|
||||
filteredTokens.push_back(tok);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filteredTokens.empty()) {
|
||||
filteredTokens.clear();
|
||||
}
|
||||
return filteredTokens;
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::getTokens(int start, int stop, int ttype) {
|
||||
std::vector<int> *s = new std::vector<int>();
|
||||
s->insert(s->begin(), ttype);
|
||||
return getTokens(start,stop, s);
|
||||
std::vector<TokenRef> BufferedTokenStream::getTokens(int start, int stop, int ttype) {
|
||||
std::vector<int> s;
|
||||
s.push_back(ttype);
|
||||
return getTokens(start, stop, s);
|
||||
}
|
||||
|
||||
ssize_t BufferedTokenStream::nextTokenOnChannel(size_t i, int channel) {
|
||||
|
@ -254,21 +247,21 @@ ssize_t BufferedTokenStream::nextTokenOnChannel(size_t i, int channel) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
Token *token = tokens[i];
|
||||
TokenRef token = _tokens[i];
|
||||
while (token->getChannel() != channel) {
|
||||
if (token->getType() == EOF) {
|
||||
return -1;
|
||||
}
|
||||
i++;
|
||||
sync(i);
|
||||
token = tokens[i];
|
||||
token = _tokens[i];
|
||||
}
|
||||
return (ssize_t)i;
|
||||
}
|
||||
|
||||
ssize_t BufferedTokenStream::previousTokenOnChannel(size_t i, int channel) const {
|
||||
do {
|
||||
if (tokens[i]->getChannel() == channel)
|
||||
if (_tokens[i]->getChannel() == channel)
|
||||
return (ssize_t)i;
|
||||
if (i == 0)
|
||||
return -1;
|
||||
|
@ -277,10 +270,10 @@ ssize_t BufferedTokenStream::previousTokenOnChannel(size_t i, int channel) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::getHiddenTokensToRight(size_t tokenIndex, int channel) {
|
||||
std::vector<TokenRef> BufferedTokenStream::getHiddenTokensToRight(size_t tokenIndex, int channel) {
|
||||
lazyInit();
|
||||
if (tokenIndex >= tokens.size()) {
|
||||
throw IndexOutOfBoundsException(std::to_string(tokenIndex) + " not in 0.." + std::to_string(tokens.size() - 1));
|
||||
if (tokenIndex >= _tokens.size()) {
|
||||
throw IndexOutOfBoundsException(std::to_string(tokenIndex) + " not in 0.." + std::to_string(_tokens.size() - 1));
|
||||
}
|
||||
|
||||
ssize_t nextOnChannel = nextTokenOnChannel(tokenIndex + 1, Lexer::DEFAULT_TOKEN_CHANNEL);
|
||||
|
@ -296,19 +289,19 @@ std::vector<Token*> BufferedTokenStream::getHiddenTokensToRight(size_t tokenInde
|
|||
return filterForChannel(from, (size_t)to, channel);
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::getHiddenTokensToRight(size_t tokenIndex) {
|
||||
std::vector<TokenRef> BufferedTokenStream::getHiddenTokensToRight(size_t tokenIndex) {
|
||||
return getHiddenTokensToRight(tokenIndex, -1);
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::getHiddenTokensToLeft(size_t tokenIndex, int channel) {
|
||||
std::vector<TokenRef> BufferedTokenStream::getHiddenTokensToLeft(size_t tokenIndex, int channel) {
|
||||
lazyInit();
|
||||
if (tokenIndex >= tokens.size()) {
|
||||
throw IndexOutOfBoundsException(std::to_string(tokenIndex) + " not in 0.." + std::to_string(tokens.size() - 1));
|
||||
if (tokenIndex >= _tokens.size()) {
|
||||
throw IndexOutOfBoundsException(std::to_string(tokenIndex) + " not in 0.." + std::to_string(_tokens.size() - 1));
|
||||
}
|
||||
|
||||
ssize_t prevOnChannel = previousTokenOnChannel(tokenIndex - 1, Lexer::DEFAULT_TOKEN_CHANNEL);
|
||||
if (prevOnChannel == (ssize_t)tokenIndex - 1) {
|
||||
return std::vector<Token*>();
|
||||
return std::vector<TokenRef>();
|
||||
}
|
||||
// if none onchannel to left, prevOnChannel=-1 then from=0
|
||||
size_t from = (size_t)(prevOnChannel + 1);
|
||||
|
@ -317,14 +310,14 @@ std::vector<Token*> BufferedTokenStream::getHiddenTokensToLeft(size_t tokenIndex
|
|||
return filterForChannel(from, to, channel);
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::getHiddenTokensToLeft(size_t tokenIndex) {
|
||||
std::vector<TokenRef> BufferedTokenStream::getHiddenTokensToLeft(size_t tokenIndex) {
|
||||
return getHiddenTokensToLeft(tokenIndex, -1);
|
||||
}
|
||||
|
||||
std::vector<Token*> BufferedTokenStream::filterForChannel(size_t from, size_t to, int channel) {
|
||||
std::vector<Token*> hidden = std::vector<Token*>();
|
||||
std::vector<TokenRef> BufferedTokenStream::filterForChannel(size_t from, size_t to, int channel) {
|
||||
std::vector<TokenRef> hidden;
|
||||
for (size_t i = from; i <= to; i++) {
|
||||
Token *t = tokens[i];
|
||||
TokenRef t = _tokens[i];
|
||||
if (channel == -1) {
|
||||
if (t->getChannel() != Lexer::DEFAULT_TOKEN_CHANNEL) {
|
||||
hidden.push_back(t);
|
||||
|
@ -335,9 +328,7 @@ std::vector<Token*> BufferedTokenStream::filterForChannel(size_t from, size_t to
|
|||
}
|
||||
}
|
||||
}
|
||||
if (hidden.empty()) {
|
||||
return std::vector<Token*>();
|
||||
}
|
||||
|
||||
return hidden;
|
||||
}
|
||||
|
||||
|
@ -346,7 +337,7 @@ std::vector<Token*> BufferedTokenStream::filterForChannel(size_t from, size_t to
|
|||
*/
|
||||
std::string BufferedTokenStream::getSourceName() const
|
||||
{
|
||||
return tokenSource->getSourceName();
|
||||
return _tokenSource->getSourceName();
|
||||
}
|
||||
|
||||
std::wstring BufferedTokenStream::getText() {
|
||||
|
@ -362,13 +353,13 @@ std::wstring BufferedTokenStream::getText(const misc::Interval &interval) {
|
|||
return L"";
|
||||
}
|
||||
lazyInit();
|
||||
if (stop >= (int)tokens.size()) {
|
||||
stop = (int)tokens.size() - 1;
|
||||
if (stop >= (int)_tokens.size()) {
|
||||
stop = (int)_tokens.size() - 1;
|
||||
}
|
||||
|
||||
std::wstringstream ss;
|
||||
for (size_t i = (size_t)start; i <= (size_t)stop; i++) {
|
||||
Token *t = tokens[i];
|
||||
TokenRef t = _tokens[i];
|
||||
if (t->getType() == EOF) {
|
||||
break;
|
||||
}
|
||||
|
@ -381,7 +372,7 @@ std::wstring BufferedTokenStream::getText(RuleContext *ctx) {
|
|||
return getText(ctx->getSourceInterval());
|
||||
}
|
||||
|
||||
std::wstring BufferedTokenStream::getText(Token *start, Token *stop) {
|
||||
std::wstring BufferedTokenStream::getText(TokenRef start, TokenRef stop) {
|
||||
if (start != nullptr && stop != nullptr) {
|
||||
return getText(misc::Interval(start->getTokenIndex(), stop->getTokenIndex()));
|
||||
}
|
||||
|
@ -401,7 +392,6 @@ void BufferedTokenStream::fill() {
|
|||
}
|
||||
|
||||
void BufferedTokenStream::InitializeInstanceFields() {
|
||||
tokens.reserve(100);
|
||||
_needSetup = true;
|
||||
fetchedEOF = false;
|
||||
_fetchedEOF = false;
|
||||
}
|
||||
|
|
|
@ -38,29 +38,95 @@ namespace antlr {
|
|||
namespace v4 {
|
||||
namespace runtime {
|
||||
|
||||
/// <summary>
|
||||
/// Buffer all input tokens but do on-demand fetching of new tokens from lexer.
|
||||
/// Useful when the parser or lexer has to set context/mode info before proper
|
||||
/// lexing of future tokens. The ST template parser needs this, for example,
|
||||
/// because it has to constantly flip back and forth between inside/output
|
||||
/// templates. E.g., {@code <names:{hi, <it>}>} has to parse names as part of an
|
||||
/// expression but {@code "hi, <it>"} as a nested template.
|
||||
/// <p/>
|
||||
/// templates. E.g., <names:{hi, <it>}> has to parse names as part of an
|
||||
/// expression but "hi, <it>" as a nested template.
|
||||
///
|
||||
/// You can't use this stream if you pass whitespace or other off-channel tokens
|
||||
/// to the parser. The stream can't ignore off-channel tokens.
|
||||
/// (<seealso cref="UnbufferedTokenStream"/> is the same way.) Use
|
||||
/// <seealso cref="CommonTokenStream"/>.
|
||||
/// </summary>
|
||||
/// (UnbufferedTokenStream is the same way.) Use CommonTokenStream.
|
||||
class BufferedTokenStream : public TokenStream {
|
||||
protected:
|
||||
TokenSource *tokenSource;
|
||||
public:
|
||||
BufferedTokenStream(TokenSource *tokenSource);
|
||||
|
||||
virtual TokenSource* getTokenSource() const override;
|
||||
virtual size_t index() override;
|
||||
virtual ssize_t mark() override;
|
||||
|
||||
virtual void release(ssize_t marker) override;
|
||||
virtual void reset();
|
||||
virtual void seek(size_t index) override;
|
||||
|
||||
virtual size_t size() override;
|
||||
virtual void consume() override;
|
||||
|
||||
virtual TokenRef get(size_t i) const override;
|
||||
|
||||
/// Get all tokens from start..stop inclusively.
|
||||
virtual std::vector<TokenRef> get(size_t start, size_t stop);
|
||||
|
||||
virtual ssize_t LA(ssize_t i) override;
|
||||
virtual TokenRef LT(ssize_t k) override;
|
||||
|
||||
/// Reset this token stream by setting its token source.
|
||||
virtual void setTokenSource(TokenSource *tokenSource);
|
||||
virtual std::vector<TokenRef> getTokens();
|
||||
virtual std::vector<TokenRef> getTokens(int start, int stop);
|
||||
|
||||
/// <summary>
|
||||
/// Given a start and stop index, return a List of all tokens in
|
||||
/// the token type BitSet. Return null if no tokens were found. This
|
||||
/// method looks at both on and off channel tokens.
|
||||
/// </summary>
|
||||
virtual std::vector<TokenRef> getTokens(int start, int stop, const std::vector<int> &types);
|
||||
virtual std::vector<TokenRef> getTokens(int start, int stop, int ttype);
|
||||
|
||||
/// Collect all tokens on specified channel to the right of
|
||||
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL or
|
||||
/// EOF. If channel is -1, find any non default channel token.
|
||||
virtual std::vector<TokenRef> getHiddenTokensToRight(size_t tokenIndex, int channel);
|
||||
|
||||
/// <summary>
|
||||
/// Collect all hidden tokens (any off-default channel) to the right of
|
||||
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL
|
||||
/// of EOF.
|
||||
/// </summary>
|
||||
virtual std::vector<TokenRef> getHiddenTokensToRight(size_t tokenIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Collect all tokens on specified channel to the left of
|
||||
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
|
||||
/// If channel is -1, find any non default channel token.
|
||||
/// </summary>
|
||||
virtual std::vector<TokenRef> getHiddenTokensToLeft(size_t tokenIndex, int channel);
|
||||
|
||||
/// <summary>
|
||||
/// Collect all hidden tokens (any off-default channel) to the left of
|
||||
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
|
||||
/// </summary>
|
||||
virtual std::vector<TokenRef> getHiddenTokensToLeft(size_t tokenIndex);
|
||||
|
||||
virtual std::string getSourceName() const override;
|
||||
virtual std::wstring getText() override;
|
||||
virtual std::wstring getText(const misc::Interval &interval) override;
|
||||
virtual std::wstring getText(RuleContext *ctx) override;
|
||||
virtual std::wstring getText(TokenRef start, TokenRef stop) override;
|
||||
|
||||
/// <summary>
|
||||
/// Get all tokens from lexer until EOF </summary>
|
||||
virtual void fill();
|
||||
|
||||
protected:
|
||||
TokenSource *_tokenSource;
|
||||
|
||||
/// Record every single token pulled from the source so we can reproduce
|
||||
/// chunks of it later. This list captures everything so we can access
|
||||
/// complete input text.
|
||||
/// </summary>
|
||||
std::vector<Token*> tokens;
|
||||
// ml: we own the tokens produced by the token factory.
|
||||
std::vector<TokenRef> _tokens;
|
||||
|
||||
/// <summary>
|
||||
/// The index into <seealso cref="#tokens"/> of the current token (next token to
|
||||
|
@ -70,7 +136,7 @@ namespace runtime {
|
|||
/// <seealso cref="#LT LT(1)"/> or whatever gets the first token and sets
|
||||
/// <seealso cref="#p"/>{@code =0;}.
|
||||
/// </summary>
|
||||
size_t p;
|
||||
size_t _p;
|
||||
|
||||
/// <summary>
|
||||
/// Set to {@code true} when the EOF token is fetched. Do not continue fetching
|
||||
|
@ -78,31 +144,14 @@ namespace runtime {
|
|||
/// <seealso cref="#tokens"/> array.
|
||||
/// </summary>
|
||||
/// <seealso cref= #fetch </seealso>
|
||||
bool fetchedEOF;
|
||||
|
||||
public:
|
||||
BufferedTokenStream(TokenSource *tokenSource);
|
||||
|
||||
virtual TokenSource *getTokenSource() const override;
|
||||
virtual size_t index() override;
|
||||
virtual ssize_t mark() override;
|
||||
|
||||
virtual void release(ssize_t marker) override;
|
||||
|
||||
virtual void reset();
|
||||
|
||||
virtual void seek(size_t index) override;
|
||||
|
||||
virtual size_t size() override;
|
||||
virtual void consume() override;
|
||||
|
||||
bool _fetchedEOF;
|
||||
|
||||
/// <summary>
|
||||
/// Make sure index {@code i} in tokens has a token.
|
||||
/// </summary>
|
||||
/// <returns> {@code true} if a token is located at index {@code i}, otherwise
|
||||
/// {@code false}. </returns>
|
||||
/// <seealso cref= #get(int i) </seealso>
|
||||
protected:
|
||||
virtual bool sync(size_t i);
|
||||
|
||||
/// <summary>
|
||||
|
@ -110,23 +159,9 @@ namespace runtime {
|
|||
/// </summary>
|
||||
/// <returns> The actual number of elements added to the buffer. </returns>
|
||||
virtual size_t fetch(size_t n);
|
||||
|
||||
virtual TokenRef LB(size_t k);
|
||||
|
||||
public:
|
||||
virtual Token *get(size_t i) const override;
|
||||
|
||||
/// <summary>
|
||||
/// Get all tokens from start..stop inclusively </summary>
|
||||
virtual std::vector<Token*> get(size_t start, size_t stop);
|
||||
|
||||
virtual ssize_t LA(ssize_t i) override;
|
||||
|
||||
protected:
|
||||
virtual Token *LB(size_t k);
|
||||
|
||||
public:
|
||||
virtual Token *LT(ssize_t k) override;
|
||||
|
||||
protected:
|
||||
/// Allowed derived classes to modify the behavior of operations which change
|
||||
/// the current stream position by adjusting the target token index of a seek
|
||||
/// operation. The default implementation simply returns {@code i}. If an
|
||||
|
@ -142,22 +177,6 @@ namespace runtime {
|
|||
void lazyInit();
|
||||
virtual void setup();
|
||||
|
||||
/// <summary>
|
||||
/// Reset this token stream by setting its token source. </summary>
|
||||
public:
|
||||
virtual void setTokenSource(TokenSource *tokenSource);
|
||||
virtual std::vector<Token*> getTokens();
|
||||
virtual std::vector<Token*> getTokens(int start, int stop);
|
||||
|
||||
/// <summary>
|
||||
/// Given a start and stop index, return a List of all tokens in
|
||||
/// the token type BitSet. Return null if no tokens were found. This
|
||||
/// method looks at both on and off channel tokens.
|
||||
/// </summary>
|
||||
virtual std::vector<Token*> getTokens(int start, int stop, std::vector<int> *types);
|
||||
virtual std::vector<Token*> getTokens(int start, int stop, int ttype);
|
||||
|
||||
protected:
|
||||
/// Given a starting index, return the index of the next token on channel.
|
||||
/// Return i if tokens[i] is on channel. Return -1 if there are no tokens
|
||||
/// on channel between i and EOF.
|
||||
|
@ -167,49 +186,8 @@ namespace runtime {
|
|||
/// Return i if tokens[i] is on channel. Return -1 if there are no tokens
|
||||
/// on channel between i and 0.
|
||||
virtual ssize_t previousTokenOnChannel(size_t i, int channel) const;
|
||||
|
||||
/// <summary>
|
||||
/// Collect all tokens on specified channel to the right of
|
||||
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL or
|
||||
/// EOF. If channel is -1, find any non default channel token.
|
||||
/// </summary>
|
||||
public:
|
||||
virtual std::vector<Token*> getHiddenTokensToRight(size_t tokenIndex, int channel);
|
||||
|
||||
/// <summary>
|
||||
/// Collect all hidden tokens (any off-default channel) to the right of
|
||||
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL
|
||||
/// of EOF.
|
||||
/// </summary>
|
||||
virtual std::vector<Token*> getHiddenTokensToRight(size_t tokenIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Collect all tokens on specified channel to the left of
|
||||
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
|
||||
/// If channel is -1, find any non default channel token.
|
||||
/// </summary>
|
||||
virtual std::vector<Token*> getHiddenTokensToLeft(size_t tokenIndex, int channel);
|
||||
|
||||
/// <summary>
|
||||
/// Collect all hidden tokens (any off-default channel) to the left of
|
||||
/// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
|
||||
/// </summary>
|
||||
virtual std::vector<Token*> getHiddenTokensToLeft(size_t tokenIndex);
|
||||
|
||||
protected:
|
||||
virtual std::vector<Token*> filterForChannel(size_t from, size_t to, int channel);
|
||||
|
||||
public:
|
||||
virtual std::string getSourceName() const override;
|
||||
virtual std::wstring getText() override;
|
||||
virtual std::wstring getText(const misc::Interval &interval) override;
|
||||
virtual std::wstring getText(RuleContext *ctx) override;
|
||||
virtual std::wstring getText(Token *start, Token *stop) override;
|
||||
|
||||
/// <summary>
|
||||
/// Get all tokens from lexer until EOF </summary>
|
||||
virtual void fill();
|
||||
|
||||
|
||||
virtual std::vector<TokenRef> filterForChannel(size_t from, size_t to, int channel);
|
||||
private:
|
||||
bool _needSetup;
|
||||
void InitializeInstanceFields();
|
||||
|
|
|
@ -33,68 +33,70 @@
|
|||
#include "TokenSource.h"
|
||||
#include "Strings.h"
|
||||
#include "CharStream.h"
|
||||
#include "CPPUtils.h"
|
||||
|
||||
#include "CommonToken.h"
|
||||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
using namespace antlrcpp;
|
||||
|
||||
std::pair<TokenSource*, CharStream*> *const CommonToken::EMPTY_SOURCE = new std::pair<TokenSource*, CharStream*>(nullptr, nullptr);
|
||||
const std::pair<TokenSource*, CharStream*> CommonToken::EMPTY_SOURCE;
|
||||
|
||||
CommonToken::CommonToken(int type) {
|
||||
InitializeInstanceFields();
|
||||
this->type = type;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
CommonToken::CommonToken(std::pair<TokenSource*, CharStream*> *source, int type, int channel, int start, int stop) {
|
||||
CommonToken::CommonToken(std::pair<TokenSource*, CharStream*> source, int type, int channel, int start, int stop) {
|
||||
InitializeInstanceFields();
|
||||
this->source = source;
|
||||
this->type = type;
|
||||
this->channel = channel;
|
||||
this->start = start;
|
||||
this->stop = stop;
|
||||
if (source->first != nullptr) {
|
||||
this->line = (int)source->first->getLine();
|
||||
this->charPositionInLine = source->first->getCharPositionInLine();
|
||||
_source = source;
|
||||
_type = type;
|
||||
_channel = channel;
|
||||
_start = start;
|
||||
_stop = stop;
|
||||
if (_source.first != nullptr) {
|
||||
_line = (int)source.first->getLine();
|
||||
_charPositionInLine = source.first->getCharPositionInLine();
|
||||
}
|
||||
}
|
||||
|
||||
CommonToken::CommonToken(int type, const std::wstring &text) {
|
||||
InitializeInstanceFields();
|
||||
this->type = type;
|
||||
this->channel = DEFAULT_CHANNEL;
|
||||
this->text = text;
|
||||
this->source = EMPTY_SOURCE;
|
||||
_type = type;
|
||||
_channel = DEFAULT_CHANNEL;
|
||||
_text = text;
|
||||
_source = EMPTY_SOURCE;
|
||||
}
|
||||
|
||||
CommonToken::CommonToken(Token *oldToken) {
|
||||
InitializeInstanceFields();
|
||||
text = oldToken->getText();
|
||||
type = oldToken->getType();
|
||||
line = oldToken->getLine();
|
||||
index = oldToken->getTokenIndex();
|
||||
charPositionInLine = oldToken->getCharPositionInLine();
|
||||
channel = oldToken->getChannel();
|
||||
start = oldToken->getStartIndex();
|
||||
stop = oldToken->getStopIndex();
|
||||
_text = oldToken->getText();
|
||||
_type = oldToken->getType();
|
||||
_line = oldToken->getLine();
|
||||
_index = oldToken->getTokenIndex();
|
||||
_charPositionInLine = oldToken->getCharPositionInLine();
|
||||
_channel = oldToken->getChannel();
|
||||
_start = oldToken->getStartIndex();
|
||||
_stop = oldToken->getStopIndex();
|
||||
|
||||
if (dynamic_cast<CommonToken*>(oldToken) != nullptr) {
|
||||
source = (static_cast<CommonToken*>(oldToken))->source;
|
||||
if (is<CommonToken*>(oldToken)) {
|
||||
_source = (static_cast<CommonToken*>(oldToken))->_source;
|
||||
} else {
|
||||
source = new std::pair<TokenSource*, CharStream*>(oldToken->getTokenSource(), oldToken->getInputStream());
|
||||
_source = { oldToken->getTokenSource(), oldToken->getInputStream() };
|
||||
}
|
||||
}
|
||||
|
||||
int CommonToken::getType() const {
|
||||
return type;
|
||||
return _type;
|
||||
}
|
||||
|
||||
void CommonToken::setLine(int line) {
|
||||
this->line = line;
|
||||
_line = line;
|
||||
}
|
||||
|
||||
std::wstring CommonToken::getText() {
|
||||
if (text != L"") {
|
||||
return text;
|
||||
if (!_text.empty()) {
|
||||
return _text;
|
||||
}
|
||||
|
||||
CharStream *input = getInputStream();
|
||||
|
@ -102,79 +104,79 @@ std::wstring CommonToken::getText() {
|
|||
return L"";
|
||||
}
|
||||
size_t n = input->size();
|
||||
if ((size_t)start < n && (size_t)stop < n) {
|
||||
return input->getText(misc::Interval(start,stop));
|
||||
if ((size_t)_start < n && (size_t)_stop < n) {
|
||||
return input->getText(misc::Interval(_start, _stop));
|
||||
} else {
|
||||
return L"<EOF>";
|
||||
}
|
||||
}
|
||||
|
||||
void CommonToken::setText(const std::wstring &text) {
|
||||
this->text = text;
|
||||
_text = text;
|
||||
}
|
||||
|
||||
int CommonToken::getLine() {
|
||||
return line;
|
||||
return _line;
|
||||
}
|
||||
|
||||
int CommonToken::getCharPositionInLine() {
|
||||
return charPositionInLine;
|
||||
return _charPositionInLine;
|
||||
}
|
||||
|
||||
void CommonToken::setCharPositionInLine(int charPositionInLine) {
|
||||
this->charPositionInLine = charPositionInLine;
|
||||
_charPositionInLine = charPositionInLine;
|
||||
}
|
||||
|
||||
int CommonToken::getChannel() {
|
||||
return channel;
|
||||
return _channel;
|
||||
}
|
||||
|
||||
void CommonToken::setChannel(int channel) {
|
||||
this->channel = channel;
|
||||
_channel = channel;
|
||||
}
|
||||
|
||||
void CommonToken::setType(int type) {
|
||||
this->type = type;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
int CommonToken::getStartIndex() {
|
||||
return start;
|
||||
return _start;
|
||||
}
|
||||
|
||||
void CommonToken::setStartIndex(int start) {
|
||||
this->start = start;
|
||||
_start = start;
|
||||
}
|
||||
|
||||
int CommonToken::getStopIndex() {
|
||||
return stop;
|
||||
return _stop;
|
||||
}
|
||||
|
||||
void CommonToken::setStopIndex(int stop) {
|
||||
this->stop = stop;
|
||||
_stop = stop;
|
||||
}
|
||||
|
||||
int CommonToken::getTokenIndex() {
|
||||
return index;
|
||||
return _index;
|
||||
}
|
||||
|
||||
void CommonToken::setTokenIndex(int index) {
|
||||
this->index = index;
|
||||
_index = index;
|
||||
}
|
||||
|
||||
org::antlr::v4::runtime::TokenSource *CommonToken::getTokenSource() {
|
||||
return source->first;
|
||||
return _source.first;
|
||||
}
|
||||
|
||||
org::antlr::v4::runtime::CharStream *CommonToken::getInputStream() {
|
||||
return source->second;
|
||||
return _source.second;
|
||||
}
|
||||
|
||||
void CommonToken::InitializeInstanceFields() {
|
||||
type = 0;
|
||||
line = 0;
|
||||
charPositionInLine = -1;
|
||||
channel = DEFAULT_CHANNEL;
|
||||
index = -1;
|
||||
start = 0;
|
||||
stop = 0;
|
||||
_type = 0;
|
||||
_line = 0;
|
||||
_charPositionInLine = -1;
|
||||
_channel = DEFAULT_CHANNEL;
|
||||
_index = -1;
|
||||
_start = 0;
|
||||
_stop = 0;
|
||||
}
|
||||
|
|
|
@ -40,47 +40,41 @@ namespace runtime {
|
|||
|
||||
class CommonToken : public WritableToken {
|
||||
protected:
|
||||
static std::pair<TokenSource*, CharStream*> *const EMPTY_SOURCE;
|
||||
static const std::pair<TokenSource*, CharStream*> EMPTY_SOURCE;
|
||||
|
||||
int type;
|
||||
int line;
|
||||
int charPositionInLine; // set to invalid position
|
||||
int channel;
|
||||
std::pair<TokenSource*, CharStream*> *source;
|
||||
int _type;
|
||||
int _line;
|
||||
int _charPositionInLine; // set to invalid position
|
||||
int _channel;
|
||||
std::pair<TokenSource*, CharStream*> _source; // Pure references, usually from statically allocated classes.
|
||||
|
||||
/// <summary>
|
||||
/// We need to be able to change the text once in a while. If
|
||||
/// this is non-empty, then getText should return this. Note that
|
||||
/// start/stop are not affected by changing this.
|
||||
/// </summary>
|
||||
///
|
||||
// TO_DO: can store these in map in token stream rather than as field here
|
||||
std::wstring text;
|
||||
std::wstring _text;
|
||||
|
||||
/// <summary>
|
||||
/// What token number is this from 0..n-1 tokens; < 0 implies invalid index </summary>
|
||||
int index;
|
||||
int _index;
|
||||
|
||||
/// <summary>
|
||||
/// The char position into the input buffer where this token starts </summary>
|
||||
int start;
|
||||
int _start;
|
||||
|
||||
/// <summary>
|
||||
/// The char position into the input buffer where this token stops </summary>
|
||||
int stop;
|
||||
int _stop;
|
||||
|
||||
public:
|
||||
CommonToken(int type);
|
||||
|
||||
CommonToken(std::pair<TokenSource*, CharStream*> *source, int type, int channel, int start, int stop);
|
||||
|
||||
CommonToken(std::pair<TokenSource*, CharStream*> source, int type, int channel, int start, int stop);
|
||||
CommonToken(int type, const std::wstring &text);
|
||||
|
||||
CommonToken(Token *oldToken);
|
||||
|
||||
virtual int getType() const override;
|
||||
|
||||
virtual void setLine(int line) override;
|
||||
|
||||
virtual std::wstring getText() override;
|
||||
|
||||
/// <summary>
|
||||
|
@ -90,33 +84,26 @@ namespace runtime {
|
|||
/// was converted to a new string in the token object.
|
||||
/// </summary>
|
||||
virtual void setText(const std::wstring &text) override;
|
||||
|
||||
virtual int getLine() override;
|
||||
|
||||
virtual int getCharPositionInLine() override;
|
||||
|
||||
virtual void setCharPositionInLine(int charPositionInLine) override;
|
||||
|
||||
virtual int getChannel() override;
|
||||
|
||||
virtual void setChannel(int channel) override;
|
||||
|
||||
virtual void setType(int type) override;
|
||||
|
||||
virtual int getStartIndex() override;
|
||||
|
||||
virtual void setStartIndex(int start);
|
||||
|
||||
virtual int getStopIndex() override;
|
||||
|
||||
virtual void setStopIndex(int stop);
|
||||
|
||||
virtual int getTokenIndex() override;
|
||||
|
||||
virtual void setTokenIndex(int index) override;
|
||||
|
||||
virtual TokenSource *getTokenSource() override;
|
||||
|
||||
virtual CharStream *getInputStream() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
TokenFactory<CommonToken*> *const CommonTokenFactory::DEFAULT = new CommonTokenFactory();
|
||||
const std::shared_ptr<TokenFactory<CommonToken>> CommonTokenFactory::DEFAULT = std::make_shared<CommonTokenFactory>();
|
||||
|
||||
CommonTokenFactory::CommonTokenFactory(bool copyText) : copyText(copyText) {
|
||||
}
|
||||
|
@ -45,19 +45,21 @@ CommonTokenFactory::CommonTokenFactory(bool copyText) : copyText(copyText) {
|
|||
CommonTokenFactory::CommonTokenFactory() : CommonTokenFactory(false) {
|
||||
}
|
||||
|
||||
CommonToken *CommonTokenFactory::create(std::pair<TokenSource*, CharStream*> *source, int type, const std::wstring &text, int channel, int start, int stop, int line, int charPositionInLine) {
|
||||
CommonToken *t = new CommonToken(source, type, channel, start, stop);
|
||||
std::shared_ptr<CommonToken> CommonTokenFactory::create(std::pair<TokenSource*, CharStream*> source, int type,
|
||||
const std::wstring &text, int channel, int start, int stop, int line, int charPositionInLine) {
|
||||
|
||||
std::shared_ptr<CommonToken> t = std::make_shared<CommonToken>(source, type, channel, start, stop);
|
||||
t->setLine(line);
|
||||
t->setCharPositionInLine(charPositionInLine);
|
||||
if (text != L"") {
|
||||
t->setText(text);
|
||||
} else if (copyText && source->second != nullptr) {
|
||||
t->setText(source->second->getText(misc::Interval(start, stop)));
|
||||
} else if (copyText && source.second != nullptr) {
|
||||
t->setText(source.second->getText(misc::Interval(start, stop)));
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
org::antlr::v4::runtime::CommonToken *CommonTokenFactory::create(int type, const std::wstring &text) {
|
||||
return new CommonToken(type, text);
|
||||
std::shared_ptr<CommonToken> CommonTokenFactory::create(int type, const std::wstring &text) {
|
||||
return std::make_shared<CommonToken>(type, text);
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@ namespace antlr {
|
|||
namespace v4 {
|
||||
namespace runtime {
|
||||
|
||||
class CommonTokenFactory : public TokenFactory<CommonToken*> {
|
||||
class CommonTokenFactory : public TokenFactory<CommonToken> {
|
||||
public:
|
||||
static TokenFactory<CommonToken*> *const DEFAULT;
|
||||
static const std::shared_ptr<TokenFactory<CommonToken>> DEFAULT;
|
||||
|
||||
/// <summary>
|
||||
/// Copy text for token out of input char stream. Useful when input
|
||||
|
@ -49,18 +49,17 @@ namespace runtime {
|
|||
protected:
|
||||
const bool copyText;
|
||||
|
||||
/// <summary>
|
||||
public:
|
||||
/// Create factory and indicate whether or not the factory copy
|
||||
/// text out of the char stream.
|
||||
/// </summary>
|
||||
public:
|
||||
CommonTokenFactory(bool copyText);
|
||||
|
||||
CommonTokenFactory();
|
||||
|
||||
virtual CommonToken *create(std::pair<TokenSource*, CharStream*> *source, int type, const std::wstring &text, int channel, int start, int stop, int line, int charPositionInLine) override;
|
||||
virtual std::shared_ptr<CommonToken> create(std::pair<TokenSource*, CharStream*> source, int type,
|
||||
const std::wstring &text, int channel, int start, int stop, int line, int charPositionInLine) override;
|
||||
|
||||
virtual CommonToken *create(int type, const std::wstring &text) override;
|
||||
virtual std::shared_ptr<CommonToken> create(int type, const std::wstring &text) override;
|
||||
};
|
||||
|
||||
} // namespace runtime
|
||||
|
|
|
@ -48,12 +48,12 @@ size_t CommonTokenStream::adjustSeekIndex(size_t i) {
|
|||
return (size_t)nextTokenOnChannel(i, channel);
|
||||
}
|
||||
|
||||
Token *CommonTokenStream::LB(size_t k) {
|
||||
if (k == 0 || k > p) {
|
||||
return nullptr;
|
||||
TokenRef CommonTokenStream::LB(size_t k) {
|
||||
if (k == 0 || k > _p) {
|
||||
return TokenRef();
|
||||
}
|
||||
|
||||
size_t i = p;
|
||||
size_t i = _p;
|
||||
size_t n = 1;
|
||||
// find k good tokens looking backwards
|
||||
while (n <= k) {
|
||||
|
@ -62,10 +62,10 @@ Token *CommonTokenStream::LB(size_t k) {
|
|||
i = (size_t)previousTokenOnChannel(i - 1, channel);
|
||||
n++;
|
||||
}
|
||||
return tokens[i];
|
||||
return _tokens[i];
|
||||
}
|
||||
|
||||
Token *CommonTokenStream::LT(ssize_t k) {
|
||||
TokenRef CommonTokenStream::LT(ssize_t k) {
|
||||
lazyInit();
|
||||
if (k == 0) {
|
||||
return nullptr;
|
||||
|
@ -73,7 +73,7 @@ Token *CommonTokenStream::LT(ssize_t k) {
|
|||
if (k < 0) {
|
||||
return LB((size_t)-k);
|
||||
}
|
||||
size_t i = p;
|
||||
size_t i = _p;
|
||||
size_t n = 1; // we know tokens[p] is a good one
|
||||
// find k good tokens
|
||||
while (n < (size_t)k) {
|
||||
|
@ -85,14 +85,14 @@ Token *CommonTokenStream::LT(ssize_t k) {
|
|||
n++;
|
||||
}
|
||||
|
||||
return tokens[i];
|
||||
return _tokens[i];
|
||||
}
|
||||
|
||||
int CommonTokenStream::getNumberOfOnChannelTokens() {
|
||||
int n = 0;
|
||||
fill();
|
||||
for (size_t i = 0; i < tokens.size(); i++) {
|
||||
Token *t = tokens[i];
|
||||
for (size_t i = 0; i < _tokens.size(); i++) {
|
||||
TokenRef t = _tokens[i];
|
||||
if (t->getChannel() == channel) {
|
||||
n++;
|
||||
}
|
||||
|
|
|
@ -68,13 +68,12 @@ namespace runtime {
|
|||
protected:
|
||||
virtual size_t adjustSeekIndex(size_t i) override;
|
||||
|
||||
virtual Token *LB(size_t k) override;
|
||||
virtual TokenRef LB(size_t k) override;
|
||||
|
||||
public:
|
||||
virtual Token *LT(ssize_t k) override;
|
||||
virtual TokenRef LT(ssize_t k) override;
|
||||
|
||||
/// <summary>
|
||||
/// Count EOF just once. </summary>
|
||||
/// Count EOF just once.
|
||||
virtual int getNumberOfOnChannelTokens();
|
||||
|
||||
private:
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "ATNState.h"
|
||||
#include "Parser.h"
|
||||
#include "Strings.h"
|
||||
#include "CommonToken.h"
|
||||
|
||||
#include "DefaultErrorStrategy.h"
|
||||
|
||||
|
@ -118,7 +119,7 @@ void DefaultErrorStrategy::sync(Parser *recognizer) {
|
|||
return;
|
||||
}
|
||||
|
||||
TokenStream *tokens = recognizer->getInputStream();
|
||||
TokenStream *tokens = recognizer->getTokenStream();
|
||||
ssize_t la = tokens->LA(1);
|
||||
|
||||
// try cheaper subset first; might get lucky. seems to shave a wee bit off
|
||||
|
@ -160,7 +161,7 @@ void DefaultErrorStrategy::sync(Parser *recognizer) {
|
|||
}
|
||||
|
||||
void DefaultErrorStrategy::reportNoViableAlternative(Parser *recognizer, const NoViableAltException &e) {
|
||||
TokenStream *tokens = recognizer->getInputStream();
|
||||
TokenStream *tokens = recognizer->getTokenStream();
|
||||
std::wstring input;
|
||||
if (tokens != nullptr) {
|
||||
if (e.getStartToken()->getType() == EOF) {
|
||||
|
@ -182,7 +183,7 @@ void DefaultErrorStrategy::reportInputMismatch(Parser *recognizer, const InputMi
|
|||
}
|
||||
|
||||
void DefaultErrorStrategy::reportFailedPredicate(Parser *recognizer, const FailedPredicateException &e) {
|
||||
const std::wstring& ruleName = recognizer->getRuleNames()[(size_t)recognizer->ctx->getRuleIndex()];
|
||||
const std::wstring& ruleName = recognizer->getRuleNames()[(size_t)recognizer->getContext()->getRuleIndex()];
|
||||
std::wstring msg = std::wstring(L"rule ") + ruleName + std::wstring(L" ") + antlrcpp::s2ws(e.what());
|
||||
recognizer->notifyErrorListeners(e.getOffendingToken(), msg, std::make_exception_ptr(e));
|
||||
}
|
||||
|
@ -194,7 +195,7 @@ void DefaultErrorStrategy::reportUnwantedToken(Parser *recognizer) {
|
|||
|
||||
beginErrorCondition(recognizer);
|
||||
|
||||
Token *t = recognizer->getCurrentToken();
|
||||
TokenRef t = recognizer->getCurrentToken();
|
||||
std::wstring tokenName = getTokenErrorDisplay(t);
|
||||
misc::IntervalSet expecting = getExpectedTokens(recognizer);
|
||||
|
||||
|
@ -209,17 +210,17 @@ void DefaultErrorStrategy::reportMissingToken(Parser *recognizer) {
|
|||
|
||||
beginErrorCondition(recognizer);
|
||||
|
||||
Token *t = recognizer->getCurrentToken();
|
||||
TokenRef t = recognizer->getCurrentToken();
|
||||
misc::IntervalSet expecting = getExpectedTokens(recognizer);
|
||||
std::wstring msg = std::wstring(L"missing ") + expecting.toString(recognizer->getTokenNames()) + std::wstring(L" at ") + getTokenErrorDisplay(t);
|
||||
|
||||
recognizer->notifyErrorListeners(t, msg, nullptr);
|
||||
}
|
||||
|
||||
Token *DefaultErrorStrategy::recoverInline(Parser *recognizer) {
|
||||
TokenRef DefaultErrorStrategy::recoverInline(Parser *recognizer) {
|
||||
// SINGLE TOKEN DELETION
|
||||
Token *matchedSymbol = singleTokenDeletion(recognizer);
|
||||
if (matchedSymbol != nullptr) {
|
||||
TokenRef matchedSymbol = singleTokenDeletion(recognizer);
|
||||
if (matchedSymbol) {
|
||||
// we have deleted the extra token.
|
||||
// now, move past ttype token as if all were ok
|
||||
recognizer->consume();
|
||||
|
@ -244,7 +245,7 @@ bool DefaultErrorStrategy::singleTokenInsertion(Parser *recognizer) {
|
|||
atn::ATNState *currentState = recognizer->getInterpreter<atn::ATNSimulator>()->atn.states[(size_t)recognizer->getState()];
|
||||
atn::ATNState *next = currentState->transition(0)->target;
|
||||
const atn::ATN &atn = recognizer->getInterpreter<atn::ATNSimulator>()->atn;
|
||||
misc::IntervalSet expectingAtLL2 = atn.nextTokens(next, recognizer->ctx);
|
||||
misc::IntervalSet expectingAtLL2 = atn.nextTokens(next, recognizer->getContext());
|
||||
if (expectingAtLL2.contains((int)currentSymbolType)) {
|
||||
reportMissingToken(recognizer);
|
||||
return true;
|
||||
|
@ -252,22 +253,22 @@ bool DefaultErrorStrategy::singleTokenInsertion(Parser *recognizer) {
|
|||
return false;
|
||||
}
|
||||
|
||||
Token *DefaultErrorStrategy::singleTokenDeletion(Parser *recognizer) {
|
||||
TokenRef DefaultErrorStrategy::singleTokenDeletion(Parser *recognizer) {
|
||||
ssize_t nextTokenType = recognizer->getInputStream()->LA(2);
|
||||
misc::IntervalSet expecting = getExpectedTokens(recognizer);
|
||||
if (expecting.contains((int)nextTokenType)) {
|
||||
reportUnwantedToken(recognizer);
|
||||
recognizer->consume(); // simply delete extra token
|
||||
// we want to return the token we're actually matching
|
||||
Token *matchedSymbol = recognizer->getCurrentToken();
|
||||
TokenRef matchedSymbol = recognizer->getCurrentToken();
|
||||
reportMatch(recognizer); // we know current token is correct
|
||||
return matchedSymbol;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Token *DefaultErrorStrategy::getMissingSymbol(Parser *recognizer) {
|
||||
Token *currentSymbol = recognizer->getCurrentToken();
|
||||
TokenRef DefaultErrorStrategy::getMissingSymbol(Parser *recognizer) {
|
||||
TokenRef currentSymbol = recognizer->getCurrentToken();
|
||||
misc::IntervalSet expecting = getExpectedTokens(recognizer);
|
||||
ssize_t expectedTokenType = expecting.getMinElement(); // get any element
|
||||
std::wstring tokenText;
|
||||
|
@ -276,21 +277,21 @@ Token *DefaultErrorStrategy::getMissingSymbol(Parser *recognizer) {
|
|||
} else {
|
||||
tokenText = std::wstring(L"<missing ") + recognizer->getTokenNames()[(size_t)expectedTokenType] + std::wstring(L">");
|
||||
}
|
||||
Token *current = currentSymbol;
|
||||
Token *lookback = recognizer->getInputStream()->LT(-1);
|
||||
TokenRef current = currentSymbol;
|
||||
TokenRef lookback = recognizer->getTokenStream()->LT(-1);
|
||||
if (current->getType() == EOF && lookback != nullptr) {
|
||||
current = lookback;
|
||||
}
|
||||
return (Token*)recognizer->getTokenFactory()->create(new std::pair<TokenSource*, CharStream*>(current->getTokenSource(),
|
||||
current->getTokenSource()->getInputStream()), (int)expectedTokenType, tokenText, Token::DEFAULT_CHANNEL, -1, -1,
|
||||
current->getLine(), current->getCharPositionInLine());
|
||||
return std::dynamic_pointer_cast<Token>(recognizer->getTokenFactory()->create({ current->getTokenSource(),
|
||||
current->getTokenSource()->getInputStream() }, (int)expectedTokenType, tokenText, Token::DEFAULT_CHANNEL, -1, -1,
|
||||
current->getLine(), current->getCharPositionInLine()));
|
||||
}
|
||||
|
||||
misc::IntervalSet DefaultErrorStrategy::getExpectedTokens(Parser *recognizer) {
|
||||
return recognizer->getExpectedTokens();
|
||||
}
|
||||
|
||||
std::wstring DefaultErrorStrategy::getTokenErrorDisplay(Token *t) {
|
||||
std::wstring DefaultErrorStrategy::getTokenErrorDisplay(TokenRef t) {
|
||||
if (t == nullptr) {
|
||||
return L"<no token>";
|
||||
}
|
||||
|
@ -305,11 +306,11 @@ std::wstring DefaultErrorStrategy::getTokenErrorDisplay(Token *t) {
|
|||
return escapeWSAndQuote(s);
|
||||
}
|
||||
|
||||
std::wstring DefaultErrorStrategy::getSymbolText(Token *symbol) {
|
||||
std::wstring DefaultErrorStrategy::getSymbolText(TokenRef symbol) {
|
||||
return symbol->getText();
|
||||
}
|
||||
|
||||
int DefaultErrorStrategy::getSymbolType(Token *symbol) {
|
||||
int DefaultErrorStrategy::getSymbolType(TokenRef symbol) {
|
||||
return symbol->getType();
|
||||
}
|
||||
|
||||
|
@ -323,15 +324,18 @@ std::wstring DefaultErrorStrategy::escapeWSAndQuote(std::wstring &s) {
|
|||
|
||||
misc::IntervalSet DefaultErrorStrategy::getErrorRecoverySet(Parser *recognizer) {
|
||||
const atn::ATN &atn = recognizer->getInterpreter<atn::ATNSimulator>()->atn;
|
||||
RuleContext *ctx = recognizer->ctx;
|
||||
RuleContextRef ctx = recognizer->getContext();
|
||||
misc::IntervalSet recoverSet;
|
||||
while (ctx != nullptr && ctx->invokingState >= 0) {
|
||||
while (ctx->invokingState >= 0) {
|
||||
// compute what follows who invoked us
|
||||
atn::ATNState *invokingState = atn.states[(size_t)ctx->invokingState];
|
||||
atn::RuleTransition *rt = dynamic_cast<atn::RuleTransition*>(invokingState->transition(0));
|
||||
misc::IntervalSet follow = atn.nextTokens(rt->followState);
|
||||
recoverSet.addAll(follow);
|
||||
ctx = ctx->parent;
|
||||
|
||||
if (ctx->parent.expired())
|
||||
break;
|
||||
ctx = ctx->parent.lock();
|
||||
}
|
||||
recoverSet.remove(Token::EPSILON);
|
||||
|
||||
|
|
|
@ -305,7 +305,7 @@ namespace runtime {
|
|||
/// in rule {@code atom}. It can assume that you forgot the {@code ')'}.
|
||||
/// </summary>
|
||||
public:
|
||||
virtual Token *recoverInline(Parser *recognizer) override;
|
||||
virtual TokenRef recoverInline(Parser *recognizer) override;
|
||||
|
||||
/// <summary>
|
||||
/// This method implements the single-token insertion inline error recovery
|
||||
|
@ -344,7 +344,7 @@ namespace runtime {
|
|||
/// <returns> the successfully matched <seealso cref="Token"/> instance if single-token
|
||||
/// deletion successfully recovers from the mismatched input, otherwise
|
||||
/// {@code null} </returns>
|
||||
virtual Token *singleTokenDeletion(Parser *recognizer);
|
||||
virtual TokenRef singleTokenDeletion(Parser *recognizer);
|
||||
|
||||
/// <summary>
|
||||
/// Conjure up a missing token during error recovery.
|
||||
|
@ -366,7 +366,7 @@ namespace runtime {
|
|||
/// If you change what tokens must be created by the lexer,
|
||||
/// override this method to create the appropriate tokens.
|
||||
/// </summary>
|
||||
virtual Token *getMissingSymbol(Parser *recognizer);
|
||||
virtual TokenRef getMissingSymbol(Parser *recognizer);
|
||||
|
||||
virtual misc::IntervalSet getExpectedTokens(Parser *recognizer);
|
||||
|
||||
|
@ -379,11 +379,11 @@ namespace runtime {
|
|||
/// your token objects because you don't have to go modify your lexer
|
||||
/// so that it creates a new Java type.
|
||||
/// </summary>
|
||||
virtual std::wstring getTokenErrorDisplay(Token *t);
|
||||
virtual std::wstring getTokenErrorDisplay(TokenRef t);
|
||||
|
||||
virtual std::wstring getSymbolText(Token *symbol);
|
||||
virtual std::wstring getSymbolText(TokenRef symbol);
|
||||
|
||||
virtual int getSymbolType(Token *symbol);
|
||||
virtual int getSymbolType(TokenRef symbol);
|
||||
|
||||
virtual std::wstring escapeWSAndQuote(std::wstring &s);
|
||||
|
||||
|
|
|
@ -47,21 +47,22 @@ DiagnosticErrorListener::DiagnosticErrorListener(bool exactOnly) : exactOnly(exa
|
|||
}
|
||||
|
||||
void DiagnosticErrorListener::reportAmbiguity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
bool exact, antlrcpp::BitSet *ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
bool exact, const antlrcpp::BitSet &ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
if (exactOnly && !exact) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::wstring decision = getDecisionDescription(recognizer, dfa);
|
||||
antlrcpp::BitSet *conflictingAlts = getConflictingAlts(ambigAlts, configs);
|
||||
antlrcpp::BitSet conflictingAlts = getConflictingAlts(ambigAlts, configs);
|
||||
std::wstring text = recognizer->getTokenStream()->getText(misc::Interval((int)startIndex, (int)stopIndex));
|
||||
std::wstring message = L"reportAmbiguity d = " + decision + L": ambigAlts = " + conflictingAlts->toString() + L", input = '" + text + L"'";
|
||||
std::wstring message = L"reportAmbiguity d = " + decision + L": ambigAlts = " + conflictingAlts.toString() +
|
||||
L", input = '" + text + L"'";
|
||||
|
||||
recognizer->notifyErrorListeners(message);
|
||||
}
|
||||
|
||||
void DiagnosticErrorListener::reportAttemptingFullContext(Parser *recognizer, dfa::DFA *dfa, size_t startIndex,
|
||||
size_t stopIndex, antlrcpp::BitSet *conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
size_t stopIndex, const antlrcpp::BitSet &conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
std::wstring decision = getDecisionDescription(recognizer, dfa);
|
||||
std::wstring text = recognizer->getTokenStream()->getText(misc::Interval((int)startIndex, (int)stopIndex));
|
||||
std::wstring message = L"reportAttemptingFullContext d = " + decision + L", input = '" + text + L"'";
|
||||
|
@ -93,16 +94,17 @@ std::wstring DiagnosticErrorListener::getDecisionDescription(Parser *recognizer,
|
|||
return std::to_wstring(decision) + L"(" + ruleName + L")";
|
||||
}
|
||||
|
||||
antlrcpp::BitSet *DiagnosticErrorListener::getConflictingAlts(antlrcpp::BitSet *reportedAlts,
|
||||
std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
if (reportedAlts != nullptr) {
|
||||
antlrcpp::BitSet DiagnosticErrorListener::getConflictingAlts(const antlrcpp::BitSet &reportedAlts,
|
||||
std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
if (reportedAlts.count() > 0) { // Not exactly like the original Java code, but this listener is only used
|
||||
// in the TestRig (where it never provides a good alt set), so it's probably ok so.
|
||||
return reportedAlts;
|
||||
}
|
||||
|
||||
antlrcpp::BitSet *result = new antlrcpp::BitSet();
|
||||
antlrcpp::BitSet result;
|
||||
for (size_t i = 0; i < configs->size(); i++) {
|
||||
atn::ATNConfig *config = configs->get(i);
|
||||
result->set((size_t)config->alt);
|
||||
result.set((size_t)config->alt);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -82,10 +82,10 @@ namespace runtime {
|
|||
DiagnosticErrorListener(bool exactOnly);
|
||||
|
||||
virtual void reportAmbiguity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex, bool exact,
|
||||
antlrcpp::BitSet *ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
const antlrcpp::BitSet &ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
|
||||
virtual void reportAttemptingFullContext(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
antlrcpp::BitSet *conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
const antlrcpp::BitSet &conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
|
||||
virtual void reportContextSensitivity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
int prediction, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
|
@ -103,7 +103,7 @@ namespace runtime {
|
|||
/// <param name="configs"> The conflicting or ambiguous configuration set. </param>
|
||||
/// <returns> Returns {@code reportedAlts} if it is not {@code null}, otherwise
|
||||
/// returns the set of alternatives represented in {@code configs}. </returns>
|
||||
virtual antlrcpp::BitSet *getConflictingAlts(antlrcpp::BitSet *reportedAlts, std::shared_ptr<atn::ATNConfigSet> configs);
|
||||
virtual antlrcpp::BitSet getConflictingAlts(const antlrcpp::BitSet &reportedAlts, std::shared_ptr<atn::ATNConfigSet> configs);
|
||||
};
|
||||
|
||||
} // namespace runtime
|
||||
|
|
|
@ -47,7 +47,7 @@ FailedPredicateException::FailedPredicateException(Parser *recognizer, const std
|
|||
|
||||
FailedPredicateException::FailedPredicateException(Parser *recognizer, const std::string &predicate, const std::string &message)
|
||||
: RecognitionException(!message.empty() ? message : "failed predicate: " + predicate + "?", recognizer,
|
||||
recognizer->getInputStream(), recognizer->ctx, recognizer->getCurrentToken()) {
|
||||
recognizer->getInputStream(), recognizer->getContext(), recognizer->getCurrentToken()) {
|
||||
|
||||
atn::ATNState *s = recognizer->getInterpreter<atn::ATNSimulator>()->atn.states[(size_t)recognizer->getState()];
|
||||
atn::Transition *transition = s->transition(0);
|
||||
|
|
|
@ -36,5 +36,6 @@
|
|||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
InputMismatchException::InputMismatchException(Parser *recognizer)
|
||||
: RecognitionException(recognizer, recognizer->getInputStream(), recognizer->ctx, recognizer->getCurrentToken()) {
|
||||
: RecognitionException(recognizer, recognizer->getInputStream(), recognizer->getContext(),
|
||||
recognizer->getCurrentToken()) {
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
InterpreterRuleContext::InterpreterRuleContext(ParserRuleContext *parent, int invokingStateNumber, ssize_t ruleIndex)
|
||||
InterpreterRuleContext::InterpreterRuleContext(std::weak_ptr<ParserRuleContext> parent, int invokingStateNumber, ssize_t ruleIndex)
|
||||
: ParserRuleContext(parent, invokingStateNumber), ruleIndex(ruleIndex) {
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace runtime {
|
|||
const ssize_t ruleIndex;
|
||||
|
||||
public:
|
||||
InterpreterRuleContext(ParserRuleContext *parent, int invokingStateNumber, ssize_t ruleIndex);
|
||||
InterpreterRuleContext(std::weak_ptr<ParserRuleContext> parent, int invokingStateNumber, ssize_t ruleIndex);
|
||||
|
||||
virtual ssize_t getRuleIndex() const override;
|
||||
};
|
||||
|
|
|
@ -36,28 +36,22 @@
|
|||
#include "LexerNoViableAltException.h"
|
||||
#include "ANTLRErrorListener.h"
|
||||
#include "CPPUtils.h"
|
||||
#include "CommonToken.h"
|
||||
|
||||
#include "Lexer.h"
|
||||
|
||||
using namespace antlrcpp;
|
||||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
Lexer::Lexer() {
|
||||
Lexer::Lexer(CharStream *input) : _input(input) {
|
||||
InitializeInstanceFields();
|
||||
}
|
||||
|
||||
Lexer::Lexer(CharStream *input) {
|
||||
InitializeInstanceFields();
|
||||
this->_input = input;
|
||||
this->_tokenFactorySourcePair = new std::pair<TokenSource*, CharStream*>(this, input);
|
||||
}
|
||||
|
||||
void Lexer::reset() {
|
||||
// wack Lexer state variables
|
||||
if (_input != nullptr) {
|
||||
_input->seek(0); // rewind the input
|
||||
}
|
||||
delete _token;
|
||||
_input->seek(0); // rewind the input
|
||||
|
||||
_token.reset();
|
||||
_type = Token::INVALID_TYPE;
|
||||
_channel = Token::DEFAULT_CHANNEL;
|
||||
_tokenStartCharIndex = -1;
|
||||
|
@ -72,11 +66,7 @@ void Lexer::reset() {
|
|||
getInterpreter<atn::LexerATNSimulator>()->reset();
|
||||
}
|
||||
|
||||
Token *Lexer::nextToken() {
|
||||
if (_input == nullptr) {
|
||||
throw IllegalStateException("nextToken requires a non-null input stream.");
|
||||
}
|
||||
|
||||
TokenRef Lexer::nextToken() {
|
||||
// Mark start location in char stream so unbuffered streams are
|
||||
// guaranteed at least have text of current token
|
||||
ssize_t tokenStartMarker = _input->mark();
|
||||
|
@ -94,8 +84,7 @@ Token *Lexer::nextToken() {
|
|||
return _token;
|
||||
}
|
||||
|
||||
delete _token;
|
||||
_token = nullptr;
|
||||
_token.reset();
|
||||
_channel = Token::DEFAULT_CHANNEL;
|
||||
_tokenStartCharIndex = (int)_input->index();
|
||||
_tokenStartCharPositionInLine = getInterpreter<atn::LexerATNSimulator>()->getCharPositionInLine();
|
||||
|
@ -161,38 +150,35 @@ int Lexer::popMode() {
|
|||
}
|
||||
|
||||
|
||||
TokenFactory<CommonToken*> *Lexer::getTokenFactory() {
|
||||
std::shared_ptr<TokenFactory<CommonToken>> Lexer::getTokenFactory() {
|
||||
return _factory;
|
||||
}
|
||||
|
||||
void Lexer::setInputStream(IntStream *input) {
|
||||
delete this->_input;
|
||||
this->_tokenFactorySourcePair = new std::pair<TokenSource*, CharStream*>(this, _input);
|
||||
reset();
|
||||
this->_input = static_cast<CharStream*>(input);
|
||||
this->_tokenFactorySourcePair = new std::pair<TokenSource*, CharStream*>(this, _input);
|
||||
_input = dynamic_cast<CharStream*>(input);
|
||||
}
|
||||
|
||||
std::string Lexer::getSourceName() {
|
||||
return _input->getSourceName();
|
||||
}
|
||||
|
||||
CharStream *Lexer::getInputStream() {
|
||||
CharStream* Lexer::getInputStream() {
|
||||
return _input;
|
||||
}
|
||||
|
||||
void Lexer::emit(Token *token) {
|
||||
//System.err.println("emit "+token);
|
||||
this->_token = token;
|
||||
void Lexer::emit(TokenRef token) {
|
||||
_token = token;
|
||||
}
|
||||
|
||||
Token *Lexer::emit() {
|
||||
Token *t = (Token*)_factory->create(_tokenFactorySourcePair, _type, _text, _channel, _tokenStartCharIndex, getCharIndex() - 1, _tokenStartLine, _tokenStartCharPositionInLine);
|
||||
TokenRef Lexer::emit() {
|
||||
TokenRef t = std::dynamic_pointer_cast<Token>(_factory->create({ this, _input }, _type, _text, _channel,
|
||||
_tokenStartCharIndex, getCharIndex() - 1, _tokenStartLine, _tokenStartCharPositionInLine));
|
||||
emit(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
Token *Lexer::emitEOF() {
|
||||
TokenRef Lexer::emitEOF() {
|
||||
int cpos = getCharPositionInLine();
|
||||
// The character position for EOF is one beyond the position of
|
||||
// the previous token's last character
|
||||
|
@ -200,8 +186,8 @@ Token *Lexer::emitEOF() {
|
|||
int n = _token->getStopIndex() - _token->getStartIndex() + 1;
|
||||
cpos = _token->getCharPositionInLine() + n;
|
||||
}
|
||||
Token *eof = (Token*)_factory->create(_tokenFactorySourcePair, EOF, L"", Token::DEFAULT_CHANNEL,
|
||||
(int)_input->index(), (int)_input->index() - 1, (int)getLine(), cpos);
|
||||
TokenRef eof = std::dynamic_pointer_cast<Token>(_factory->create({ this, _input }, EOF, L"", Token::DEFAULT_CHANNEL,
|
||||
(int)_input->index(), (int)_input->index() - 1, (int)getLine(), cpos));
|
||||
emit(eof);
|
||||
return eof;
|
||||
}
|
||||
|
@ -237,12 +223,12 @@ void Lexer::setText(const std::wstring &text) {
|
|||
this->_text = text;
|
||||
}
|
||||
|
||||
Token *Lexer::getToken() {
|
||||
TokenRef Lexer::getToken() {
|
||||
return _token;
|
||||
}
|
||||
|
||||
void Lexer::setToken(Token *_token) {
|
||||
this->_token = _token;
|
||||
void Lexer::setToken(TokenRef token) {
|
||||
_token = token;
|
||||
}
|
||||
|
||||
void Lexer::setType(int ttype) {
|
||||
|
@ -261,9 +247,9 @@ int Lexer::getChannel() {
|
|||
return _channel;
|
||||
}
|
||||
|
||||
std::vector<Token*> Lexer::getAllTokens() {
|
||||
std::vector<Token*> tokens = std::vector<Token*>();
|
||||
Token *t = nextToken();
|
||||
std::vector<TokenRef> Lexer::getAllTokens() {
|
||||
std::vector<TokenRef> tokens;
|
||||
TokenRef t = nextToken();
|
||||
while (t->getType() != EOF) {
|
||||
tokens.push_back(t);
|
||||
t = nextToken();
|
||||
|
|
|
@ -42,9 +42,9 @@ namespace v4 {
|
|||
namespace runtime {
|
||||
|
||||
/// A lexer is recognizer that draws input symbols from a character stream.
|
||||
/// lexer grammars result in a subclass of this object. A Lexer object
|
||||
/// uses simplified match() and error recovery mechanisms in the interest
|
||||
/// of speed.
|
||||
/// lexer grammars result in a subclass of this object. A Lexer object
|
||||
/// uses simplified match() and error recovery mechanisms in the interest
|
||||
/// of speed.
|
||||
class Lexer : public Recognizer, public TokenSource {
|
||||
public:
|
||||
static const int DEFAULT_MODE = 0;
|
||||
|
@ -56,15 +56,13 @@ namespace runtime {
|
|||
static const wchar_t MIN_CHAR_VALUE = L'\0';
|
||||
static const wchar_t MAX_CHAR_VALUE = L'\uFFFE';
|
||||
|
||||
CharStream *_input;
|
||||
CharStream *_input; // Pure reference, usually from statically allocated instance.
|
||||
protected:
|
||||
std::pair<TokenSource*, CharStream*> *_tokenFactorySourcePair;
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// How to create token objects </summary>
|
||||
TokenFactory<CommonToken*> *_factory;
|
||||
std::shared_ptr<TokenFactory<CommonToken>> _factory;
|
||||
|
||||
/// <summary>
|
||||
public:
|
||||
/// The goal of all lexer rules/methods is to create a token object.
|
||||
/// This is an instance variable as multiple rules may collaborate to
|
||||
/// create a single token. nextToken will return this object after
|
||||
|
@ -72,9 +70,7 @@ namespace runtime {
|
|||
/// emissions, then set this to the last token to be matched or
|
||||
/// something nonnull so that the auto token emit mechanism will not
|
||||
/// emit another token.
|
||||
/// </summary>
|
||||
public:
|
||||
Token *_token;
|
||||
TokenRef _token;
|
||||
|
||||
/// <summary>
|
||||
/// What character index in the stream did the current token start at?
|
||||
|
@ -113,14 +109,12 @@ namespace runtime {
|
|||
/// the input char buffer. Use setText() or can set this instance var.
|
||||
std::wstring _text;
|
||||
|
||||
Lexer();
|
||||
|
||||
Lexer(CharStream *input);
|
||||
|
||||
virtual void reset();
|
||||
|
||||
/// Return a token from this source; i.e., match a token on the char stream.
|
||||
virtual Token *nextToken() override;
|
||||
virtual TokenRef nextToken() override;
|
||||
|
||||
/// Instruct the lexer to skip creating a token for current lexer rule
|
||||
/// and look for another token. nextToken() knows to keep looking when
|
||||
|
@ -142,7 +136,7 @@ namespace runtime {
|
|||
this->_factory = factory;
|
||||
}
|
||||
|
||||
virtual TokenFactory<CommonToken*> *getTokenFactory() override;
|
||||
virtual std::shared_ptr<TokenFactory<CommonToken>> getTokenFactory() override;
|
||||
|
||||
/// <summary>
|
||||
/// Set the char stream and reset the lexer </summary>
|
||||
|
@ -150,7 +144,7 @@ namespace runtime {
|
|||
|
||||
virtual std::string getSourceName() override;
|
||||
|
||||
virtual CharStream *getInputStream() override;
|
||||
virtual CharStream* getInputStream() override;
|
||||
|
||||
/// <summary>
|
||||
/// By default does not support multiple emits per nextToken invocation
|
||||
|
@ -158,7 +152,7 @@ namespace runtime {
|
|||
/// and getToken (to push tokens into a list and pull from that list
|
||||
/// rather than a single variable as this implementation does).
|
||||
/// </summary>
|
||||
virtual void emit(Token *token);
|
||||
virtual void emit(TokenRef token);
|
||||
|
||||
/// <summary>
|
||||
/// The standard method called to automatically emit a token at the
|
||||
|
@ -167,9 +161,9 @@ namespace runtime {
|
|||
/// use that to set the token's text. Override this method to emit
|
||||
/// custom Token objects or provide a new factory.
|
||||
/// </summary>
|
||||
virtual Token *emit();
|
||||
virtual TokenRef emit();
|
||||
|
||||
virtual Token *emitEOF();
|
||||
virtual TokenRef emitEOF();
|
||||
|
||||
virtual size_t getLine() const override;
|
||||
|
||||
|
@ -197,9 +191,9 @@ namespace runtime {
|
|||
|
||||
/// <summary>
|
||||
/// Override if emitting multiple tokens. </summary>
|
||||
virtual Token *getToken();
|
||||
virtual TokenRef getToken();
|
||||
|
||||
virtual void setToken(Token *_token);
|
||||
virtual void setToken(TokenRef token);
|
||||
|
||||
virtual void setType(int ttype);
|
||||
|
||||
|
@ -211,11 +205,9 @@ namespace runtime {
|
|||
|
||||
virtual const std::vector<std::wstring>& getModeNames() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Return a list of all Token objects in input char stream.
|
||||
/// Forces load of all tokens. Does not include EOF token.
|
||||
/// </summary>
|
||||
virtual std::vector<Token*> getAllTokens();
|
||||
/// Forces load of all tokens. Does not include EOF token.
|
||||
virtual std::vector<TokenRef> getAllTokens();
|
||||
|
||||
virtual void recover(const LexerNoViableAltException &e);
|
||||
|
||||
|
|
|
@ -39,13 +39,13 @@ using namespace org::antlr::v4::runtime;
|
|||
|
||||
int ListTokenSource::getCharPositionInLine() {
|
||||
if (i < tokens.size()) {
|
||||
return ((Token*)tokens[i])->getCharPositionInLine();
|
||||
return tokens[i]->getCharPositionInLine();
|
||||
} else if (eofToken != nullptr) {
|
||||
return eofToken->getCharPositionInLine();
|
||||
} else if (tokens.size() > 0) {
|
||||
// have to calculate the result from the line/column of the previous
|
||||
// token, along with the text of the token.
|
||||
Token *lastToken = tokens[tokens.size() - 1];
|
||||
TokenRef lastToken = tokens.back();
|
||||
std::wstring tokenText = lastToken->getText();
|
||||
if (tokenText != L"") {
|
||||
int lastNewLine = (int)tokenText.rfind(L'\n');
|
||||
|
@ -62,26 +62,26 @@ int ListTokenSource::getCharPositionInLine() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Token *ListTokenSource::nextToken() {
|
||||
TokenRef ListTokenSource::nextToken() {
|
||||
if (i >= tokens.size()) {
|
||||
if (eofToken == nullptr) {
|
||||
int start = -1;
|
||||
if (tokens.size() > 0) {
|
||||
int previousStop = ((Token*)tokens[tokens.size() - 1])->getStopIndex();
|
||||
int previousStop = tokens.back()->getStopIndex();
|
||||
if (previousStop != -1) {
|
||||
start = previousStop + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int stop = std::max(-1, start - 1);
|
||||
eofToken = _factory->create(new std::pair<TokenSource*, CharStream*>(this, getInputStream()), EOF,
|
||||
L"EOF", Token::DEFAULT_CHANNEL, start, stop, (int)getLine(), getCharPositionInLine());
|
||||
eofToken = std::dynamic_pointer_cast<Token>(_factory->create({ this, getInputStream() }, EOF, L"EOF",
|
||||
Token::DEFAULT_CHANNEL, start, stop, (int)getLine(), getCharPositionInLine()));
|
||||
}
|
||||
|
||||
return eofToken;
|
||||
}
|
||||
|
||||
Token *t = tokens[i];
|
||||
TokenRef t = tokens[i];
|
||||
if (i == tokens.size() - 1 && t->getType() == EOF) {
|
||||
eofToken = t;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ size_t ListTokenSource::getLine() const {
|
|||
} else if (tokens.size() > 0) {
|
||||
// have to calculate the result from the line/column of the previous
|
||||
// token, along with the text of the token.
|
||||
Token *lastToken = tokens[tokens.size() - 1];
|
||||
TokenRef lastToken = tokens.back();
|
||||
int line = lastToken->getLine();
|
||||
|
||||
std::wstring tokenText = lastToken->getText();
|
||||
|
@ -145,7 +145,7 @@ std::string ListTokenSource::getSourceName() {
|
|||
return "List";
|
||||
}
|
||||
|
||||
TokenFactory<CommonToken*> *ListTokenSource::getTokenFactory() {
|
||||
std::shared_ptr<TokenFactory<CommonToken>> ListTokenSource::getTokenFactory() {
|
||||
return _factory;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,11 +48,8 @@ namespace runtime {
|
|||
/// list is reached. Otherwise, an EOF token will be created.
|
||||
/// </summary>
|
||||
class ListTokenSource : public TokenSource {
|
||||
/// <summary>
|
||||
/// The wrapped collection of <seealso cref="Token"/> objects to return.
|
||||
/// </summary>
|
||||
protected:
|
||||
const std::vector<Token *> tokens;
|
||||
const std::vector<TokenRef> tokens;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the input source. If this value is {@code null}, a call to
|
||||
|
@ -74,14 +71,14 @@ namespace runtime {
|
|||
/// <summary>
|
||||
/// This field caches the EOF token for the token source.
|
||||
/// </summary>
|
||||
Token *eofToken;
|
||||
TokenRef eofToken;
|
||||
|
||||
/// <summary>
|
||||
/// This is the backing field for <seealso cref="#getTokenFactory"/> and
|
||||
/// <seealso cref="setTokenFactory"/>.
|
||||
/// </summary>
|
||||
private:
|
||||
TokenFactory<CommonToken *> *_factory = CommonTokenFactory::DEFAULT;
|
||||
std::shared_ptr<TokenFactory<CommonToken>> _factory = CommonTokenFactory::DEFAULT;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <seealso cref="ListTokenSource"/> instance from the specified
|
||||
|
@ -117,43 +114,18 @@ namespace runtime {
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// @inheritDoc
|
||||
/// </summary>
|
||||
virtual int getCharPositionInLine() override;
|
||||
|
||||
/// <summary>
|
||||
/// @inheritDoc
|
||||
/// </summary>
|
||||
virtual Token *nextToken() override;
|
||||
|
||||
/// <summary>
|
||||
/// @inheritDoc
|
||||
/// </summary>
|
||||
virtual TokenRef nextToken() override;
|
||||
virtual size_t getLine() const override;
|
||||
|
||||
/// <summary>
|
||||
/// @inheritDoc
|
||||
/// </summary>
|
||||
virtual CharStream *getInputStream() override;
|
||||
|
||||
/// <summary>
|
||||
/// @inheritDoc
|
||||
/// </summary>
|
||||
virtual CharStream* getInputStream() override;
|
||||
virtual std::string getSourceName() override;
|
||||
|
||||
/// <summary>
|
||||
/// @inheritDoc
|
||||
/// </summary>
|
||||
template<typename T1>
|
||||
void setTokenFactory(TokenFactory<T1> *factory) {
|
||||
this->_factory = factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// @inheritDoc
|
||||
/// </summary>
|
||||
virtual TokenFactory<CommonToken *> *getTokenFactory() override;
|
||||
virtual std::shared_ptr<TokenFactory<CommonToken>> getTokenFactory() override;
|
||||
|
||||
private:
|
||||
void InitializeInstanceFields();
|
||||
|
|
|
@ -36,16 +36,16 @@
|
|||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
NoViableAltException::NoViableAltException(Parser *recognizer)
|
||||
: NoViableAltException(recognizer, recognizer->getInputStream(), recognizer->getCurrentToken(),
|
||||
recognizer->getCurrentToken(), nullptr, recognizer->ctx) {
|
||||
: NoViableAltException(recognizer, recognizer->getTokenStream(), recognizer->getCurrentToken(),
|
||||
recognizer->getCurrentToken(), nullptr, recognizer->getContext()) {
|
||||
}
|
||||
|
||||
NoViableAltException::NoViableAltException(Parser *recognizer, TokenStream *input, Token *startToken,
|
||||
Token *offendingToken, std::shared_ptr<atn::ATNConfigSet> deadEndConfigs, ParserRuleContext *ctx)
|
||||
NoViableAltException::NoViableAltException(Parser *recognizer, TokenStream *input, TokenRef startToken,
|
||||
TokenRef offendingToken, std::shared_ptr<atn::ATNConfigSet> deadEndConfigs, ParserRuleContextRef ctx)
|
||||
: RecognitionException(recognizer, input, ctx, offendingToken), _deadEndConfigs(deadEndConfigs), _startToken(startToken) {
|
||||
}
|
||||
|
||||
Token* NoViableAltException::getStartToken() const {
|
||||
TokenRef NoViableAltException::getStartToken() const {
|
||||
return _startToken;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,21 +47,21 @@ namespace runtime {
|
|||
class NoViableAltException : public RecognitionException {
|
||||
public:
|
||||
NoViableAltException(Parser *recognizer); // LL(1) error
|
||||
NoViableAltException(Parser *recognizer, TokenStream *input, Token *startToken, Token *offendingToken,
|
||||
std::shared_ptr<atn::ATNConfigSet> deadEndConfigs, ParserRuleContext *ctx);
|
||||
NoViableAltException(Parser *recognizer, TokenStream *input, TokenRef startToken, TokenRef offendingToken,
|
||||
std::shared_ptr<atn::ATNConfigSet> deadEndConfigs, ParserRuleContextRef ctx);
|
||||
|
||||
virtual Token* getStartToken() const;
|
||||
virtual TokenRef getStartToken() const;
|
||||
virtual std::shared_ptr<atn::ATNConfigSet> getDeadEndConfigs() const;
|
||||
|
||||
private:
|
||||
/// Which configurations did we try at input.index() that couldn't match input.LT(1)?
|
||||
std::shared_ptr<atn::ATNConfigSet> _deadEndConfigs;
|
||||
std::shared_ptr<atn::ATNConfigSet> _deadEndConfigs;
|
||||
|
||||
/// The token object at the start index; the input stream might
|
||||
/// not be buffering tokens so get a reference to it. (At the
|
||||
/// time the error occurred, of course the stream needs to keep a
|
||||
/// buffer all of the tokens but later we might not have access to those.)
|
||||
Token* _startToken;
|
||||
TokenRef _startToken;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -45,56 +45,59 @@
|
|||
#include "Strings.h"
|
||||
#include "Exceptions.h"
|
||||
#include "ANTLRErrorListener.h"
|
||||
#include "ParseTreePattern.h"
|
||||
|
||||
#include "Parser.h"
|
||||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
using namespace antlrcpp;
|
||||
|
||||
std::map<std::wstring, atn::ATN> Parser::bypassAltsAtnCache;
|
||||
|
||||
Parser::TraceListener::TraceListener(Parser *outerInstance) : outerInstance(outerInstance) {
|
||||
}
|
||||
|
||||
void Parser::TraceListener::enterEveryRule(ParserRuleContext *ctx) {
|
||||
void Parser::TraceListener::enterEveryRule(ParserRuleContextRef ctx) {
|
||||
std::cout << "enter "
|
||||
<< antlrcpp::ws2s(outerInstance->getRuleNames()[(size_t)ctx->getRuleIndex()])
|
||||
<< ", LT(1)=" << antlrcpp::ws2s(outerInstance->_input->LT(1)->getText())
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void Parser::TraceListener::visitTerminal(tree::TerminalNode *node) {
|
||||
void Parser::TraceListener::visitTerminal(std::shared_ptr<tree::TerminalNode> node) {
|
||||
std::cout << "consume "
|
||||
<< node->getSymbol() << " rule "
|
||||
<< antlrcpp::ws2s(outerInstance->getRuleNames()[(size_t)outerInstance->ctx->getRuleIndex()])
|
||||
<< antlrcpp::ws2s(outerInstance->getRuleNames()[(size_t)outerInstance->getContext()->getRuleIndex()])
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void Parser::TraceListener::visitErrorNode(tree::ErrorNode *node) {
|
||||
void Parser::TraceListener::visitErrorNode(std::shared_ptr<tree::ErrorNode> node) {
|
||||
}
|
||||
|
||||
void Parser::TraceListener::exitEveryRule(ParserRuleContext *ctx) {
|
||||
void Parser::TraceListener::exitEveryRule(ParserRuleContextRef ctx) {
|
||||
std::cout << "exit "
|
||||
<< antlrcpp::ws2s(outerInstance->getRuleNames()[(size_t)ctx->getRuleIndex()])
|
||||
<< ", LT(1)=" << antlrcpp::ws2s(outerInstance->_input->LT(1)->getText())
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
Parser::TrimToSizeListener *const Parser::TrimToSizeListener::INSTANCE = new Parser::TrimToSizeListener();
|
||||
const std::shared_ptr<Parser::TrimToSizeListener> Parser::TrimToSizeListener::INSTANCE =
|
||||
std::make_shared<Parser::TrimToSizeListener>();
|
||||
|
||||
void Parser::TrimToSizeListener::enterEveryRule(ParserRuleContext *ctx) {
|
||||
void Parser::TrimToSizeListener::enterEveryRule(ParserRuleContextRef ctx) {
|
||||
}
|
||||
|
||||
void Parser::TrimToSizeListener::visitTerminal(tree::TerminalNode *node) {
|
||||
void Parser::TrimToSizeListener::visitTerminal(std::shared_ptr<tree::TerminalNode> node) {
|
||||
}
|
||||
|
||||
void Parser::TrimToSizeListener::visitErrorNode(tree::ErrorNode *node) {
|
||||
void Parser::TrimToSizeListener::visitErrorNode(std::shared_ptr<tree::ErrorNode> node) {
|
||||
}
|
||||
|
||||
void Parser::TrimToSizeListener::exitEveryRule(ParserRuleContext *ctx) {
|
||||
void Parser::TrimToSizeListener::exitEveryRule(ParserRuleContextRef ctx) {
|
||||
ctx->children.shrink_to_fit();
|
||||
}
|
||||
|
||||
Parser::Parser(TokenStream* input) : _tracer(this) {
|
||||
Parser::Parser(TokenStream *input) {
|
||||
InitializeInstanceFields();
|
||||
setInputStream(input);
|
||||
}
|
||||
|
@ -106,9 +109,8 @@ void Parser::reset() {
|
|||
if (getInputStream() != nullptr) {
|
||||
getInputStream()->seek(0);
|
||||
}
|
||||
_errHandler->reset(this);
|
||||
_errHandler->reset(this); // Watch out, this is not shared_ptr.reset().
|
||||
|
||||
delete ctx;
|
||||
_syntaxErrors = 0;
|
||||
setTrace(false);
|
||||
_precedenceStack.clear();
|
||||
|
@ -119,8 +121,8 @@ void Parser::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
Token *Parser::match(int ttype) {
|
||||
Token *t = getCurrentToken();
|
||||
TokenRef Parser::match(int ttype) {
|
||||
TokenRef t = getCurrentToken();
|
||||
if (t->getType() == ttype) {
|
||||
_errHandler->reportMatch(this);
|
||||
consume();
|
||||
|
@ -129,14 +131,14 @@ Token *Parser::match(int ttype) {
|
|||
if (_buildParseTrees && t->getTokenIndex() == -1) {
|
||||
// we must have conjured up a new token during single token insertion
|
||||
// if it's not the current symbol
|
||||
ctx->addErrorNode(t);
|
||||
_ctx->addErrorNode(t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
Token *Parser::matchWildcard() {
|
||||
Token *t = getCurrentToken();
|
||||
TokenRef Parser::matchWildcard() {
|
||||
TokenRef t = getCurrentToken();
|
||||
if (t->getType() > 0) {
|
||||
_errHandler->reportMatch(this);
|
||||
consume();
|
||||
|
@ -145,7 +147,7 @@ Token *Parser::matchWildcard() {
|
|||
if (_buildParseTrees && t->getTokenIndex() == -1) {
|
||||
// we must have conjured up a new token during single token insertion
|
||||
// if it's not the current symbol
|
||||
ctx->addErrorNode(t);
|
||||
_ctx->addErrorNode(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,29 +177,19 @@ bool Parser::getTrimParseTree() {
|
|||
return std::find(getParseListeners().begin(), getParseListeners().end(), TrimToSizeListener::INSTANCE) != getParseListeners().end();
|
||||
}
|
||||
|
||||
std::vector<tree::ParseTreeListener*> Parser::getParseListeners() {
|
||||
std::vector<tree::ParseTreeListener*> listeners = _parseListeners;
|
||||
if (listeners.empty()) {
|
||||
std::vector<tree::ParseTreeListener*> emptyList;
|
||||
return emptyList;
|
||||
}
|
||||
|
||||
return listeners;
|
||||
std::vector<std::shared_ptr<tree::ParseTreeListener>> Parser::getParseListeners() {
|
||||
return _parseListeners;
|
||||
}
|
||||
|
||||
void Parser::addParseListener(tree::ParseTreeListener *listener) {
|
||||
if (listener == nullptr) {
|
||||
void Parser::addParseListener(std::shared_ptr<tree::ParseTreeListener> listener) {
|
||||
if (!listener) {
|
||||
throw NullPointerException("listener");
|
||||
}
|
||||
|
||||
if (_parseListeners.empty()) {
|
||||
_parseListeners = std::vector<tree::ParseTreeListener*>();
|
||||
}
|
||||
|
||||
this->_parseListeners.push_back(listener);
|
||||
}
|
||||
|
||||
void Parser::removeParseListener(tree::ParseTreeListener *listener) {
|
||||
void Parser::removeParseListener(std::shared_ptr<tree::ParseTreeListener> listener) {
|
||||
if (!_parseListeners.empty()) {
|
||||
auto it = std::find(_parseListeners.begin(), _parseListeners.end(), listener);
|
||||
if (it != _parseListeners.end()) {
|
||||
|
@ -212,17 +204,16 @@ void Parser::removeParseListeners() {
|
|||
|
||||
void Parser::triggerEnterRuleEvent() {
|
||||
for (auto listener : _parseListeners) {
|
||||
listener->enterEveryRule(ctx);
|
||||
ctx->enterRule(listener);
|
||||
listener->enterEveryRule(_ctx);
|
||||
_ctx->enterRule(listener);
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::triggerExitRuleEvent() {
|
||||
// reverse order walk of listeners
|
||||
for (auto it = _parseListeners.rbegin(); it != _parseListeners.rend(); ++it) {
|
||||
tree::ParseTreeListener *listener = *it;
|
||||
ctx->exitRule(*it);
|
||||
listener->exitEveryRule(ctx);
|
||||
_ctx->exitRule(*it);
|
||||
(*it)->exitEveryRule(_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +221,7 @@ int Parser::getNumberOfSyntaxErrors() {
|
|||
return _syntaxErrors;
|
||||
}
|
||||
|
||||
TokenFactory<CommonToken*> *Parser::getTokenFactory() {
|
||||
std::shared_ptr<TokenFactory<CommonToken>> Parser::getTokenFactory() {
|
||||
return _input->getTokenSource()->getTokenFactory();
|
||||
}
|
||||
|
||||
|
@ -257,20 +248,21 @@ const atn::ATN& Parser::getATNWithBypassAlts() {
|
|||
return bypassAltsAtnCache[serializedAtn];
|
||||
}
|
||||
|
||||
tree::pattern::ParseTreePattern *Parser::compileParseTreePattern(const std::wstring &pattern, int patternRuleIndex) {
|
||||
tree::pattern::ParseTreePattern Parser::compileParseTreePattern(const std::wstring &pattern, int patternRuleIndex) {
|
||||
if (getTokenStream() != nullptr) {
|
||||
TokenSource *tokenSource = getTokenStream()->getTokenSource();
|
||||
if (dynamic_cast<Lexer*>(tokenSource) != nullptr) {
|
||||
Lexer *lexer = static_cast<Lexer*>(tokenSource);
|
||||
if (is<Lexer*>(tokenSource)) {
|
||||
Lexer *lexer = dynamic_cast<Lexer *>(tokenSource);
|
||||
return compileParseTreePattern(pattern, patternRuleIndex, lexer);
|
||||
}
|
||||
}
|
||||
throw UnsupportedOperationException("Parser can't discover a lexer to use");
|
||||
}
|
||||
|
||||
tree::pattern::ParseTreePattern *Parser::compileParseTreePattern(const std::wstring &pattern, int patternRuleIndex, Lexer *lexer) {
|
||||
tree::pattern::ParseTreePatternMatcher *m = new tree::pattern::ParseTreePatternMatcher(lexer, this);
|
||||
return m->compile(pattern, patternRuleIndex);
|
||||
tree::pattern::ParseTreePattern Parser::compileParseTreePattern(const std::wstring &pattern, int patternRuleIndex,
|
||||
Lexer *lexer) {
|
||||
tree::pattern::ParseTreePatternMatcher m(lexer, this);
|
||||
return m.compile(pattern, patternRuleIndex);
|
||||
}
|
||||
|
||||
std::shared_ptr<ANTLRErrorStrategy> Parser::getErrorHandler() {
|
||||
|
@ -281,7 +273,7 @@ void Parser::setErrorHandler(std::shared_ptr<ANTLRErrorStrategy> handler) {
|
|||
_errHandler = handler;
|
||||
}
|
||||
|
||||
TokenStream *Parser::getInputStream() {
|
||||
IntStream* Parser::getInputStream() {
|
||||
return getTokenStream();
|
||||
}
|
||||
|
||||
|
@ -289,7 +281,7 @@ void Parser::setInputStream(IntStream *input) {
|
|||
setTokenStream(static_cast<TokenStream*>(input));
|
||||
}
|
||||
|
||||
TokenStream *Parser::getTokenStream() {
|
||||
TokenStream* Parser::getTokenStream() {
|
||||
return _input;
|
||||
}
|
||||
|
||||
|
@ -300,7 +292,7 @@ void Parser::setTokenStream(TokenStream *input) {
|
|||
_input = input;
|
||||
}
|
||||
|
||||
Token *Parser::getCurrentToken() {
|
||||
TokenRef Parser::getCurrentToken() {
|
||||
return _input->LT(1);
|
||||
}
|
||||
|
||||
|
@ -308,7 +300,7 @@ void Parser::notifyErrorListeners(const std::wstring &msg) {
|
|||
notifyErrorListeners(getCurrentToken(), msg, nullptr);
|
||||
}
|
||||
|
||||
void Parser::notifyErrorListeners(Token *offendingToken, const std::wstring &msg, std::exception_ptr e) {
|
||||
void Parser::notifyErrorListeners(TokenRef offendingToken, const std::wstring &msg, std::exception_ptr e) {
|
||||
_syntaxErrors++;
|
||||
int line = -1;
|
||||
int charPositionInLine = -1;
|
||||
|
@ -319,22 +311,22 @@ void Parser::notifyErrorListeners(Token *offendingToken, const std::wstring &msg
|
|||
listener->syntaxError(this, offendingToken, (size_t)line, charPositionInLine, msg, e);
|
||||
}
|
||||
|
||||
Token *Parser::consume() {
|
||||
Token *o = getCurrentToken();
|
||||
TokenRef Parser::consume() {
|
||||
TokenRef o = getCurrentToken();
|
||||
if (o->getType() != EOF) {
|
||||
getInputStream()->consume();
|
||||
}
|
||||
bool hasListener = _parseListeners.size() > 0 && !_parseListeners.empty();
|
||||
if (_buildParseTrees || hasListener) {
|
||||
if (_errHandler->inErrorRecoveryMode(this)) {
|
||||
tree::ErrorNode *node = ctx->addErrorNode(o);
|
||||
std::shared_ptr<tree::ErrorNode> node = _ctx->addErrorNode(o);
|
||||
if (_parseListeners.size() > 0) {
|
||||
for (auto listener : _parseListeners) {
|
||||
listener->visitErrorNode(node);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tree::TerminalNode *node = ctx->addChild(o);
|
||||
std::shared_ptr<tree::TerminalNode> node = _ctx->addChild(o);
|
||||
if (_parseListeners.size() > 0) {
|
||||
for (auto listener : _parseListeners) {
|
||||
listener->visitTerminal(node);
|
||||
|
@ -346,17 +338,18 @@ Token *Parser::consume() {
|
|||
}
|
||||
|
||||
void Parser::addContextToParseTree() {
|
||||
ParserRuleContext *parent = static_cast<ParserRuleContext*>(ctx->parent);
|
||||
// add current context to parent if we have a parent
|
||||
if (parent != nullptr) {
|
||||
parent->addChild(ctx);
|
||||
}
|
||||
// Add current context to parent if we have a parent.
|
||||
if (_ctx->parent.expired())
|
||||
return;
|
||||
|
||||
ParserRuleContextRef parent = std::dynamic_pointer_cast<ParserRuleContext>(_ctx->parent.lock());
|
||||
parent->addChild(_ctx);
|
||||
}
|
||||
|
||||
void Parser::enterRule(ParserRuleContext *localctx, int state, int ruleIndex) {
|
||||
void Parser::enterRule(ParserRuleContextRef localctx, int state, int ruleIndex) {
|
||||
setState(state);
|
||||
ctx = localctx;
|
||||
ctx->start = _input->LT(1);
|
||||
_ctx = localctx;
|
||||
_ctx->start = _input->LT(1);
|
||||
if (_buildParseTrees) {
|
||||
addContextToParseTree();
|
||||
}
|
||||
|
@ -366,52 +359,52 @@ void Parser::enterRule(ParserRuleContext *localctx, int state, int ruleIndex) {
|
|||
}
|
||||
|
||||
void Parser::exitRule() {
|
||||
ctx->stop = _input->LT(-1);
|
||||
_ctx->stop = _input->LT(-1);
|
||||
// trigger event on ctx, before it reverts to parent
|
||||
if (_parseListeners.size() > 0) {
|
||||
triggerExitRuleEvent();
|
||||
}
|
||||
setState(ctx->invokingState);
|
||||
ctx = static_cast<ParserRuleContext*>(ctx->parent);
|
||||
setState(_ctx->invokingState);
|
||||
_ctx = std::dynamic_pointer_cast<ParserRuleContext>(_ctx->parent.lock());
|
||||
}
|
||||
|
||||
void Parser::enterOuterAlt(ParserRuleContext *localctx, int altNum) {
|
||||
void Parser::enterOuterAlt(ParserRuleContextRef localctx, int altNum) {
|
||||
// if we have new localctx, make sure we replace existing ctx
|
||||
// that is previous child of parse tree
|
||||
if (_buildParseTrees && ctx != localctx) {
|
||||
ParserRuleContext *parent = static_cast<ParserRuleContext*>(ctx->parent);
|
||||
if (parent != nullptr) {
|
||||
if (_buildParseTrees && _ctx != localctx) {
|
||||
if (!_ctx->parent.expired()) {
|
||||
ParserRuleContextRef parent = std::dynamic_pointer_cast<ParserRuleContext>(_ctx->parent.lock());
|
||||
parent->removeLastChild();
|
||||
parent->addChild(localctx);
|
||||
}
|
||||
}
|
||||
ctx = localctx;
|
||||
_ctx = localctx;
|
||||
}
|
||||
|
||||
void Parser::enterRecursionRule(ParserRuleContext *localctx, int ruleIndex) {
|
||||
void Parser::enterRecursionRule(ParserRuleContextRef localctx, int ruleIndex) {
|
||||
enterRecursionRule(localctx, getATN().ruleToStartState[(size_t)ruleIndex]->stateNumber, ruleIndex, 0);
|
||||
}
|
||||
|
||||
void Parser::enterRecursionRule(ParserRuleContext *localctx, int state, int ruleIndex, int precedence) {
|
||||
void Parser::enterRecursionRule(ParserRuleContextRef localctx, int state, int ruleIndex, int precedence) {
|
||||
setState(state);
|
||||
_precedenceStack.push_back(precedence);
|
||||
ctx = localctx;
|
||||
ctx->start = _input->LT(1);
|
||||
_ctx = localctx;
|
||||
_ctx->start = _input->LT(1);
|
||||
if (_parseListeners.size() > 0) {
|
||||
triggerEnterRuleEvent(); // simulates rule entry for left-recursive rules
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::pushNewRecursionContext(ParserRuleContext *localctx, int state, int ruleIndex) {
|
||||
ParserRuleContext *previous = ctx;
|
||||
void Parser::pushNewRecursionContext(ParserRuleContextRef localctx, int state, int ruleIndex) {
|
||||
ParserRuleContextRef previous = _ctx;
|
||||
previous->parent = localctx;
|
||||
previous->invokingState = state;
|
||||
previous->stop = _input->LT(-1);
|
||||
|
||||
ctx = localctx;
|
||||
ctx->start = previous->start;
|
||||
_ctx = localctx;
|
||||
_ctx->start = previous->start;
|
||||
if (_buildParseTrees) {
|
||||
ctx->addChild(previous);
|
||||
_ctx->addChild(previous);
|
||||
}
|
||||
|
||||
if (_parseListeners.size() > 0) {
|
||||
|
@ -419,50 +412,52 @@ void Parser::pushNewRecursionContext(ParserRuleContext *localctx, int state, int
|
|||
}
|
||||
}
|
||||
|
||||
void Parser::unrollRecursionContexts(ParserRuleContext *_parentctx) {
|
||||
void Parser::unrollRecursionContexts(ParserRuleContextRef parentctx) {
|
||||
_precedenceStack.pop_back();
|
||||
ctx->stop = _input->LT(-1);
|
||||
ParserRuleContext *retctx = ctx; // save current ctx (return value)
|
||||
_ctx->stop = _input->LT(-1);
|
||||
ParserRuleContextRef retctx = _ctx; // save current ctx (return value)
|
||||
|
||||
// unroll so ctx is as it was before call to recursive method
|
||||
if (_parseListeners.size() > 0) {
|
||||
while (ctx != _parentctx) {
|
||||
while (_ctx != parentctx) {
|
||||
triggerExitRuleEvent();
|
||||
ctx = static_cast<ParserRuleContext*>(ctx->parent);
|
||||
_ctx = std::dynamic_pointer_cast<ParserRuleContext>(_ctx->parent.lock());
|
||||
}
|
||||
} else {
|
||||
ctx = _parentctx;
|
||||
_ctx = parentctx;
|
||||
}
|
||||
|
||||
// hook into tree
|
||||
retctx->parent = _parentctx;
|
||||
retctx->parent = parentctx;
|
||||
|
||||
if (_buildParseTrees && _parentctx != nullptr) {
|
||||
if (_buildParseTrees && parentctx != nullptr) {
|
||||
// add return ctx into invoking rule's tree
|
||||
_parentctx->addChild(retctx);
|
||||
parentctx->addChild(retctx);
|
||||
}
|
||||
}
|
||||
|
||||
ParserRuleContext *Parser::getInvokingContext(int ruleIndex) {
|
||||
ParserRuleContext *p = ctx;
|
||||
while (p != nullptr) {
|
||||
ParserRuleContextRef Parser::getInvokingContext(int ruleIndex) {
|
||||
ParserRuleContextRef p = _ctx;
|
||||
while (p) {
|
||||
if (p->getRuleIndex() == ruleIndex) {
|
||||
return p;
|
||||
}
|
||||
p = static_cast<ParserRuleContext*>(p->parent);
|
||||
if (p->parent.expired())
|
||||
break;
|
||||
p = std::dynamic_pointer_cast<ParserRuleContext>(p->parent.lock());
|
||||
}
|
||||
return nullptr;
|
||||
return ParserRuleContextRef();
|
||||
}
|
||||
|
||||
ParserRuleContext *Parser::getContext() {
|
||||
return ctx;
|
||||
ParserRuleContextRef Parser::getContext() {
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
void Parser::setContext(ParserRuleContext *ctx) {
|
||||
ctx = ctx;
|
||||
void Parser::setContext(ParserRuleContextRef ctx) {
|
||||
_ctx = ctx;
|
||||
}
|
||||
|
||||
bool Parser::precpred(RuleContext *localctx, int precedence) {
|
||||
bool Parser::precpred(RuleContextRef localctx, int precedence) {
|
||||
return precedence >= _precedenceStack.back();
|
||||
}
|
||||
|
||||
|
@ -473,7 +468,7 @@ bool Parser::inContext(const std::wstring &context) {
|
|||
|
||||
bool Parser::isExpectedToken(int symbol) {
|
||||
const atn::ATN &atn = getInterpreter<atn::ParserATNSimulator>()->atn;
|
||||
ParserRuleContext *ctx = ctx;
|
||||
ParserRuleContextRef ctx = _ctx;
|
||||
atn::ATNState *s = atn.states[(size_t)getState()];
|
||||
misc::IntervalSet following = atn.nextTokens(s);
|
||||
|
||||
|
@ -485,7 +480,7 @@ bool Parser::isExpectedToken(int symbol) {
|
|||
return false;
|
||||
}
|
||||
|
||||
while (ctx != nullptr && ctx->invokingState >= 0 && following.contains(Token::EPSILON)) {
|
||||
while (ctx && ctx->invokingState >= 0 && following.contains(Token::EPSILON)) {
|
||||
atn::ATNState *invokingState = atn.states[(size_t)ctx->invokingState];
|
||||
atn::RuleTransition *rt = static_cast<atn::RuleTransition*>(invokingState->transition(0));
|
||||
following = atn.nextTokens(rt->followState);
|
||||
|
@ -493,7 +488,7 @@ bool Parser::isExpectedToken(int symbol) {
|
|||
return true;
|
||||
}
|
||||
|
||||
ctx = static_cast<ParserRuleContext*>(ctx->parent);
|
||||
ctx = std::dynamic_pointer_cast<ParserRuleContext>(ctx->parent.lock());
|
||||
}
|
||||
|
||||
if (following.contains(Token::EPSILON) && symbol == EOF) {
|
||||
|
@ -521,18 +516,18 @@ int Parser::getRuleIndex(const std::wstring &ruleName) {
|
|||
return m.at(ruleName);
|
||||
}
|
||||
|
||||
ParserRuleContext *Parser::getRuleContext() {
|
||||
return ctx;
|
||||
ParserRuleContextRef Parser::getRuleContext() {
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> Parser::getRuleInvocationStack() {
|
||||
return getRuleInvocationStack(ctx);
|
||||
return getRuleInvocationStack(_ctx);
|
||||
}
|
||||
|
||||
std::vector<std::wstring> Parser::getRuleInvocationStack(RuleContext *p) {
|
||||
std::vector<std::wstring> Parser::getRuleInvocationStack(RuleContextRef p) {
|
||||
std::vector<std::wstring> ruleNames = getRuleNames();
|
||||
std::vector<std::wstring> stack = std::vector<std::wstring>();
|
||||
while (p != nullptr) {
|
||||
while (p) {
|
||||
// compute what follows who invoked us
|
||||
ssize_t ruleIndex = p->getRuleIndex();
|
||||
if (ruleIndex < 0) {
|
||||
|
@ -540,7 +535,9 @@ std::vector<std::wstring> Parser::getRuleInvocationStack(RuleContext *p) {
|
|||
} else {
|
||||
stack.push_back(ruleNames[(size_t)ruleIndex]);
|
||||
}
|
||||
p = p->parent;
|
||||
if (p->parent.expired())
|
||||
break;
|
||||
p = p->parent.lock();
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
@ -586,10 +583,14 @@ std::string Parser::getSourceName() {
|
|||
|
||||
void Parser::setTrace(bool trace) {
|
||||
if (!trace) {
|
||||
removeParseListener(&_tracer);
|
||||
if (_tracer)
|
||||
removeParseListener(_tracer);
|
||||
_tracer.reset();
|
||||
} else {
|
||||
removeParseListener(&_tracer); // Just in case this is triggered multiple times.
|
||||
addParseListener(&_tracer);
|
||||
if (_tracer)
|
||||
removeParseListener(_tracer); // Just in case this is triggered multiple times.
|
||||
_tracer = std::make_shared<TraceListener>(this);
|
||||
addParseListener(_tracer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,10 +51,10 @@ namespace runtime {
|
|||
TraceListener(Parser *outerInstance);
|
||||
virtual ~TraceListener() {};
|
||||
|
||||
virtual void enterEveryRule(ParserRuleContext *ctx) override;
|
||||
virtual void visitTerminal(tree::TerminalNode *node) override;
|
||||
virtual void visitErrorNode(tree::ErrorNode *node) override;
|
||||
virtual void exitEveryRule(ParserRuleContext *ctx) override;
|
||||
virtual void enterEveryRule(ParserRuleContextRef ctx) override;
|
||||
virtual void visitTerminal(std::shared_ptr<tree::TerminalNode> node) override;
|
||||
virtual void visitErrorNode(std::shared_ptr<tree::ErrorNode> node) override;
|
||||
virtual void exitEveryRule(ParserRuleContextRef ctx) override;
|
||||
|
||||
private:
|
||||
Parser *const outerInstance;
|
||||
|
@ -62,20 +62,14 @@ namespace runtime {
|
|||
|
||||
class TrimToSizeListener : public tree::ParseTreeListener {
|
||||
public:
|
||||
static TrimToSizeListener *const INSTANCE;
|
||||
static const std::shared_ptr<TrimToSizeListener> INSTANCE;
|
||||
|
||||
virtual void enterEveryRule(ParserRuleContext *ctx) override;
|
||||
virtual void visitTerminal(tree::TerminalNode *node) override;
|
||||
virtual void visitErrorNode(tree::ErrorNode *node) override;
|
||||
virtual void exitEveryRule(ParserRuleContext *ctx) override;
|
||||
virtual void enterEveryRule(ParserRuleContextRef ctx) override;
|
||||
virtual void visitTerminal(std::shared_ptr<tree::TerminalNode> node) override;
|
||||
virtual void visitErrorNode(std::shared_ptr<tree::ErrorNode> node) override;
|
||||
virtual void exitEveryRule(ParserRuleContextRef ctx) override;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The <seealso cref="ParserRuleContext"/> object for the currently executing rule.
|
||||
/// This is always non-null during the parsing process.
|
||||
/// </summary>
|
||||
ParserRuleContext *ctx;
|
||||
|
||||
Parser(TokenStream *input);
|
||||
virtual ~Parser();
|
||||
|
||||
|
@ -100,7 +94,7 @@ namespace runtime {
|
|||
/// <exception cref="RecognitionException"> if the current input symbol did not match
|
||||
/// {@code ttype} and the error strategy could not recover from the
|
||||
/// mismatched symbol </exception>
|
||||
virtual Token *match(int ttype);
|
||||
virtual TokenRef match(int ttype);
|
||||
|
||||
/// <summary>
|
||||
/// Match current input symbol as a wildcard. If the symbol type matches
|
||||
|
@ -118,7 +112,7 @@ namespace runtime {
|
|||
/// <exception cref="RecognitionException"> if the current input symbol did not match
|
||||
/// a wildcard and the error strategy could not recover from the mismatched
|
||||
/// symbol </exception>
|
||||
virtual Token *matchWildcard();
|
||||
virtual TokenRef matchWildcard();
|
||||
|
||||
/// <summary>
|
||||
/// Track the <seealso cref="ParserRuleContext"/> objects during the parse and hook
|
||||
|
@ -157,7 +151,7 @@ namespace runtime {
|
|||
/// using the default <seealso cref="Parser.TrimToSizeListener"/> during the parse process. </returns>
|
||||
virtual bool getTrimParseTree();
|
||||
|
||||
virtual std::vector<tree::ParseTreeListener*> getParseListeners();
|
||||
virtual std::vector<std::shared_ptr<tree::ParseTreeListener>> getParseListeners();
|
||||
|
||||
/// <summary>
|
||||
/// Registers {@code listener} to receive events during the parsing process.
|
||||
|
@ -187,7 +181,7 @@ namespace runtime {
|
|||
/// <param name="listener"> the listener to add
|
||||
/// </param>
|
||||
/// <exception cref="NullPointerException"> if {@code} listener is {@code null} </exception>
|
||||
virtual void addParseListener(tree::ParseTreeListener *listener);
|
||||
virtual void addParseListener(std::shared_ptr<tree::ParseTreeListener> listener);
|
||||
|
||||
/// <summary>
|
||||
/// Remove {@code listener} from the list of parse listeners.
|
||||
|
@ -198,7 +192,7 @@ namespace runtime {
|
|||
/// <seealso cref= #addParseListener
|
||||
/// </seealso>
|
||||
/// <param name="listener"> the listener to remove </param>
|
||||
virtual void removeParseListener(tree::ParseTreeListener *listener);
|
||||
virtual void removeParseListener(std::shared_ptr<tree::ParseTreeListener> listener);
|
||||
|
||||
/// <summary>
|
||||
/// Remove all parse listeners.
|
||||
|
@ -225,7 +219,7 @@ namespace runtime {
|
|||
/// <seealso cref= #notifyErrorListeners </seealso>
|
||||
virtual int getNumberOfSyntaxErrors();
|
||||
|
||||
virtual TokenFactory<CommonToken*> *getTokenFactory() override;
|
||||
virtual std::shared_ptr<TokenFactory<CommonToken>> getTokenFactory() override;
|
||||
|
||||
/// <summary>
|
||||
/// Tell our token source and error strategy about a new way to create tokens. </summary>
|
||||
|
@ -249,35 +243,35 @@ namespace runtime {
|
|||
/// String id = m.get("ID");
|
||||
/// </pre>
|
||||
/// </summary>
|
||||
virtual tree::pattern::ParseTreePattern *compileParseTreePattern(const std::wstring &pattern, int patternRuleIndex);
|
||||
virtual tree::pattern::ParseTreePattern compileParseTreePattern(const std::wstring &pattern, int patternRuleIndex);
|
||||
|
||||
/// <summary>
|
||||
/// The same as <seealso cref="#compileParseTreePattern(String, int)"/> but specify a
|
||||
/// <seealso cref="Lexer"/> rather than trying to deduce it from this parser.
|
||||
/// </summary>
|
||||
virtual tree::pattern::ParseTreePattern *compileParseTreePattern(const std::wstring &pattern, int patternRuleIndex, Lexer *lexer);
|
||||
virtual tree::pattern::ParseTreePattern compileParseTreePattern(const std::wstring &pattern, int patternRuleIndex,
|
||||
Lexer *lexer);
|
||||
|
||||
virtual std::shared_ptr<ANTLRErrorStrategy> getErrorHandler();
|
||||
virtual void setErrorHandler(std::shared_ptr<ANTLRErrorStrategy> handler);
|
||||
|
||||
virtual TokenStream *getInputStream() override;
|
||||
virtual IntStream* getInputStream() override;
|
||||
void setInputStream(IntStream *input) override;
|
||||
|
||||
virtual TokenStream *getTokenStream();
|
||||
virtual TokenStream* getTokenStream();
|
||||
|
||||
/// <summary>
|
||||
/// Set the token stream and reset the parser. </summary>
|
||||
/// Set the token stream and reset the parser.
|
||||
virtual void setTokenStream(TokenStream *input);
|
||||
|
||||
/// <summary>
|
||||
/// Match needs to return the current input symbol, which gets put
|
||||
/// into the label for the associated token ref; e.g., x=ID.
|
||||
/// </summary>
|
||||
virtual Token *getCurrentToken();
|
||||
virtual TokenRef getCurrentToken();
|
||||
|
||||
void notifyErrorListeners(const std::wstring &msg);
|
||||
|
||||
virtual void notifyErrorListeners(Token *offendingToken, const std::wstring &msg, std::exception_ptr e);
|
||||
virtual void notifyErrorListeners(TokenRef offendingToken, const std::wstring &msg, std::exception_ptr e);
|
||||
|
||||
/// <summary>
|
||||
/// Consume and return the <seealso cref="#getCurrentToken current symbol"/>.
|
||||
|
@ -300,38 +294,37 @@ namespace runtime {
|
|||
/// <seealso cref="ParseTreeListener#visitErrorNode"/> is called on any parse
|
||||
/// listeners.
|
||||
/// </summary>
|
||||
virtual Token *consume();
|
||||
virtual TokenRef consume();
|
||||
|
||||
/// <summary>
|
||||
/// Always called by generated parsers upon entry to a rule. Access field
|
||||
/// <seealso cref="#_ctx"/> get the current context.
|
||||
/// </summary>
|
||||
virtual void enterRule(ParserRuleContext *localctx, int state, int ruleIndex);
|
||||
virtual void enterRule(ParserRuleContextRef localctx, int state, int ruleIndex);
|
||||
|
||||
virtual void exitRule();
|
||||
|
||||
virtual void enterOuterAlt(ParserRuleContext *localctx, int altNum);
|
||||
virtual void enterOuterAlt(ParserRuleContextRef localctx, int altNum);
|
||||
|
||||
/// @deprecated Use
|
||||
/// <seealso cref="#enterRecursionRule(ParserRuleContext, int, int, int)"/> instead.
|
||||
virtual void enterRecursionRule(ParserRuleContext *localctx, int ruleIndex);
|
||||
|
||||
virtual void enterRecursionRule(ParserRuleContext *localctx, int state, int ruleIndex, int precedence);
|
||||
virtual void enterRecursionRule(ParserRuleContextRef localctx, int ruleIndex);
|
||||
virtual void enterRecursionRule(ParserRuleContextRef localctx, int state, int ruleIndex, int precedence);
|
||||
|
||||
/// <summary>
|
||||
/// Like <seealso cref="#enterRule"/> but for recursive rules.
|
||||
/// </summary>
|
||||
virtual void pushNewRecursionContext(ParserRuleContext *localctx, int state, int ruleIndex);
|
||||
virtual void pushNewRecursionContext(ParserRuleContextRef localctx, int state, int ruleIndex);
|
||||
|
||||
virtual void unrollRecursionContexts(ParserRuleContext *_parentctx);
|
||||
virtual void unrollRecursionContexts(ParserRuleContextRef parentctx);
|
||||
|
||||
virtual ParserRuleContext *getInvokingContext(int ruleIndex);
|
||||
virtual ParserRuleContextRef getInvokingContext(int ruleIndex);
|
||||
|
||||
virtual ParserRuleContext *getContext();
|
||||
virtual std::shared_ptr<ParserRuleContext> getContext();
|
||||
|
||||
virtual void setContext(ParserRuleContext *ctx);
|
||||
virtual void setContext(ParserRuleContextRef ctx);
|
||||
|
||||
virtual bool precpred(RuleContext *localctx, int precedence) override;
|
||||
virtual bool precpred(RuleContextRef localctx, int precedence) override;
|
||||
|
||||
virtual bool inContext(const std::wstring &context);
|
||||
|
||||
|
@ -364,7 +357,7 @@ namespace runtime {
|
|||
/// Get a rule's index (i.e., {@code RULE_ruleName} field) or -1 if not found. </summary>
|
||||
virtual int getRuleIndex(const std::wstring &ruleName);
|
||||
|
||||
virtual ParserRuleContext *getRuleContext();
|
||||
virtual ParserRuleContextRef getRuleContext();
|
||||
|
||||
/// <summary>
|
||||
/// Return List<String> of the rule names in your parser instance
|
||||
|
@ -376,7 +369,7 @@ namespace runtime {
|
|||
/// </summary>
|
||||
virtual std::vector<std::wstring> getRuleInvocationStack();
|
||||
|
||||
virtual std::vector<std::wstring> getRuleInvocationStack(RuleContext *p);
|
||||
virtual std::vector<std::wstring> getRuleInvocationStack(RuleContextRef p);
|
||||
|
||||
/// <summary>
|
||||
/// For debugging and other purposes. </summary>
|
||||
|
@ -395,6 +388,10 @@ namespace runtime {
|
|||
virtual void setTrace(bool trace);
|
||||
|
||||
protected:
|
||||
/// The ParserRuleContext object for the currently executing rule.
|
||||
/// This is always non-null during the parsing process.
|
||||
ParserRuleContextRef _ctx;
|
||||
|
||||
/// The error handling strategy for the parser. The default is DefaultErrorStrategy.
|
||||
/// See also getErrorHandler.
|
||||
std::shared_ptr<ANTLRErrorStrategy> _errHandler;
|
||||
|
@ -423,7 +420,7 @@ namespace runtime {
|
|||
/// events during the parse.
|
||||
/// </summary>
|
||||
/// <seealso cref= #addParseListener </seealso>
|
||||
std::vector<tree::ParseTreeListener*> _parseListeners;
|
||||
std::vector<std::shared_ptr<tree::ParseTreeListener>> _parseListeners;
|
||||
|
||||
/// <summary>
|
||||
/// The number of syntax errors reported during parsing. This value is
|
||||
|
@ -434,10 +431,9 @@ namespace runtime {
|
|||
virtual void addContextToParseTree();
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
/// This field maps from the serialized ATN string to the deserialized <seealso cref="ATN"/> with
|
||||
/// bypass alternatives.
|
||||
/// </summary>
|
||||
///
|
||||
/// <seealso cref= ATNDeserializationOptions#isGenerateRuleBypassTransitions() </seealso>
|
||||
static std::map<std::wstring, atn::ATN> bypassAltsAtnCache;
|
||||
|
||||
|
@ -446,7 +442,7 @@ namespace runtime {
|
|||
/// 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.
|
||||
TraceListener _tracer;
|
||||
std::shared_ptr<TraceListener> _tracer;
|
||||
|
||||
void InitializeInstanceFields();
|
||||
};
|
||||
|
|
|
@ -103,10 +103,12 @@ std::wstring ParserInterpreter::getGrammarFileName() const {
|
|||
return _grammarFileName;
|
||||
}
|
||||
|
||||
ParserRuleContext *ParserInterpreter::parse(int startRuleIndex) {
|
||||
ParserRuleContextRef ParserInterpreter::parse(int startRuleIndex) {
|
||||
atn::RuleStartState *startRuleStartState = _atn.ruleToStartState[(size_t)startRuleIndex];
|
||||
|
||||
InterpreterRuleContext *rootContext = new InterpreterRuleContext(nullptr, atn::ATNState::INVALID_STATE_NUMBER, startRuleIndex);
|
||||
std::shared_ptr<InterpreterRuleContext> rootContext =
|
||||
std::make_shared<InterpreterRuleContext>(std::weak_ptr<ParserRuleContext>(), atn::ATNState::INVALID_STATE_NUMBER, startRuleIndex);
|
||||
|
||||
if (startRuleStartState->isPrecedenceRule) {
|
||||
enterRecursionRule(rootContext, startRuleStartState->stateNumber, startRuleIndex, 0);
|
||||
} else {
|
||||
|
@ -118,7 +120,7 @@ ParserRuleContext *ParserInterpreter::parse(int startRuleIndex) {
|
|||
switch (p->getStateType()) {
|
||||
case atn::ATNState::RULE_STOP :
|
||||
// pop; return from rule
|
||||
if (ctx->isEmpty()) {
|
||||
if (_ctx->isEmpty()) {
|
||||
exitRule();
|
||||
return rootContext;
|
||||
}
|
||||
|
@ -133,8 +135,8 @@ ParserRuleContext *ParserInterpreter::parse(int startRuleIndex) {
|
|||
}
|
||||
}
|
||||
|
||||
void ParserInterpreter::enterRecursionRule(ParserRuleContext *localctx, int state, int ruleIndex, int precedence) {
|
||||
_parentContextStack.push({ ctx, localctx->invokingState });
|
||||
void ParserInterpreter::enterRecursionRule(ParserRuleContextRef localctx, int state, int ruleIndex, int precedence) {
|
||||
_parentContextStack.push({ _ctx, localctx->invokingState });
|
||||
Parser::enterRecursionRule(localctx, state, ruleIndex, precedence);
|
||||
}
|
||||
|
||||
|
@ -145,7 +147,7 @@ atn::ATNState *ParserInterpreter::getATNState() {
|
|||
void ParserInterpreter::visitState(atn::ATNState *p) {
|
||||
int edge;
|
||||
if (p->getNumberOfTransitions() > 1) {
|
||||
edge = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, ((atn::DecisionState*)p)->decision, ctx);
|
||||
edge = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, ((atn::DecisionState*)p)->decision, _ctx);
|
||||
} else {
|
||||
edge = 1;
|
||||
}
|
||||
|
@ -153,9 +155,9 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
|
|||
atn::Transition *transition = p->transition((size_t)edge - 1);
|
||||
switch (transition->getSerializationType()) {
|
||||
case atn::Transition::EPSILON:
|
||||
if (_pushRecursionContextStates.data[(size_t)p->stateNumber] == 1 && !(dynamic_cast<atn::LoopEndState*>(transition->target) != nullptr)) {
|
||||
InterpreterRuleContext *ruleContext = new InterpreterRuleContext(_parentContextStack.top().first,
|
||||
_parentContextStack.top().second, ctx->getRuleIndex());
|
||||
if (_pushRecursionContextStates[(size_t)p->stateNumber] == 1 && !(dynamic_cast<atn::LoopEndState*>(transition->target) != nullptr)) {
|
||||
std::shared_ptr<InterpreterRuleContext> ruleContext = std::make_shared<InterpreterRuleContext>(_parentContextStack.top().first,
|
||||
_parentContextStack.top().second, _ctx->getRuleIndex());
|
||||
pushNewRecursionContext(ruleContext, _atn.ruleToStartState[(size_t)p->ruleIndex]->stateNumber,
|
||||
(int)ruleContext->getRuleIndex());
|
||||
}
|
||||
|
@ -182,11 +184,11 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
|
|||
{
|
||||
atn::RuleStartState *ruleStartState = (atn::RuleStartState*)(transition->target);
|
||||
int ruleIndex = ruleStartState->ruleIndex;
|
||||
InterpreterRuleContext *ruleContext = new InterpreterRuleContext(ctx, p->stateNumber, ruleIndex);
|
||||
std::shared_ptr<InterpreterRuleContext> ruleContext = std::make_shared<InterpreterRuleContext>(_ctx, p->stateNumber, ruleIndex);
|
||||
if (ruleStartState->isPrecedenceRule) {
|
||||
enterRecursionRule(ruleContext, ruleStartState->stateNumber, ruleIndex, ((atn::RuleTransition*)(transition))->precedence);
|
||||
} else {
|
||||
enterRule(ctx, transition->target->stateNumber, ruleIndex);
|
||||
enterRule(_ctx, transition->target->stateNumber, ruleIndex);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -194,7 +196,7 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
|
|||
case atn::Transition::PREDICATE:
|
||||
{
|
||||
atn::PredicateTransition *predicateTransition = (atn::PredicateTransition*)(transition);
|
||||
if (!sempred(ctx, predicateTransition->ruleIndex, predicateTransition->predIndex)) {
|
||||
if (!sempred(_ctx, predicateTransition->ruleIndex, predicateTransition->predIndex)) {
|
||||
throw FailedPredicateException(this);
|
||||
}
|
||||
}
|
||||
|
@ -203,13 +205,13 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
|
|||
case atn::Transition::ACTION:
|
||||
{
|
||||
atn::ActionTransition *actionTransition = (atn::ActionTransition*)(transition);
|
||||
action(ctx, actionTransition->ruleIndex, actionTransition->actionIndex);
|
||||
action(_ctx, actionTransition->ruleIndex, actionTransition->actionIndex);
|
||||
}
|
||||
break;
|
||||
|
||||
case atn::Transition::PRECEDENCE:
|
||||
{
|
||||
if (!precpred(ctx, ((atn::PrecedencePredicateTransition*)(transition))->precedence)) {
|
||||
if (!precpred(_ctx, ((atn::PrecedencePredicateTransition*)(transition))->precedence)) {
|
||||
throw FailedPredicateException(this, "precpred(_ctx, " + std::to_string(((atn::PrecedencePredicateTransition*)(transition))->precedence) + ")");
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +227,7 @@ void ParserInterpreter::visitState(atn::ATNState *p) {
|
|||
void ParserInterpreter::visitRuleStopState(atn::ATNState *p) {
|
||||
atn::RuleStartState *ruleStartState = _atn.ruleToStartState[(size_t)p->ruleIndex];
|
||||
if (ruleStartState->isPrecedenceRule) {
|
||||
std::pair<ParserRuleContext*, int> parentContext = _parentContextStack.top();
|
||||
std::pair<ParserRuleContextRef, int> parentContext = _parentContextStack.top();
|
||||
_parentContextStack.pop();
|
||||
|
||||
unrollRecursionContexts(parentContext.first);
|
||||
|
|
|
@ -67,9 +67,9 @@ namespace runtime {
|
|||
virtual std::wstring getGrammarFileName() const override;
|
||||
|
||||
/// Begin parsing at startRuleIndex
|
||||
virtual ParserRuleContext *parse(int startRuleIndex);
|
||||
virtual ParserRuleContextRef parse(int startRuleIndex);
|
||||
|
||||
virtual void enterRecursionRule(ParserRuleContext *localctx, int state, int ruleIndex, int precedence) override;
|
||||
virtual void enterRecursionRule(ParserRuleContextRef localctx, int state, int ruleIndex, int precedence) override;
|
||||
|
||||
protected:
|
||||
const std::wstring _grammarFileName;
|
||||
|
@ -82,7 +82,7 @@ namespace runtime {
|
|||
std::vector<dfa::DFA *> _decisionToDFA; // not shared like it is for generated parsers
|
||||
std::shared_ptr<atn::PredictionContextCache> _sharedContextCache;
|
||||
|
||||
std::stack<std::pair<ParserRuleContext*, int>> _parentContextStack;
|
||||
std::stack<std::pair<ParserRuleContextRef, int>> _parentContextStack;
|
||||
|
||||
virtual atn::ATNState *getATNState();
|
||||
virtual void visitState(atn::ATNState *p);
|
||||
|
|
|
@ -38,11 +38,12 @@
|
|||
#include "ParserRuleContext.h"
|
||||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
using namespace antlrcpp;
|
||||
|
||||
ParserRuleContext::ParserRuleContext() {
|
||||
}
|
||||
|
||||
void ParserRuleContext::copyFrom(ParserRuleContext *ctx) {
|
||||
void ParserRuleContext::copyFrom(std::shared_ptr<ParserRuleContext> ctx) {
|
||||
// from RuleContext
|
||||
this->parent = ctx->parent;
|
||||
this->invokingState = ctx->invokingState;
|
||||
|
@ -51,24 +52,22 @@ void ParserRuleContext::copyFrom(ParserRuleContext *ctx) {
|
|||
this->stop = ctx->stop;
|
||||
}
|
||||
|
||||
ParserRuleContext::ParserRuleContext(ParserRuleContext *parent, int invokingStateNumber) : RuleContext(parent, invokingStateNumber) {
|
||||
ParserRuleContext::ParserRuleContext(std::weak_ptr<ParserRuleContext> parent, int invokingStateNumber)
|
||||
: RuleContext(parent, invokingStateNumber) {
|
||||
}
|
||||
|
||||
void ParserRuleContext::enterRule(tree::ParseTreeListener *listener) {
|
||||
void ParserRuleContext::enterRule(std::shared_ptr<tree::ParseTreeListener> listener) {
|
||||
}
|
||||
|
||||
void ParserRuleContext::exitRule(tree::ParseTreeListener *listener) {
|
||||
void ParserRuleContext::exitRule(std::shared_ptr<tree::ParseTreeListener> listener) {
|
||||
}
|
||||
|
||||
tree::TerminalNode *ParserRuleContext::addChild(tree::TerminalNode *t) {
|
||||
if (children.empty()) {
|
||||
children = std::vector<ParseTree*>();
|
||||
}
|
||||
std::shared_ptr<tree::TerminalNode> ParserRuleContext::addChild(std::shared_ptr<tree::TerminalNode> t) {
|
||||
children.push_back(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
RuleContext *ParserRuleContext::addChild(RuleContext *ruleInvocation) {
|
||||
RuleContextRef ParserRuleContext::addChild(RuleContextRef ruleInvocation) {
|
||||
children.push_back(ruleInvocation);
|
||||
return ruleInvocation;
|
||||
}
|
||||
|
@ -79,40 +78,34 @@ void ParserRuleContext::removeLastChild() {
|
|||
}
|
||||
}
|
||||
|
||||
tree::TerminalNode *ParserRuleContext::addChild(Token *matchedToken) {
|
||||
tree::TerminalNodeImpl *t = new tree::TerminalNodeImpl(matchedToken);
|
||||
std::shared_ptr<tree::TerminalNode> ParserRuleContext::addChild(TokenRef matchedToken) {
|
||||
std::shared_ptr<tree::TerminalNodeImpl> t = std::make_shared<tree::TerminalNodeImpl>(matchedToken);
|
||||
addChild(t);
|
||||
t->parent = this;
|
||||
t->parent = shared_from_this();
|
||||
return t;
|
||||
}
|
||||
|
||||
tree::ErrorNode *ParserRuleContext::addErrorNode(Token *badToken) {
|
||||
tree::ErrorNodeImpl *t = new tree::ErrorNodeImpl(badToken);
|
||||
std::shared_ptr<tree::ErrorNode> ParserRuleContext::addErrorNode(TokenRef badToken) {
|
||||
std::shared_ptr<tree::ErrorNodeImpl> t = std::make_shared<tree::ErrorNodeImpl>(badToken);
|
||||
addChild(t);
|
||||
t->parent = this;
|
||||
t->parent = shared_from_this();
|
||||
return t;
|
||||
}
|
||||
|
||||
/// Override to make type more specific
|
||||
ParserRuleContext *ParserRuleContext::getParent()
|
||||
{
|
||||
return static_cast<ParserRuleContext*>(RuleContext::getParent());
|
||||
}
|
||||
|
||||
tree::ParseTree *ParserRuleContext::getChild(std::size_t i) {
|
||||
std::shared_ptr<tree::Tree> ParserRuleContext::getChildReference(std::size_t i) {
|
||||
return children[i];
|
||||
}
|
||||
|
||||
tree::TerminalNode *ParserRuleContext::getToken(int ttype, std::size_t i) {
|
||||
std::shared_ptr<tree::TerminalNode> ParserRuleContext::getToken(int ttype, std::size_t i) {
|
||||
if (i >= children.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t j = 0; // what token with ttype have we found?
|
||||
for (auto &o : children) {
|
||||
if (dynamic_cast<tree::TerminalNode*>(o) != nullptr) {
|
||||
tree::TerminalNode *tnode = static_cast<tree::TerminalNode*>(o);
|
||||
Token *symbol = tnode->getSymbol();
|
||||
for (auto o : children) {
|
||||
if (is<tree::TerminalNode>(o)) {
|
||||
std::shared_ptr<tree::TerminalNode> tnode = std::dynamic_pointer_cast<tree::TerminalNode>(o);
|
||||
TokenRef symbol = tnode->getSymbol();
|
||||
if (symbol->getType() == ttype) {
|
||||
if (j++ == i) {
|
||||
return tnode;
|
||||
|
@ -124,16 +117,13 @@ tree::TerminalNode *ParserRuleContext::getToken(int ttype, std::size_t i) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<tree::TerminalNode*> ParserRuleContext::getTokens(int ttype) {
|
||||
std::vector<tree::TerminalNode*> tokens;
|
||||
std::vector<std::shared_ptr<tree::TerminalNode>> ParserRuleContext::getTokens(int ttype) {
|
||||
std::vector<std::shared_ptr<tree::TerminalNode>> tokens;
|
||||
for (auto &o : children) {
|
||||
if (dynamic_cast<tree::TerminalNode*>(o) != nullptr) {
|
||||
tree::TerminalNode *tnode = static_cast<tree::TerminalNode*>(o);
|
||||
Token *symbol = tnode->getSymbol();
|
||||
if (is<tree::TerminalNode>(o)) {
|
||||
std::shared_ptr<tree::TerminalNode> tnode = std::dynamic_pointer_cast<tree::TerminalNode>(o);
|
||||
TokenRef symbol = tnode->getSymbol();
|
||||
if (symbol->getType() == ttype) {
|
||||
if (tokens.empty()) {
|
||||
tokens = std::vector<tree::TerminalNode*>();
|
||||
}
|
||||
tokens.push_back(tnode);
|
||||
}
|
||||
}
|
||||
|
@ -155,17 +145,20 @@ misc::Interval ParserRuleContext::getSourceInterval() {
|
|||
return misc::Interval(start->getTokenIndex(), stop->getTokenIndex());
|
||||
}
|
||||
|
||||
Token *ParserRuleContext::getStart() {
|
||||
TokenRef ParserRuleContext::getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
Token *ParserRuleContext::getStop() {
|
||||
TokenRef ParserRuleContext::getStop() {
|
||||
return stop;
|
||||
}
|
||||
|
||||
std::wstring ParserRuleContext::toInfoString(Parser *recognizer) {
|
||||
std::vector<std::wstring> rules = recognizer->getRuleInvocationStack(this);
|
||||
std::vector<std::wstring> rules = recognizer->getRuleInvocationStack(shared_from_this());
|
||||
std::reverse(rules.begin(), rules.end());
|
||||
std::wstring rulesStr = antlrcpp::arrayToString(rules);
|
||||
return std::wstring(L"ParserRuleContext") + rulesStr + std::wstring(L"{") + std::wstring(L"start=") + std::to_wstring(start->getTokenIndex()) + std::wstring(L", stop=") + std::to_wstring(stop->getTokenIndex()) + L'}';
|
||||
return std::wstring(L"ParserRuleContext") + rulesStr + std::wstring(L"{") + std::wstring(L"start=") +
|
||||
std::to_wstring(start->getTokenIndex()) + std::wstring(L", stop=") +
|
||||
std::to_wstring(stop->getTokenIndex()) + L'}';
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "RuleContext.h"
|
||||
#include "CPPUtils.h"
|
||||
|
||||
namespace org {
|
||||
namespace antlr {
|
||||
|
@ -71,7 +72,7 @@ namespace runtime {
|
|||
/// how we parse this rule.
|
||||
/// </summary>
|
||||
public:
|
||||
std::vector<ParseTree*> children;
|
||||
std::vector<std::shared_ptr<ParseTree>> children;
|
||||
|
||||
/// <summary>
|
||||
/// For debugging/tracing purposes, we want to track all of the nodes in
|
||||
|
@ -94,7 +95,7 @@ namespace runtime {
|
|||
/// </summary>
|
||||
// public List<Integer> states;
|
||||
|
||||
Token *start, *stop;
|
||||
TokenRef start, stop;
|
||||
|
||||
/// The exception that forced this rule to return. If the rule successfully
|
||||
/// completed, this is "null exception pointer".
|
||||
|
@ -105,95 +106,75 @@ namespace runtime {
|
|||
|
||||
/// <summary>
|
||||
/// COPY a ctx (I'm deliberately not copy constructor) </summary>
|
||||
virtual void copyFrom(ParserRuleContext *ctx);
|
||||
virtual void copyFrom(std::shared_ptr<ParserRuleContext> ctx);
|
||||
|
||||
ParserRuleContext(ParserRuleContext *parent, int invokingStateNumber);
|
||||
ParserRuleContext(std::weak_ptr<ParserRuleContext> parent, int invokingStateNumber);
|
||||
|
||||
// Double dispatch methods for listeners
|
||||
|
||||
virtual void enterRule(tree::ParseTreeListener *listener);
|
||||
virtual void exitRule(tree::ParseTreeListener *listener);
|
||||
virtual void enterRule(std::shared_ptr<tree::ParseTreeListener> listener);
|
||||
virtual void exitRule(std::shared_ptr<tree::ParseTreeListener> listener);
|
||||
|
||||
/// <summary>
|
||||
/// Does not set parent link; other add methods do that </summary>
|
||||
virtual tree::TerminalNode* addChild(tree::TerminalNode *t);
|
||||
/// Does not set parent link; other add methods do that.
|
||||
virtual std::shared_ptr<tree::TerminalNode> addChild(std::shared_ptr<tree::TerminalNode> t);
|
||||
virtual RuleContextRef addChild(RuleContextRef ruleInvocation);
|
||||
|
||||
virtual RuleContext* addChild(RuleContext *ruleInvocation);
|
||||
|
||||
/// <summary>
|
||||
/// Used by enterOuterAlt to toss out a RuleContext previously added as
|
||||
/// we entered a rule. If we have # label, we will need to remove
|
||||
/// generic ruleContext object.
|
||||
/// </summary>
|
||||
/// we entered a rule. If we have # label, we will need to remove
|
||||
/// generic ruleContext object.
|
||||
virtual void removeLastChild();
|
||||
|
||||
virtual tree::TerminalNode* addChild(Token *matchedToken);
|
||||
virtual std::shared_ptr<tree::TerminalNode> addChild(TokenRef matchedToken);
|
||||
|
||||
virtual tree::ErrorNode* addErrorNode(Token *badToken);
|
||||
virtual std::shared_ptr<tree::ErrorNode> addErrorNode(TokenRef badToken);
|
||||
|
||||
virtual ParserRuleContext* getParent() override;
|
||||
std::weak_ptr<ParserRuleContext> getParent() { return std::dynamic_pointer_cast<ParserRuleContext>(getParentReference().lock()); };
|
||||
|
||||
virtual ParseTree* getChild(std::size_t i) override;
|
||||
virtual std::shared_ptr<tree::TerminalNode> getToken(int ttype, std::size_t i);
|
||||
|
||||
virtual std::vector<std::shared_ptr<tree::TerminalNode>> getTokens(int ttype);
|
||||
|
||||
template<typename T>
|
||||
T* getChild(size_t i) {
|
||||
std::shared_ptr<T> getRuleContext(size_t i) {
|
||||
if (children.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t j = 0; // what element have we found with ctxType?
|
||||
for (auto &child : children) {
|
||||
if (dynamic_cast<T *>(child) != nullptr) {
|
||||
if (antlrcpp::is<T>(child)) {
|
||||
if (j++ == i) {
|
||||
return dynamic_cast<T *>(child);
|
||||
return std::dynamic_pointer_cast<T>(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual tree::TerminalNode* getToken(int ttype, std::size_t i);
|
||||
|
||||
virtual std::vector<tree::TerminalNode *> getTokens(int ttype);
|
||||
|
||||
template<typename T>
|
||||
T* getRuleContext(size_t i) {
|
||||
return getChild<T>(i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T*> getRuleContexts() {
|
||||
if (children.empty()) {
|
||||
return std::vector<T *>();
|
||||
}
|
||||
|
||||
std::vector<T *> contexts;
|
||||
std::vector<std::shared_ptr<T>> getRuleContexts() {
|
||||
std::vector<std::shared_ptr<T>> contexts;
|
||||
for (auto &child : children) {
|
||||
if (dynamic_cast<T *>(child)) {
|
||||
if (contexts.empty()) {
|
||||
contexts = std::vector<T *>();
|
||||
}
|
||||
|
||||
contexts.push_back((T *)(child));
|
||||
if (antlrcpp::is<T>(child)) {
|
||||
contexts.push_back(std::dynamic_pointer_cast<T>(child));
|
||||
}
|
||||
}
|
||||
|
||||
if (contexts.empty()) {
|
||||
return std::vector<T *>();
|
||||
}
|
||||
|
||||
return contexts;
|
||||
}
|
||||
|
||||
virtual std::size_t getChildCount() override;
|
||||
virtual misc::Interval getSourceInterval() override;
|
||||
|
||||
virtual Token *getStart();
|
||||
virtual Token *getStop();
|
||||
virtual TokenRef getStart();
|
||||
virtual TokenRef getStop();
|
||||
|
||||
/// <summary>
|
||||
/// Used for rule context info debugging during parse-time, not so much for ATN debugging </summary>
|
||||
virtual std::wstring toInfoString(Parser *recognizer);
|
||||
|
||||
protected:
|
||||
virtual std::shared_ptr<Tree> getChildReference(size_t i) override;
|
||||
};
|
||||
|
||||
} // namespace runtime
|
||||
|
|
|
@ -34,14 +34,14 @@
|
|||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
void ProxyErrorListener::reportAmbiguity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
bool exact, antlrcpp::BitSet *ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
bool exact, const antlrcpp::BitSet &ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
for (auto listener : *delegates) {
|
||||
listener->reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs);
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyErrorListener::reportAttemptingFullContext(Parser *recognizer, dfa::DFA *dfa, size_t startIndex,
|
||||
size_t stopIndex, antlrcpp::BitSet *conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
size_t stopIndex, const antlrcpp::BitSet &conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) {
|
||||
for (auto listener : *delegates) {
|
||||
listener->reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace runtime {
|
|||
}
|
||||
}
|
||||
|
||||
void syntaxError(IRecognizer *recognizer, Token *offendingSymbol, size_t line, int charPositionInLine,
|
||||
void syntaxError(IRecognizer *recognizer, TokenRef offendingSymbol, size_t line, int charPositionInLine,
|
||||
const std::wstring &msg, std::exception_ptr e) override {
|
||||
for (auto listener : *delegates) {
|
||||
listener->syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);
|
||||
|
@ -62,10 +62,10 @@ namespace runtime {
|
|||
}
|
||||
|
||||
virtual void reportAmbiguity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex, bool exact,
|
||||
antlrcpp::BitSet *ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
const antlrcpp::BitSet &ambigAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
|
||||
virtual void reportAttemptingFullContext(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
antlrcpp::BitSet *conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
const antlrcpp::BitSet &conflictingAlts, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
|
||||
virtual void reportContextSensitivity(Parser *recognizer, dfa::DFA *dfa, size_t startIndex, size_t stopIndex,
|
||||
int prediction, std::shared_ptr<atn::ATNConfigSet> configs) override;
|
||||
|
|
|
@ -38,12 +38,13 @@
|
|||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
RecognitionException::RecognitionException(IRecognizer *recognizer, IntStream *input, ParserRuleContext *ctx, Token *offendingToken)
|
||||
RecognitionException::RecognitionException(IRecognizer *recognizer, IntStream *input,
|
||||
ParserRuleContextRef ctx, TokenRef offendingToken)
|
||||
: RecognitionException("", recognizer, input, ctx, offendingToken) {
|
||||
}
|
||||
|
||||
RecognitionException::RecognitionException(const std::string &message, IRecognizer *recognizer, IntStream *input,
|
||||
ParserRuleContext *ctx, Token *offendingToken)
|
||||
ParserRuleContextRef ctx, TokenRef offendingToken)
|
||||
: RuntimeException(message), _recognizer(recognizer), _input(input), _offendingToken(offendingToken), _ctx(ctx) {
|
||||
InitializeInstanceFields();
|
||||
if (recognizer != nullptr) {
|
||||
|
@ -66,7 +67,7 @@ misc::IntervalSet RecognitionException::getExpectedTokens() const {
|
|||
return misc::IntervalSet::EMPTY_SET;
|
||||
}
|
||||
|
||||
RuleContext* RecognitionException::getCtx() const {
|
||||
RuleContextRef RecognitionException::getCtx() const {
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
|
@ -74,7 +75,7 @@ IntStream* RecognitionException::getInputStream() const {
|
|||
return _input;
|
||||
}
|
||||
|
||||
Token* RecognitionException::getOffendingToken() const {
|
||||
TokenRef RecognitionException::getOffendingToken() const {
|
||||
return _offendingToken;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,19 +53,20 @@ namespace runtime {
|
|||
/// The Recognizer where this exception originated.
|
||||
IRecognizer *_recognizer;
|
||||
IntStream *_input;
|
||||
RuleContext *_ctx;
|
||||
RuleContextRef _ctx;
|
||||
|
||||
/// The current Token when an error occurred. Since not all streams
|
||||
/// support accessing symbols by index, we have to track the Token
|
||||
/// instance itself.
|
||||
Token *_offendingToken;
|
||||
TokenRef _offendingToken;
|
||||
|
||||
int _offendingState;
|
||||
|
||||
public:
|
||||
RecognitionException(IRecognizer *recognizer, IntStream *input, ParserRuleContext *ctx, Token *offendingToken = nullptr);
|
||||
RecognitionException(const std::string &message, IRecognizer *recognizer, IntStream *input, ParserRuleContext *ctx,
|
||||
Token *offendingToken = nullptr);
|
||||
RecognitionException(IRecognizer *recognizer, IntStream *input, ParserRuleContextRef ctx,
|
||||
TokenRef offendingToken = TokenRef());
|
||||
RecognitionException(const std::string &message, IRecognizer *recognizer, IntStream *input,
|
||||
ParserRuleContextRef ctx, TokenRef offendingToken = TokenRef());
|
||||
|
||||
/// Get the ATN state number the parser was in at the time the error
|
||||
/// occurred. For NoViableAltException and
|
||||
|
@ -97,7 +98,7 @@ namespace runtime {
|
|||
/// </summary>
|
||||
/// <returns> The <seealso cref="RuleContext"/> at the time this exception was thrown.
|
||||
/// If the context is not available, this method returns {@code null}. </returns>
|
||||
virtual RuleContext* getCtx() const;
|
||||
virtual RuleContextRef getCtx() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the input stream which is the symbol source for the recognizer where
|
||||
|
@ -110,7 +111,7 @@ namespace runtime {
|
|||
/// available. </returns>
|
||||
virtual IntStream* getInputStream() const;
|
||||
|
||||
virtual Token* getOffendingToken() const;
|
||||
virtual TokenRef getOffendingToken() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <seealso cref="Recognizer"/> where this exception occurred.
|
||||
|
|
|
@ -142,15 +142,15 @@ ANTLRErrorListener *Recognizer::getErrorListenerDispatch() {
|
|||
return (ANTLRErrorListener *)new ProxyErrorListener(getErrorListeners());
|
||||
}
|
||||
|
||||
bool Recognizer::sempred(RuleContext *_localctx, int ruleIndex, int actionIndex) {
|
||||
bool Recognizer::sempred(RuleContextRef localctx, int ruleIndex, int actionIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Recognizer::precpred(RuleContext *localctx, int precedence) {
|
||||
bool Recognizer::precpred(RuleContextRef localctx, int precedence) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Recognizer::action(RuleContext *_localctx, int ruleIndex, int actionIndex) {
|
||||
void Recognizer::action(RuleContextRef localctx, int ruleIndex, int actionIndex) {
|
||||
}
|
||||
|
||||
int Recognizer::getState() {
|
||||
|
|
|
@ -138,11 +138,11 @@ namespace runtime {
|
|||
|
||||
// subclass needs to override these if there are sempreds or actions
|
||||
// that the ATN interp needs to execute
|
||||
virtual bool sempred(RuleContext *_localctx, int ruleIndex, int actionIndex);
|
||||
virtual bool sempred(RuleContextRef localctx, int ruleIndex, int actionIndex);
|
||||
|
||||
virtual bool precpred(RuleContext *localctx, int precedence);
|
||||
virtual bool precpred(RuleContextRef localctx, int precedence);
|
||||
|
||||
virtual void action(RuleContext *_localctx, int ruleIndex, int actionIndex);
|
||||
virtual void action(RuleContextRef localctx, int ruleIndex, int actionIndex);
|
||||
|
||||
int getState();
|
||||
|
||||
|
@ -156,11 +156,11 @@ namespace runtime {
|
|||
/// </summary>
|
||||
void setState(int atnState);
|
||||
|
||||
virtual IntStream *getInputStream() = 0;
|
||||
virtual IntStream* getInputStream() = 0;
|
||||
|
||||
virtual void setInputStream(IntStream *input) = 0;
|
||||
|
||||
virtual TokenFactory<CommonToken *> *getTokenFactory() = 0;
|
||||
virtual std::shared_ptr<TokenFactory<CommonToken>> getTokenFactory() = 0;
|
||||
|
||||
template<typename T1>
|
||||
void setTokenFactory(TokenFactory<T1> *input);
|
||||
|
|
|
@ -37,23 +37,25 @@
|
|||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
ParserRuleContext *const RuleContext::EMPTY = new ParserRuleContext();
|
||||
const ParserRuleContextRef RuleContext::EMPTY = std::make_shared<ParserRuleContext>();
|
||||
|
||||
RuleContext::RuleContext() {
|
||||
InitializeInstanceFields();
|
||||
}
|
||||
|
||||
RuleContext::RuleContext(RuleContext *parent, int invokingState) {
|
||||
RuleContext::RuleContext(std::weak_ptr<RuleContext> parent, int invokingState) {
|
||||
InitializeInstanceFields();
|
||||
this->parent = parent;
|
||||
this->invokingState = invokingState;
|
||||
}
|
||||
|
||||
int RuleContext::depth() {
|
||||
int n = 0;
|
||||
RuleContext *p = this;
|
||||
while (p != nullptr) {
|
||||
p = p->parent;
|
||||
int n = 1;
|
||||
RuleContextRef p = shared_from_this();
|
||||
while (true) {
|
||||
if (p->parent.expired())
|
||||
break;
|
||||
p = p->parent.lock();
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
|
@ -67,12 +69,13 @@ misc::Interval RuleContext::getSourceInterval() {
|
|||
return misc::Interval::INVALID;
|
||||
}
|
||||
|
||||
RuleContext *RuleContext::getRuleContext() {
|
||||
return this;
|
||||
RuleContextRef RuleContext::getRuleContext() {
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
RuleContext *RuleContext::getParent() {
|
||||
return parent;
|
||||
std::weak_ptr<tree::Tree> RuleContext::getParentReference()
|
||||
{
|
||||
return std::dynamic_pointer_cast<tree::Tree>(parent.lock());
|
||||
}
|
||||
|
||||
std::wstring RuleContext::getText() {
|
||||
|
@ -94,10 +97,11 @@ ssize_t RuleContext::getRuleIndex() const {
|
|||
return -1;
|
||||
}
|
||||
|
||||
tree::ParseTree *RuleContext::getChild(std::size_t i) {
|
||||
return nullptr;
|
||||
std::shared_ptr<tree::Tree> RuleContext::getChildReference(size_t i) {
|
||||
return std::shared_ptr<tree::Tree>();
|
||||
}
|
||||
|
||||
|
||||
std::size_t RuleContext::getChildCount() {
|
||||
return 0;
|
||||
}
|
||||
|
@ -131,11 +135,11 @@ void RuleContext::save(std::vector<std::wstring> &ruleNames, const std::wstring
|
|||
}
|
||||
|
||||
std::wstring RuleContext::toStringTree(Parser *recog) {
|
||||
return tree::Trees::toStringTree(this, recog);
|
||||
return tree::Trees::toStringTree(shared_from_this(), recog);
|
||||
}
|
||||
|
||||
std::wstring RuleContext::toStringTree(std::vector<std::wstring> &ruleNames) {
|
||||
return tree::Trees::toStringTree(this, ruleNames);
|
||||
return tree::Trees::toStringTree(shared_from_this(), ruleNames);
|
||||
}
|
||||
|
||||
std::wstring RuleContext::toStringTree() {
|
||||
|
@ -144,32 +148,33 @@ std::wstring RuleContext::toStringTree() {
|
|||
|
||||
|
||||
std::wstring RuleContext::toString(const std::vector<std::wstring> &ruleNames) {
|
||||
return toString(ruleNames, static_cast<RuleContext*>(nullptr));
|
||||
return toString(ruleNames, RuleContextRef());
|
||||
}
|
||||
|
||||
|
||||
std::wstring RuleContext::toString(const std::vector<std::wstring> &ruleNames, RuleContext *stop) {
|
||||
std::wstring RuleContext::toString(const std::vector<std::wstring> &ruleNames, RuleContextRef stop) {
|
||||
std::wstringstream ss;
|
||||
|
||||
RuleContext *p = this;
|
||||
RuleContextRef parent = shared_from_this();
|
||||
ss << L"[";
|
||||
while (p != nullptr && p != stop) {
|
||||
while (parent != stop) {
|
||||
if (ruleNames.empty()) {
|
||||
if (!p->isEmpty()) {
|
||||
ss << p->invokingState;
|
||||
if (!parent->isEmpty()) {
|
||||
ss << parent->invokingState;
|
||||
}
|
||||
} else {
|
||||
ssize_t ruleIndex = p->getRuleIndex();
|
||||
ssize_t ruleIndex = parent->getRuleIndex();
|
||||
|
||||
std::wstring ruleName = (ruleIndex >= 0 && ruleIndex < (ssize_t)ruleNames.size()) ? ruleNames[(size_t)ruleIndex] : std::to_wstring(ruleIndex);
|
||||
ss << ruleName;
|
||||
}
|
||||
|
||||
if (p->parent != nullptr && (ruleNames.size() > 0 || !p->parent->isEmpty())) {
|
||||
if (parent->parent.expired()) // No parent anymore.
|
||||
break;
|
||||
parent = parent->parent.lock();
|
||||
if (!ruleNames.empty() || !parent->isEmpty()) {
|
||||
ss << L" ";
|
||||
}
|
||||
|
||||
p = p->parent;
|
||||
}
|
||||
|
||||
ss << L"]";
|
||||
|
@ -185,7 +190,7 @@ std::wstring RuleContext::toString(Recognizer *recog) {
|
|||
return toString(recog, ParserRuleContext::EMPTY);
|
||||
}
|
||||
|
||||
std::wstring RuleContext::toString(Recognizer *recog, RuleContext *stop) {
|
||||
std::wstring RuleContext::toString(Recognizer *recog, RuleContextRef stop) {
|
||||
return toString(recog->getRuleNames(), stop);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,13 +58,13 @@ namespace runtime {
|
|||
/// ParserRuleContext.
|
||||
/// </summary>
|
||||
/// <seealso cref= ParserRuleContext </seealso>
|
||||
class RuleContext : public tree::RuleNode {
|
||||
class RuleContext : public tree::RuleNode, public std::enable_shared_from_this<RuleContext> {
|
||||
public:
|
||||
static ParserRuleContext *const EMPTY;
|
||||
static const ParserRuleContextRef EMPTY;
|
||||
|
||||
/// <summary>
|
||||
/// What context invoked this rule? </summary>
|
||||
RuleContext *parent;
|
||||
std::weak_ptr<RuleContext> parent;
|
||||
|
||||
/// <summary>
|
||||
/// What state invoked the rule associated with this context?
|
||||
|
@ -75,28 +75,22 @@ namespace runtime {
|
|||
|
||||
RuleContext();
|
||||
|
||||
RuleContext(RuleContext *parent, int invokingState);
|
||||
RuleContext(std::weak_ptr<RuleContext> parent, int invokingState);
|
||||
|
||||
virtual int depth();
|
||||
|
||||
/// <summary>
|
||||
/// A context is empty if there is no invoking state; meaning nobody call
|
||||
/// current context.
|
||||
/// </summary>
|
||||
/// A context is empty if there is no invoking state; meaning nobody call current context.
|
||||
virtual bool isEmpty();
|
||||
|
||||
// satisfy the ParseTree / SyntaxTree interface
|
||||
|
||||
virtual misc::Interval getSourceInterval() override;
|
||||
|
||||
virtual RuleContext *getRuleContext() override;
|
||||
virtual RuleContext *getParent() override;
|
||||
virtual RuleContextRef getRuleContext() override;
|
||||
virtual std::wstring getText() override;
|
||||
|
||||
virtual ssize_t getRuleIndex() const;
|
||||
|
||||
virtual ParseTree *getChild(std::size_t i) override;
|
||||
|
||||
virtual std::size_t getChildCount() override;
|
||||
|
||||
template<typename T, typename T1>
|
||||
|
@ -139,9 +133,15 @@ namespace runtime {
|
|||
std::wstring toString(const std::vector<std::wstring> &ruleNames);
|
||||
|
||||
// recog null unless ParserRuleContext, in which case we use subclass toString(...)
|
||||
std::wstring toString(Recognizer *recog, RuleContext *stop);
|
||||
std::wstring toString(Recognizer *recog, RuleContextRef stop);
|
||||
|
||||
virtual std::wstring toString(const std::vector<std::wstring> &ruleNames, RuleContext *stop);
|
||||
virtual std::wstring toString(const std::vector<std::wstring> &ruleNames, RuleContextRef stop);
|
||||
|
||||
bool operator == (const RuleContext &other) { return this == &other; } // Simple address comparison.
|
||||
|
||||
protected:
|
||||
virtual std::weak_ptr<Tree> getParentReference() override;
|
||||
virtual std::shared_ptr<Tree> getChildReference(size_t i) override;
|
||||
|
||||
private:
|
||||
void InitializeInstanceFields();
|
||||
|
|
|
@ -36,12 +36,9 @@ namespace antlr {
|
|||
namespace v4 {
|
||||
namespace runtime {
|
||||
|
||||
/// <summary>
|
||||
/// The default mechanism for creating tokens. It's used by default in Lexer and
|
||||
/// the error handling strategy (to create missing tokens). Notifying the parser
|
||||
/// of a new factory means that it notifies it's token source and error strategy.
|
||||
/// </summary>
|
||||
|
||||
template<typename Symbol>
|
||||
class TokenFactory {
|
||||
/// <summary>
|
||||
|
@ -50,11 +47,10 @@ namespace runtime {
|
|||
/// are wiped to -1 in the text override is set in the CommonToken.
|
||||
/// </summary>
|
||||
public:
|
||||
virtual Symbol create(std::pair<TokenSource*, CharStream*> *source, int type, const std::wstring &text, int channel, int start, int stop, int line, int charPositionInLine) = 0;
|
||||
virtual std::shared_ptr<Symbol> create(std::pair<TokenSource*, CharStream*> source, int type, const std::wstring &text, int channel, int start, int stop, int line, int charPositionInLine) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Generically useful </summary>
|
||||
virtual Symbol create(int type, const std::wstring &text) = 0;
|
||||
/// Generically useful
|
||||
virtual std::shared_ptr<Symbol> create(int type, const std::wstring &text) = 0;
|
||||
};
|
||||
|
||||
} // namespace runtime
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace runtime {
|
|||
/// to the parser.
|
||||
/// </summary>
|
||||
public:
|
||||
virtual Token *nextToken() = 0;
|
||||
virtual TokenRef nextToken() = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Get the line number for the current position in the input stream. The
|
||||
|
@ -86,7 +86,7 @@ namespace runtime {
|
|||
/// <returns> The <seealso cref="CharStream"/> associated with the current position in
|
||||
/// the input, or {@code null} if no input stream is available for the token
|
||||
/// source. </returns>
|
||||
virtual CharStream *getInputStream() = 0;
|
||||
virtual CharStream* getInputStream() = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the underlying input source. This method returns a
|
||||
|
@ -108,7 +108,7 @@ namespace runtime {
|
|||
/// creating <seealso cref="Token"/> objects from the input.
|
||||
/// </summary>
|
||||
/// <returns> The <seealso cref="TokenFactory"/> currently used by this token source. </returns>
|
||||
virtual TokenFactory<CommonToken *> *getTokenFactory() = 0;
|
||||
virtual std::shared_ptr<TokenFactory<CommonToken>> getTokenFactory() = 0;
|
||||
};
|
||||
|
||||
} // namespace runtime
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace runtime {
|
|||
public:
|
||||
virtual ~TokenStream();
|
||||
|
||||
virtual Token *LT(ssize_t k) = 0;
|
||||
virtual TokenRef LT(ssize_t k) = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <seealso cref="Token"/> at the specified {@code index} in the stream. When
|
||||
|
@ -72,13 +72,10 @@ namespace runtime {
|
|||
/// <exception cref="IllegalArgumentException"> if {code index} is less than 0 </exception>
|
||||
/// <exception cref="UnsupportedOperationException"> if the stream does not support
|
||||
/// retrieving the token at the specified index </exception>
|
||||
virtual Token *get(size_t index) const = 0;
|
||||
virtual TokenRef get(size_t index) const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying <seealso cref="TokenSource"/> which provides tokens for this
|
||||
/// stream.
|
||||
/// </summary>
|
||||
virtual TokenSource *getTokenSource() const = 0;
|
||||
/// Gets the underlying TokenSource which provides tokens for this stream.
|
||||
virtual TokenSource* getTokenSource() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Return the text of all tokens within the specified {@code interval}. This
|
||||
|
@ -163,7 +160,7 @@ namespace runtime {
|
|||
/// </returns>
|
||||
/// <exception cref="UnsupportedOperationException"> if this stream does not support
|
||||
/// this method for the specified tokens </exception>
|
||||
virtual std::wstring getText(Token *start, Token *stop) = 0;
|
||||
virtual std::wstring getText(TokenRef start, TokenRef stop) = 0;
|
||||
};
|
||||
|
||||
} // namespace runtime
|
||||
|
|
|
@ -287,7 +287,7 @@ std::wstring TokenStreamRewriter::getText(const std::wstring &programName, const
|
|||
while (i <= (size_t)stop && i < tokens->size()) {
|
||||
RewriteOperation *op = indexToOp[i];
|
||||
indexToOp.erase(i); // remove so any left have index size-1
|
||||
Token *t = tokens->get(i);
|
||||
TokenRef t = tokens->get(i);
|
||||
if (op == nullptr) {
|
||||
// no operation at that index, just dump token
|
||||
if (t->getType() != EOF) {
|
||||
|
|
|
@ -42,44 +42,46 @@
|
|||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
|
||||
UnbufferedTokenStream::UnbufferedTokenStream(TokenSource* tokenSource) : UnbufferedTokenStream(tokenSource, 256) {
|
||||
UnbufferedTokenStream::UnbufferedTokenStream(TokenSource *tokenSource) : UnbufferedTokenStream(tokenSource, 256) {
|
||||
}
|
||||
|
||||
UnbufferedTokenStream::UnbufferedTokenStream(TokenSource* tokenSource, int bufferSize)
|
||||
UnbufferedTokenStream::UnbufferedTokenStream(TokenSource *tokenSource, int bufferSize) : _tokenSource(tokenSource)
|
||||
{
|
||||
InitializeInstanceFields();
|
||||
this->tokenSource = tokenSource;
|
||||
fill(1); // prime the pump
|
||||
}
|
||||
|
||||
Token* UnbufferedTokenStream::get(size_t i) const
|
||||
{ // get absolute index
|
||||
size_t bufferStartIndex = getBufferStartIndex();
|
||||
if (i < bufferStartIndex || i >= bufferStartIndex + tokens.size()) {
|
||||
throw IndexOutOfBoundsException(std::string("get(") + std::to_string(i) + std::string(") outside buffer: ")
|
||||
+ std::to_string(bufferStartIndex) + std::string("..") + std::to_string(bufferStartIndex + tokens.size()));
|
||||
}
|
||||
return tokens[i - bufferStartIndex];
|
||||
UnbufferedTokenStream::~UnbufferedTokenStream() {
|
||||
}
|
||||
|
||||
Token* UnbufferedTokenStream::LT(ssize_t i)
|
||||
TokenRef UnbufferedTokenStream::get(size_t i) const
|
||||
{ // get absolute index
|
||||
size_t bufferStartIndex = getBufferStartIndex();
|
||||
if (i < bufferStartIndex || i >= bufferStartIndex + _tokens.size()) {
|
||||
throw IndexOutOfBoundsException(std::string("get(") + std::to_string(i) + std::string(") outside buffer: ")
|
||||
+ std::to_string(bufferStartIndex) + std::string("..") + std::to_string(bufferStartIndex + _tokens.size()));
|
||||
}
|
||||
return _tokens[i - bufferStartIndex];
|
||||
}
|
||||
|
||||
TokenRef UnbufferedTokenStream::LT(ssize_t i)
|
||||
{
|
||||
if (i == -1) {
|
||||
return lastToken;
|
||||
return _lastToken;
|
||||
}
|
||||
|
||||
sync(i);
|
||||
ssize_t index = (ssize_t)p + i - 1;
|
||||
ssize_t index = (ssize_t)_p + i - 1;
|
||||
if (index < 0) {
|
||||
throw IndexOutOfBoundsException(std::string("LT(") + std::to_string(i) + std::string(") gives negative index"));
|
||||
}
|
||||
|
||||
if (index >= (ssize_t)tokens.size()) {
|
||||
assert(tokens.size() > 0 && tokens.back()->getType() == EOF);
|
||||
return tokens.back();
|
||||
if (index >= (ssize_t)_tokens.size()) {
|
||||
assert(_tokens.size() > 0 && _tokens.back()->getType() == EOF);
|
||||
return _tokens.back();
|
||||
}
|
||||
|
||||
return tokens[(size_t)index];
|
||||
return _tokens[(size_t)index];
|
||||
}
|
||||
|
||||
ssize_t UnbufferedTokenStream::LA(ssize_t i)
|
||||
|
@ -89,7 +91,7 @@ ssize_t UnbufferedTokenStream::LA(ssize_t i)
|
|||
|
||||
TokenSource* UnbufferedTokenStream::getTokenSource() const
|
||||
{
|
||||
return tokenSource;
|
||||
return _tokenSource;
|
||||
}
|
||||
|
||||
std::wstring UnbufferedTokenStream::getText()
|
||||
|
@ -102,7 +104,7 @@ std::wstring UnbufferedTokenStream::getText(RuleContext* ctx)
|
|||
return getText(ctx->getSourceInterval());
|
||||
}
|
||||
|
||||
std::wstring UnbufferedTokenStream::getText(Token* start, Token* stop)
|
||||
std::wstring UnbufferedTokenStream::getText(TokenRef start, TokenRef stop)
|
||||
{
|
||||
return getText(misc::Interval(start->getTokenIndex(), stop->getTokenIndex()));
|
||||
}
|
||||
|
@ -114,18 +116,18 @@ void UnbufferedTokenStream::consume()
|
|||
}
|
||||
|
||||
// buf always has at least tokens[p==0] in this method due to ctor
|
||||
lastToken = tokens[p]; // track last token for LT(-1)
|
||||
_lastToken = _tokens[_p]; // track last token for LT(-1)
|
||||
|
||||
// if we're at last token and no markers, opportunity to flush buffer
|
||||
if (p == tokens.size() - 1 && numMarkers == 0) {
|
||||
tokens.clear();
|
||||
p = 0;
|
||||
lastTokenBufferStart = lastToken;
|
||||
if (_p == _tokens.size() - 1 && _numMarkers == 0) {
|
||||
_tokens.clear();
|
||||
_p = 0;
|
||||
_lastTokenBufferStart = _lastToken;
|
||||
} else {
|
||||
++p;
|
||||
++_p;
|
||||
}
|
||||
|
||||
++currentTokenIndex;
|
||||
++_currentTokenIndex;
|
||||
sync(1);
|
||||
}
|
||||
|
||||
|
@ -136,7 +138,7 @@ void UnbufferedTokenStream::consume()
|
|||
/// </summary>
|
||||
void UnbufferedTokenStream::sync(ssize_t want)
|
||||
{
|
||||
ssize_t need = ((ssize_t)p + want - 1) - (ssize_t)tokens.size() + 1; // how many more elements we need?
|
||||
ssize_t need = ((ssize_t)_p + want - 1) - (ssize_t)_tokens.size() + 1; // how many more elements we need?
|
||||
if (need > 0) {
|
||||
fill((size_t)need);
|
||||
}
|
||||
|
@ -150,25 +152,25 @@ void UnbufferedTokenStream::sync(ssize_t want)
|
|||
size_t UnbufferedTokenStream::fill(size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (tokens.size() > 0 && tokens.back()->getType() == EOF) {
|
||||
if (_tokens.size() > 0 && _tokens.back()->getType() == EOF) {
|
||||
return i;
|
||||
}
|
||||
|
||||
Token* t = tokenSource->nextToken();
|
||||
TokenRef t = _tokenSource->nextToken();
|
||||
add(t);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void UnbufferedTokenStream::add(Token* t)
|
||||
void UnbufferedTokenStream::add(TokenRef t)
|
||||
{
|
||||
WritableToken *writable = dynamic_cast<WritableToken *>(t);
|
||||
if (writable != nullptr) {
|
||||
writable->setTokenIndex(int(getBufferStartIndex() + tokens.size()));
|
||||
WritableTokenRef writable = std::dynamic_pointer_cast<WritableToken>(t);
|
||||
if (writable) {
|
||||
writable->setTokenIndex(int(getBufferStartIndex() + _tokens.size()));
|
||||
}
|
||||
|
||||
tokens.push_back(t);
|
||||
_tokens.push_back(t);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -180,49 +182,49 @@ void UnbufferedTokenStream::add(Token* t)
|
|||
/// </summary>
|
||||
ssize_t UnbufferedTokenStream::mark()
|
||||
{
|
||||
if (numMarkers == 0) {
|
||||
lastTokenBufferStart = lastToken;
|
||||
if (_numMarkers == 0) {
|
||||
_lastTokenBufferStart = _lastToken;
|
||||
}
|
||||
|
||||
int mark = -numMarkers - 1;
|
||||
numMarkers++;
|
||||
int mark = -_numMarkers - 1;
|
||||
_numMarkers++;
|
||||
return mark;
|
||||
}
|
||||
|
||||
void UnbufferedTokenStream::release(ssize_t marker)
|
||||
{
|
||||
ssize_t expectedMark = -numMarkers;
|
||||
ssize_t expectedMark = -_numMarkers;
|
||||
if (marker != expectedMark) {
|
||||
throw IllegalStateException("release() called with an invalid marker.");
|
||||
}
|
||||
|
||||
numMarkers--;
|
||||
if (numMarkers == 0) { // can we release buffer?
|
||||
if (p > 0) {
|
||||
_numMarkers--;
|
||||
if (_numMarkers == 0) { // can we release buffer?
|
||||
if (_p > 0) {
|
||||
// Copy tokens[p]..tokens[n-1] to tokens[0]..tokens[(n-1)-p], reset ptrs
|
||||
// p is last valid token; move nothing if p==n as we have no valid char
|
||||
std::vector<Token *>(tokens.begin() + (ssize_t)p, tokens.end()).swap(tokens);
|
||||
p = 0;
|
||||
std::vector<TokenRef>(_tokens.begin() + (ssize_t)_p, _tokens.end()).swap(_tokens);
|
||||
_p = 0;
|
||||
}
|
||||
|
||||
lastTokenBufferStart = lastToken;
|
||||
_lastTokenBufferStart = _lastToken;
|
||||
}
|
||||
}
|
||||
|
||||
size_t UnbufferedTokenStream::index()
|
||||
{
|
||||
return currentTokenIndex;
|
||||
return _currentTokenIndex;
|
||||
}
|
||||
|
||||
void UnbufferedTokenStream::seek(size_t index)
|
||||
{ // seek to absolute index
|
||||
if (index == currentTokenIndex) {
|
||||
if (index == _currentTokenIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (index > currentTokenIndex) {
|
||||
sync(ssize_t(index - currentTokenIndex));
|
||||
index = std::min(index, getBufferStartIndex() + tokens.size() - 1);
|
||||
if (index > _currentTokenIndex) {
|
||||
sync(ssize_t(index - _currentTokenIndex));
|
||||
index = std::min(index, getBufferStartIndex() + _tokens.size() - 1);
|
||||
}
|
||||
|
||||
size_t bufferStartIndex = getBufferStartIndex();
|
||||
|
@ -231,17 +233,17 @@ void UnbufferedTokenStream::seek(size_t index)
|
|||
}
|
||||
|
||||
size_t i = index - bufferStartIndex;
|
||||
if (i >= tokens.size()) {
|
||||
if (i >= _tokens.size()) {
|
||||
throw UnsupportedOperationException(std::string("seek to index outside buffer: ") + std::to_string(index) +
|
||||
" not in " + std::to_string(bufferStartIndex) + ".." + std::to_string(bufferStartIndex + tokens.size()));
|
||||
" not in " + std::to_string(bufferStartIndex) + ".." + std::to_string(bufferStartIndex + _tokens.size()));
|
||||
}
|
||||
|
||||
p = i;
|
||||
currentTokenIndex = index;
|
||||
if (p == 0) {
|
||||
lastToken = lastTokenBufferStart;
|
||||
_p = i;
|
||||
_currentTokenIndex = index;
|
||||
if (_p == 0) {
|
||||
_lastToken = _lastTokenBufferStart;
|
||||
} else {
|
||||
lastToken = tokens[p - 1];
|
||||
_lastToken = _tokens[_p - 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,13 +254,13 @@ size_t UnbufferedTokenStream::size()
|
|||
|
||||
std::string UnbufferedTokenStream::getSourceName() const
|
||||
{
|
||||
return tokenSource->getSourceName();
|
||||
return _tokenSource->getSourceName();
|
||||
}
|
||||
|
||||
std::wstring UnbufferedTokenStream::getText(const misc::Interval &interval)
|
||||
{
|
||||
size_t bufferStartIndex = getBufferStartIndex();
|
||||
size_t bufferStopIndex = bufferStartIndex + tokens.size() - 1;
|
||||
size_t bufferStopIndex = bufferStartIndex + _tokens.size() - 1;
|
||||
|
||||
size_t start = (size_t)interval.a;
|
||||
size_t stop = (size_t)interval.b;
|
||||
|
@ -272,7 +274,7 @@ std::wstring UnbufferedTokenStream::getText(const misc::Interval &interval)
|
|||
|
||||
std::wstringstream ss;
|
||||
for (size_t i = a; i <= b; i++) {
|
||||
Token *t = tokens[i];
|
||||
TokenRef t = _tokens[i];
|
||||
if (i > 0)
|
||||
ss << L", ";
|
||||
ss << t->getText();
|
||||
|
@ -283,12 +285,12 @@ std::wstring UnbufferedTokenStream::getText(const misc::Interval &interval)
|
|||
|
||||
size_t UnbufferedTokenStream::getBufferStartIndex() const
|
||||
{
|
||||
return currentTokenIndex - p;
|
||||
return _currentTokenIndex - _p;
|
||||
}
|
||||
|
||||
void UnbufferedTokenStream::InitializeInstanceFields()
|
||||
{
|
||||
p = 0;
|
||||
numMarkers = 0;
|
||||
currentTokenIndex = 0;
|
||||
_p = 0;
|
||||
_numMarkers = 0;
|
||||
_currentTokenIndex = 0;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,43 @@ namespace v4 {
|
|||
namespace runtime {
|
||||
|
||||
class UnbufferedTokenStream : public TokenStream {
|
||||
public:
|
||||
UnbufferedTokenStream(TokenSource *tokenSource);
|
||||
UnbufferedTokenStream(TokenSource *tokenSource, int bufferSize);
|
||||
virtual ~UnbufferedTokenStream();
|
||||
|
||||
virtual TokenRef get(size_t i) const override;
|
||||
virtual TokenRef LT(ssize_t i) override;
|
||||
virtual ssize_t LA(ssize_t i) override;
|
||||
|
||||
virtual TokenSource* getTokenSource() const override;
|
||||
|
||||
virtual std::wstring getText(const misc::Interval &interval) override;
|
||||
virtual std::wstring getText() override;
|
||||
virtual std::wstring getText(RuleContext *ctx) override;
|
||||
virtual std::wstring getText(TokenRef start, TokenRef stop) override;
|
||||
|
||||
virtual void consume() override;
|
||||
|
||||
/// <summary>
|
||||
/// Return a marker that we can release later.
|
||||
/// <p/>
|
||||
/// The specific marker value used for this class allows for some level of
|
||||
/// protection against misuse where {@code seek()} is called on a mark or
|
||||
/// {@code release()} is called in the wrong order.
|
||||
/// </summary>
|
||||
virtual ssize_t mark() override;
|
||||
virtual void release(ssize_t marker) override;
|
||||
virtual size_t index() override;
|
||||
virtual void seek(size_t index) override;
|
||||
virtual size_t size() override;
|
||||
virtual std::string getSourceName() const override;
|
||||
|
||||
protected:
|
||||
TokenSource *tokenSource;
|
||||
/// Make sure we have 'need' elements from current position p. Last valid
|
||||
/// p index is tokens.length - 1. p + need - 1 is the tokens index 'need' elements
|
||||
/// ahead. If we need 1 element, (p+1-1)==p must be less than tokens.length.
|
||||
TokenSource *_tokenSource;
|
||||
|
||||
/// <summary>
|
||||
/// A moving window buffer of the data being scanned. While there's a marker,
|
||||
|
@ -48,7 +83,7 @@ namespace runtime {
|
|||
/// we start filling at index 0 again.
|
||||
/// </summary>
|
||||
|
||||
std::vector<Token *> tokens;
|
||||
std::vector<TokenRef> _tokens;
|
||||
|
||||
/// <summary>
|
||||
/// 0..n-1 index into <seealso cref="#tokens tokens"/> of next token.
|
||||
|
@ -56,7 +91,7 @@ namespace runtime {
|
|||
/// The {@code LT(1)} token is {@code tokens[p]}. If {@code p == n}, we are
|
||||
/// out of buffered tokens.
|
||||
/// </summary>
|
||||
size_t p;
|
||||
size_t _p;
|
||||
|
||||
/// <summary>
|
||||
/// Count up with <seealso cref="#mark mark()"/> and down with
|
||||
|
@ -64,18 +99,18 @@ namespace runtime {
|
|||
/// {@code numMarkers} reaches 0 and we reset the buffer. Copy
|
||||
/// {@code tokens[p]..tokens[n-1]} to {@code tokens[0]..tokens[(n-1)-p]}.
|
||||
/// </summary>
|
||||
int numMarkers;
|
||||
int _numMarkers;
|
||||
|
||||
/// <summary>
|
||||
/// This is the {@code LT(-1)} token for the current position.
|
||||
/// </summary>
|
||||
Token *lastToken;
|
||||
TokenRef _lastToken;
|
||||
|
||||
/// <summary>
|
||||
/// When {@code numMarkers > 0}, this is the {@code LT(-1)} token for the
|
||||
/// first token in <seealso cref="#tokens"/>. Otherwise, this is {@code null}.
|
||||
/// </summary>
|
||||
Token *lastTokenBufferStart;
|
||||
TokenRef _lastTokenBufferStart;
|
||||
|
||||
/// <summary>
|
||||
/// Absolute token index. It's the index of the token about to be read via
|
||||
|
@ -85,31 +120,8 @@ namespace runtime {
|
|||
/// This value is used to set the token indexes if the stream provides tokens
|
||||
/// that implement <seealso cref="WritableToken"/>.
|
||||
/// </summary>
|
||||
size_t currentTokenIndex;
|
||||
|
||||
public:
|
||||
UnbufferedTokenStream(TokenSource *tokenSource);
|
||||
UnbufferedTokenStream(TokenSource *tokenSource, int bufferSize);
|
||||
|
||||
virtual Token *get(size_t i) const override;
|
||||
virtual Token *LT(ssize_t i) override;
|
||||
virtual ssize_t LA(ssize_t i) override;
|
||||
|
||||
virtual TokenSource *getTokenSource() const override;
|
||||
|
||||
virtual std::wstring getText(const misc::Interval &interval) override;
|
||||
virtual std::wstring getText() override;
|
||||
virtual std::wstring getText(RuleContext *ctx) override;
|
||||
virtual std::wstring getText(Token *start, Token *stop) override;
|
||||
|
||||
virtual void consume() override;
|
||||
|
||||
/// <summary>
|
||||
/// Make sure we have 'need' elements from current position <seealso cref="#p p"/>. Last valid
|
||||
/// {@code p} index is {@code tokens.length-1}. {@code p+need-1} is the tokens index 'need' elements
|
||||
/// ahead. If we need 1 element, {@code (p+1-1)==p} must be less than {@code tokens.length}.
|
||||
/// </summary>
|
||||
protected:
|
||||
size_t _currentTokenIndex;
|
||||
|
||||
virtual void sync(ssize_t want);
|
||||
|
||||
/// <summary>
|
||||
|
@ -118,24 +130,8 @@ namespace runtime {
|
|||
/// then EOF was reached before {@code n} tokens could be added.
|
||||
/// </summary>
|
||||
virtual size_t fill(size_t n);
|
||||
virtual void add(Token *t);
|
||||
virtual void add(TokenRef t);
|
||||
|
||||
/// <summary>
|
||||
/// Return a marker that we can release later.
|
||||
/// <p/>
|
||||
/// The specific marker value used for this class allows for some level of
|
||||
/// protection against misuse where {@code seek()} is called on a mark or
|
||||
/// {@code release()} is called in the wrong order.
|
||||
/// </summary>
|
||||
public:
|
||||
virtual ssize_t mark() override;
|
||||
virtual void release(ssize_t marker) override;
|
||||
virtual size_t index() override;
|
||||
virtual void seek(size_t index) override;
|
||||
virtual size_t size() override;
|
||||
virtual std::string getSourceName() const override;
|
||||
|
||||
protected:
|
||||
size_t getBufferStartIndex() const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -50,7 +50,7 @@ ATN::ATN() : ATN(ATNType::LEXER, 0) {
|
|||
ATN::ATN(ATNType grammarType, int maxTokenType) : grammarType(grammarType), maxTokenType(maxTokenType) {
|
||||
}
|
||||
|
||||
misc::IntervalSet ATN::nextTokens(ATNState *s, RuleContext *ctx) const {
|
||||
misc::IntervalSet ATN::nextTokens(ATNState *s, RuleContextRef ctx) const {
|
||||
LL1Analyzer analyzer(*this);
|
||||
return analyzer.LOOK(s, ctx);
|
||||
|
||||
|
@ -95,12 +95,12 @@ int ATN::getNumberOfDecisions() const {
|
|||
return (int)decisionToState.size();
|
||||
}
|
||||
|
||||
misc::IntervalSet ATN::getExpectedTokens(int stateNumber, RuleContext *context) const {
|
||||
misc::IntervalSet ATN::getExpectedTokens(int stateNumber, RuleContextRef context) const {
|
||||
if (stateNumber < 0 || stateNumber >= (int)states.size()) {
|
||||
throw IllegalArgumentException("Invalid state number.");
|
||||
}
|
||||
|
||||
RuleContext *ctx = context;
|
||||
RuleContextRef ctx = context;
|
||||
ATNState *s = states.at((size_t)stateNumber);
|
||||
misc::IntervalSet following = nextTokens(s);
|
||||
if (!following.contains(Token::EPSILON)) {
|
||||
|
@ -110,13 +110,17 @@ misc::IntervalSet ATN::getExpectedTokens(int stateNumber, RuleContext *context)
|
|||
misc::IntervalSet expected;
|
||||
expected.addAll(following);
|
||||
expected.remove(Token::EPSILON);
|
||||
while (ctx != nullptr && ctx->invokingState >= 0 && following.contains(Token::EPSILON)) {
|
||||
while (ctx && ctx->invokingState >= 0 && following.contains(Token::EPSILON)) {
|
||||
ATNState *invokingState = states.at((size_t)ctx->invokingState);
|
||||
RuleTransition *rt = static_cast<RuleTransition*>(invokingState->transition(0));
|
||||
following = nextTokens(rt->followState);
|
||||
expected.addAll(following);
|
||||
expected.remove(Token::EPSILON);
|
||||
ctx = ctx->parent;
|
||||
|
||||
if (ctx->parent.expired()) {
|
||||
break;
|
||||
}
|
||||
ctx = ctx->parent.lock();
|
||||
}
|
||||
|
||||
if (following.contains(Token::EPSILON)) {
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace atn {
|
|||
/// the rule surrounding {@code s}. In other words, the set will be
|
||||
/// restricted to tokens reachable staying within {@code s}'s rule.
|
||||
/// </summary>
|
||||
virtual misc::IntervalSet nextTokens(ATNState *s, RuleContext *ctx) const;
|
||||
virtual misc::IntervalSet nextTokens(ATNState *s, RuleContextRef ctx) const;
|
||||
|
||||
/// <summary>
|
||||
/// Compute the set of valid tokens that can occur starting in {@code s} and
|
||||
|
@ -126,7 +126,7 @@ namespace atn {
|
|||
/// specified state in the specified context. </returns>
|
||||
/// <exception cref="IllegalArgumentException"> if the ATN does not contain a state with
|
||||
/// number {@code stateNumber} </exception>
|
||||
virtual misc::IntervalSet getExpectedTokens(int stateNumber, RuleContext *context) const;
|
||||
virtual misc::IntervalSet getExpectedTokens(int stateNumber, RuleContextRef context) const;
|
||||
};
|
||||
|
||||
} // namespace atn
|
||||
|
|
|
@ -87,3 +87,25 @@ bool ATNConfig::operator == (const ATNConfig& other) const
|
|||
std::wstring ATNConfig::toString() {
|
||||
return toString(true);
|
||||
}
|
||||
|
||||
std::wstring ATNConfig::toString(bool showAlt) {
|
||||
std::wstringstream ss;
|
||||
ss << L"(";
|
||||
|
||||
ss << state->toString();
|
||||
if (showAlt) {
|
||||
ss << L"," << alt;
|
||||
}
|
||||
if (context) {
|
||||
ss << L",[" << context->toString() << L"]";
|
||||
}
|
||||
if (semanticContext != nullptr && semanticContext != SemanticContext::NONE) {
|
||||
ss << L"," << semanticContext.get();
|
||||
}
|
||||
if (reachesIntoOuterContext > 0) {
|
||||
ss << L",up=" << reachesIntoOuterContext;
|
||||
}
|
||||
ss << L')';
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
|
|
@ -111,28 +111,7 @@ namespace atn {
|
|||
bool operator == (const ATNConfig &other) const;
|
||||
|
||||
virtual std::wstring toString();
|
||||
|
||||
std::wstring toString(bool showAlt) {
|
||||
std::wstringstream ss(L" (");
|
||||
|
||||
ss << state;
|
||||
if (showAlt) {
|
||||
ss << L"," << alt;
|
||||
}
|
||||
if (context != nullptr) {
|
||||
ss << L",[" << context->toString() << L"]";
|
||||
}
|
||||
if (semanticContext != nullptr && semanticContext != SemanticContext::NONE) {
|
||||
ss << L"," << semanticContext.get();
|
||||
}
|
||||
if (reachesIntoOuterContext > 0) {
|
||||
ss << L",up=" << reachesIntoOuterContext;
|
||||
}
|
||||
ss << L')';
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::wstring toString(bool showAlt);
|
||||
};
|
||||
|
||||
} // namespace atn
|
||||
|
|
|
@ -57,12 +57,11 @@ bool SimpleATNConfigComparer::operator () (const ATNConfig &lhs, const ATNConfig
|
|||
|
||||
//------------------ ATNConfigSet --------------------------------------------------------------------------------------
|
||||
|
||||
ATNConfigSet::ATNConfigSet(bool fullCtx, std::shared_ptr<ConfigLookup> lookup) : fullCtx(fullCtx) {
|
||||
configLookup = !lookup ? std::shared_ptr<ConfigLookup>(new ConfigLookupImpl<SimpleATNConfigHasher, SimpleATNConfigComparer>()) : lookup;
|
||||
ATNConfigSet::ATNConfigSet(bool fullCtx) : fullCtx(fullCtx) {
|
||||
InitializeInstanceFields();
|
||||
}
|
||||
|
||||
ATNConfigSet::ATNConfigSet(std::shared_ptr<ATNConfigSet> old) : ATNConfigSet(old->fullCtx, std::shared_ptr<ConfigLookup>()) {
|
||||
ATNConfigSet::ATNConfigSet(std::shared_ptr<ATNConfigSet> old) : ATNConfigSet(old->fullCtx) {
|
||||
addAll(old);
|
||||
uniqueAlt = old->uniqueAlt;
|
||||
conflictingAlts = old->conflictingAlts;
|
||||
|
@ -228,9 +227,11 @@ void ATNConfigSet::setReadonly(bool readonly) {
|
|||
|
||||
std::wstring ATNConfigSet::toString() {
|
||||
std::wstringstream ss;
|
||||
ss << L"[";
|
||||
for (size_t i = 0; i < elements().size(); i++) {
|
||||
ss << elements().at(i)->toString();
|
||||
ss << configs[i]->toString();
|
||||
}
|
||||
ss << L"]";
|
||||
|
||||
if (hasSemanticContext) {
|
||||
ss << L",hasSemanticContext = " << hasSemanticContext;
|
||||
|
@ -238,10 +239,12 @@ std::wstring ATNConfigSet::toString() {
|
|||
if (uniqueAlt != ATN::INVALID_ALT_NUMBER) {
|
||||
ss << L",uniqueAlt = " << uniqueAlt;
|
||||
}
|
||||
if (conflictingAlts != nullptr) {
|
||||
|
||||
if (conflictingAlts.size() > 0) {
|
||||
ss << L",conflictingAlts = ";
|
||||
ss << conflictingAlts->toString();
|
||||
ss << conflictingAlts.toString();
|
||||
}
|
||||
|
||||
if (dipsIntoOuterContext) {
|
||||
ss << L", dipsIntoOuterContext";
|
||||
}
|
||||
|
@ -253,6 +256,7 @@ bool ATNConfigSet::remove(void *o) {
|
|||
}
|
||||
|
||||
void ATNConfigSet::InitializeInstanceFields() {
|
||||
configLookup = std::shared_ptr<ConfigLookup>(new ConfigLookupImpl<SimpleATNConfigHasher, SimpleATNConfigComparer>());
|
||||
uniqueAlt = 0;
|
||||
hasSemanticContext = false;
|
||||
dipsIntoOuterContext = false;
|
||||
|
|
|
@ -55,10 +55,8 @@ namespace atn {
|
|||
/// graph-structured stack.
|
||||
class ATNConfigSet {
|
||||
public:
|
||||
/// <summary>
|
||||
/// All configs but hashed by (s, i, _, pi) not including context. Wiped out
|
||||
/// when we go readonly as this set becomes a DFA state.
|
||||
/// </summary>
|
||||
std::shared_ptr<ConfigLookup> configLookup;
|
||||
|
||||
/// <summary>
|
||||
|
@ -69,7 +67,7 @@ namespace atn {
|
|||
// TO_DO: can we track conflicts as they are added to save scanning configs later?
|
||||
int uniqueAlt;
|
||||
|
||||
antlrcpp::BitSet *conflictingAlts;
|
||||
antlrcpp::BitSet conflictingAlts;
|
||||
|
||||
// Used in parser and lexer. In lexer, it indicates we hit a pred
|
||||
// while computing a closure operation. Don't make a DFA state from this.
|
||||
|
@ -83,7 +81,7 @@ namespace atn {
|
|||
/// </summary>
|
||||
const bool fullCtx;
|
||||
|
||||
ATNConfigSet(bool fullCtx, std::shared_ptr<ConfigLookup> lookup);
|
||||
ATNConfigSet(bool fullCtx = true);
|
||||
ATNConfigSet(std::shared_ptr<ATNConfigSet> old);
|
||||
|
||||
virtual ~ATNConfigSet();
|
||||
|
|
|
@ -37,10 +37,11 @@
|
|||
|
||||
using namespace org::antlr::v4::runtime::atn;
|
||||
|
||||
ATNState::~ATNState() {};
|
||||
|
||||
const int ATNState::INITIAL_NUM_TRANSITIONS;
|
||||
const int ATNState::INVALID_STATE_NUMBER;
|
||||
|
||||
ATNState::~ATNState() {
|
||||
};
|
||||
|
||||
const wchar_t * ATNState::serializationNames[] = {L"INVALID", L"BASIC", L"RULE_START", L"BLOCK_START",
|
||||
L"PLUS_BLOCK_START", L"STAR_BLOCK_START", L"TOKEN_START", L"RULE_STOP",
|
||||
|
@ -50,12 +51,8 @@ size_t ATNState::hashCode() {
|
|||
return (size_t)stateNumber;
|
||||
}
|
||||
|
||||
bool ATNState::equals(void *o) {
|
||||
// are these states same object?
|
||||
if (o != nullptr) {
|
||||
return stateNumber == (static_cast<ATNState*>(o))->stateNumber;
|
||||
}
|
||||
return false;
|
||||
bool ATNState::operator == (const ATNState &other) {
|
||||
return stateNumber == other.stateNumber;
|
||||
}
|
||||
|
||||
bool ATNState::isNonGreedyExitState() {
|
||||
|
|
|
@ -104,6 +104,7 @@ namespace atn {
|
|||
virtual ~ATNState();
|
||||
|
||||
static const int INITIAL_NUM_TRANSITIONS = 4;
|
||||
static const int INVALID_STATE_NUMBER = -1;
|
||||
|
||||
enum {
|
||||
ATN_INVALID_TYPE = 0,
|
||||
|
@ -123,8 +124,6 @@ namespace atn {
|
|||
|
||||
static const wchar_t * serializationNames[];
|
||||
|
||||
static const int INVALID_STATE_NUMBER = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Which ATN are we in? </summary>
|
||||
ATN *atn = nullptr;
|
||||
|
@ -146,7 +145,7 @@ namespace atn {
|
|||
misc::IntervalSet nextTokenWithinRule;
|
||||
|
||||
virtual size_t hashCode();
|
||||
virtual bool equals(void *o);
|
||||
bool operator == (const ATNState &other);
|
||||
|
||||
virtual bool isNonGreedyExitState();
|
||||
|
||||
|
|
|
@ -82,7 +82,8 @@ std::wstring ArrayPredictionContext::toString() {
|
|||
return L"[]";
|
||||
}
|
||||
|
||||
std::wstringstream ss(L"[");
|
||||
std::wstringstream ss;
|
||||
ss << L"[";
|
||||
for (size_t i = 0; i < returnStates.size(); i++) {
|
||||
if (i > 0) {
|
||||
ss << L", ";
|
||||
|
|
|
@ -74,11 +74,11 @@ std::vector<misc::IntervalSet> LL1Analyzer::getDecisionLookahead(ATNState *s) co
|
|||
return look;
|
||||
}
|
||||
|
||||
misc::IntervalSet LL1Analyzer::LOOK(ATNState *s, RuleContext *ctx) const {
|
||||
misc::IntervalSet LL1Analyzer::LOOK(ATNState *s, RuleContextRef ctx) const {
|
||||
return LOOK(s, nullptr, ctx);
|
||||
}
|
||||
|
||||
misc::IntervalSet LL1Analyzer::LOOK(ATNState *s, ATNState *stopState, RuleContext *ctx) const {
|
||||
misc::IntervalSet LL1Analyzer::LOOK(ATNState *s, ATNState *stopState, RuleContextRef ctx) const {
|
||||
misc::IntervalSet r;
|
||||
bool seeThruPreds = true; // ignore preds; get all lookahead
|
||||
PredictionContextRef lookContext = ctx != nullptr ? PredictionContext::fromRuleContext(*s->atn, ctx) : nullptr;
|
||||
|
@ -122,14 +122,14 @@ void LL1Analyzer::_LOOK(ATNState *s, ATNState *stopState, PredictionContextRef c
|
|||
for (size_t i = 0; i < ctx->size(); i++) {
|
||||
ATNState *returnState = _atn.states[(size_t)ctx->getReturnState(i)];
|
||||
|
||||
bool removed = calledRuleStack.data.test((size_t)returnState->ruleIndex);
|
||||
bool removed = calledRuleStack.test((size_t)returnState->ruleIndex);
|
||||
auto onExit = finally([&] {
|
||||
if (removed) {
|
||||
calledRuleStack.set((size_t)returnState->ruleIndex);
|
||||
}
|
||||
});
|
||||
|
||||
calledRuleStack.data[(size_t)returnState->ruleIndex] = false;
|
||||
calledRuleStack[(size_t)returnState->ruleIndex] = false;
|
||||
_LOOK(returnState, stopState, ctx->getParent(i).lock(), look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
|
||||
}
|
||||
return;
|
||||
|
@ -141,13 +141,13 @@ void LL1Analyzer::_LOOK(ATNState *s, ATNState *stopState, PredictionContextRef c
|
|||
Transition *t = s->transition(i);
|
||||
|
||||
if (typeid(t) == typeid(RuleTransition)) {
|
||||
if (calledRuleStack.data[(size_t)(static_cast<RuleTransition*>(t))->target->ruleIndex]) {
|
||||
if (calledRuleStack[(size_t)(static_cast<RuleTransition*>(t))->target->ruleIndex]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PredictionContextRef newContext = SingletonPredictionContext::create(ctx, (static_cast<RuleTransition*>(t))->followState->stateNumber);
|
||||
auto onExit = finally([&] {
|
||||
calledRuleStack.data[(size_t)((static_cast<RuleTransition*>(t))->target->ruleIndex)] = false;
|
||||
calledRuleStack[(size_t)((static_cast<RuleTransition*>(t))->target->ruleIndex)] = false;
|
||||
});
|
||||
|
||||
calledRuleStack.set((size_t)(static_cast<RuleTransition*>(t))->target->ruleIndex);
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace atn {
|
|||
/// </param>
|
||||
/// <returns> The set of tokens that can follow {@code s} in the ATN in the
|
||||
/// specified {@code ctx}. </returns>
|
||||
virtual misc::IntervalSet LOOK(ATNState *s, RuleContext *ctx) const;
|
||||
virtual misc::IntervalSet LOOK(ATNState *s, RuleContextRef ctx) const;
|
||||
|
||||
/// <summary>
|
||||
/// Compute set of tokens that can follow {@code s} in the ATN in the
|
||||
|
@ -98,7 +98,7 @@ namespace atn {
|
|||
/// </param>
|
||||
/// <returns> The set of tokens that can follow {@code s} in the ATN in the
|
||||
/// specified {@code ctx}. </returns>
|
||||
virtual misc::IntervalSet LOOK(ATNState *s, ATNState *stopState, RuleContext *ctx) const;
|
||||
virtual misc::IntervalSet LOOK(ATNState *s, ATNState *stopState, RuleContextRef ctx) const;
|
||||
|
||||
/// <summary>
|
||||
/// Compute set of tokens that can follow {@code s} in the ATN in the
|
||||
|
|
|
@ -91,7 +91,7 @@ int LexerATNSimulator::match(CharStream *input, size_t mode) {
|
|||
_mode = mode;
|
||||
ssize_t mark = input->mark();
|
||||
|
||||
auto onExit = finally([=] {
|
||||
auto onExit = finally([&] {
|
||||
input->release(mark);
|
||||
});
|
||||
|
||||
|
@ -179,6 +179,7 @@ int LexerATNSimulator::execATN(CharStream *input, dfa::DFAState *ds0) {
|
|||
target = computeTargetState(input, s, t);
|
||||
}
|
||||
|
||||
std::wstring temp = target->toString();
|
||||
if (target == ERROR.get()) {
|
||||
break;
|
||||
}
|
||||
|
@ -254,28 +255,27 @@ void LexerATNSimulator::getReachableConfigSet(CharStream *input, std::shared_ptr
|
|||
// this is used to skip processing for configs which have a lower priority
|
||||
// than a config that already reached an accept state for the same rule
|
||||
int skipAlt = ATN::INVALID_ALT_NUMBER;
|
||||
if (closure->configLookup) {
|
||||
for (auto c : *closure->configLookup) {
|
||||
bool currentAltReachedAcceptState = c->alt == skipAlt;
|
||||
if (currentAltReachedAcceptState && (static_cast<LexerATNConfig*>(c))->hasPassedThroughNonGreedyDecision()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
std::wcout << L"testing " << getTokenName((int)t) << " at " << c->toString(true) << std::endl;
|
||||
}
|
||||
for (auto c : closure->configs) {
|
||||
bool currentAltReachedAcceptState = c->alt == skipAlt;
|
||||
if (currentAltReachedAcceptState && (static_cast<LexerATNConfig*>(c))->hasPassedThroughNonGreedyDecision()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t n = c->state->getNumberOfTransitions();
|
||||
for (size_t ti = 0; ti < n; ti++) { // for each transition
|
||||
Transition *trans = c->state->transition(ti);
|
||||
ATNState *target = getReachableTarget(trans, (int)t);
|
||||
if (target != nullptr) {
|
||||
if (this->closure(input, new LexerATNConfig(static_cast<LexerATNConfig*>(c), target), reach, currentAltReachedAcceptState, true)) {
|
||||
// any remaining configs for this alt have a lower priority than
|
||||
// the one that just reached an accept state.
|
||||
skipAlt = c->alt;
|
||||
break;
|
||||
}
|
||||
if (debug) {
|
||||
std::wcout << L"testing " << getTokenName((int)t) << " at " << c->toString(true) << std::endl;
|
||||
}
|
||||
|
||||
size_t n = c->state->getNumberOfTransitions();
|
||||
for (size_t ti = 0; ti < n; ti++) { // for each transition
|
||||
Transition *trans = c->state->transition(ti);
|
||||
ATNState *target = getReachableTarget(trans, (int)t);
|
||||
if (target != nullptr) {
|
||||
if (this->closure(input, new LexerATNConfig(static_cast<LexerATNConfig*>(c), target), reach, currentAltReachedAcceptState, true)) {
|
||||
// any remaining configs for this alt have a lower priority than
|
||||
// the one that just reached an accept state.
|
||||
skipAlt = c->alt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -522,7 +522,7 @@ dfa::DFAState *LexerATNSimulator::addDFAState(std::shared_ptr<ATNConfigSet> conf
|
|||
|
||||
dfa::DFAState *proposed = new dfa::DFAState(configs);
|
||||
ATNConfig *firstConfigWithRuleStopState = nullptr;
|
||||
for (auto c : *configs->configLookup) {
|
||||
for (auto c : configs->configs) {
|
||||
if (dynamic_cast<RuleStopState*>(c->state) != nullptr) {
|
||||
firstConfigWithRuleStopState = c;
|
||||
break;
|
||||
|
|
|
@ -33,6 +33,6 @@
|
|||
|
||||
using namespace org::antlr::v4::runtime::atn;
|
||||
|
||||
OrderedATNConfigSet::OrderedATNConfigSet()
|
||||
: ATNConfigSet(true, std::shared_ptr<ConfigLookup>(new ConfigLookupImpl<OrderedATNConfigHasher, OrderedATNConfigComparer>())) {
|
||||
OrderedATNConfigSet::OrderedATNConfigSet() : ATNConfigSet() {
|
||||
configLookup = std::shared_ptr<ConfigLookup>(new ConfigLookupImpl<OrderedATNConfigHasher, OrderedATNConfigComparer>());
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ ParserATNSimulator::ParserATNSimulator(Parser *parser, const ATN &atn, const std
|
|||
void ParserATNSimulator::reset() {
|
||||
}
|
||||
|
||||
int ParserATNSimulator::adaptivePredict(TokenStream *input, int decision, ParserRuleContext *outerContext) {
|
||||
int ParserATNSimulator::adaptivePredict(TokenStream *input, int decision, ParserRuleContextRef outerContext) {
|
||||
if (debug || debug_list_atn_decisions) {
|
||||
std::wcout << L"adaptivePredict decision " << decision << L" exec LA(1)==" << getLookaheadName(input) << L" line " << input->LT(1)->getLine() << L":" << input->LT(1)->getCharPositionInLine() << std::endl;
|
||||
}
|
||||
|
@ -123,9 +123,10 @@ int ParserATNSimulator::adaptivePredict(TokenStream *input, int decision, Parser
|
|||
}
|
||||
|
||||
int ParserATNSimulator::execATN(dfa::DFA *dfa, dfa::DFAState *s0, TokenStream *input, size_t startIndex,
|
||||
ParserRuleContext *outerContext) {
|
||||
ParserRuleContextRef outerContext) {
|
||||
if (debug || debug_list_atn_decisions) {
|
||||
std::wcout << L"execATN decision " << dfa->decision << L" exec LA(1)==" << getLookaheadName(input) << L" line " << input->LT(1)->getLine() << L":" << input->LT(1)->getCharPositionInLine() << std::endl;
|
||||
std::wcout << L"execATN decision " << dfa->decision << L" exec LA(1)==" << getLookaheadName(input) <<
|
||||
L" line " << input->LT(1)->getLine() << L":" << input->LT(1)->getCharPositionInLine() << std::endl;
|
||||
}
|
||||
|
||||
dfa::DFAState *previousD = s0;
|
||||
|
@ -163,7 +164,7 @@ int ParserATNSimulator::execATN(dfa::DFA *dfa, dfa::DFAState *s0, TokenStream *i
|
|||
|
||||
if (D->requiresFullContext && mode != PredictionMode::SLL) {
|
||||
// IF PREDS, MIGHT RESOLVE TO SINGLE ALT => SLL (or syntax error)
|
||||
BitSet *conflictingAlts = nullptr;
|
||||
BitSet conflictingAlts;
|
||||
if (D->predicates.size() != 0) {
|
||||
if (debug) {
|
||||
std::wcout << L"DFA state has preds in DFA sim LL failover" << std::endl;
|
||||
|
@ -174,11 +175,11 @@ int ParserATNSimulator::execATN(dfa::DFA *dfa, dfa::DFAState *s0, TokenStream *i
|
|||
}
|
||||
|
||||
conflictingAlts = evalSemanticContext(D->predicates, outerContext, true);
|
||||
if (conflictingAlts->count() == 1) {
|
||||
if (conflictingAlts.count() == 1) {
|
||||
if (debug) {
|
||||
std::wcout << L"Full LL avoided" << std::endl;
|
||||
}
|
||||
return conflictingAlts->nextSetBit(0);
|
||||
return conflictingAlts.nextSetBit(0);
|
||||
}
|
||||
|
||||
if (conflictIndex != startIndex) {
|
||||
|
@ -205,19 +206,19 @@ int ParserATNSimulator::execATN(dfa::DFA *dfa, dfa::DFAState *s0, TokenStream *i
|
|||
|
||||
size_t stopIndex = input->index();
|
||||
input->seek(startIndex);
|
||||
BitSet *alts = evalSemanticContext(D->predicates, outerContext, true);
|
||||
switch (alts->count()) {
|
||||
BitSet alts = evalSemanticContext(D->predicates, outerContext, true);
|
||||
switch (alts.count()) {
|
||||
case 0:
|
||||
throw noViableAlt(input, outerContext, D->configs, startIndex);
|
||||
|
||||
case 1:
|
||||
return alts->nextSetBit(0);
|
||||
return alts.nextSetBit(0);
|
||||
|
||||
default:
|
||||
// report ambiguity after predicate evaluation to make sure the correct
|
||||
// set of ambig alts is reported.
|
||||
reportAmbiguity(dfa, D, startIndex, stopIndex, false, alts, D->configs);
|
||||
return alts->nextSetBit(0);
|
||||
return alts.nextSetBit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,11 +270,11 @@ dfa::DFAState *ParserATNSimulator::computeTargetState(dfa::DFA *dfa, dfa::DFASta
|
|||
D->prediction = predictedAlt;
|
||||
} else if (PredictionModeClass::hasSLLConflictTerminatingPrediction(&mode, reach)) {
|
||||
// MORE THAN ONE VIABLE ALTERNATIVE
|
||||
D->configs->conflictingAlts->data = getConflictingAlts(reach).data;
|
||||
D->configs->conflictingAlts = getConflictingAlts(reach);
|
||||
D->requiresFullContext = true;
|
||||
// in SLL-only mode, we will stop at this state and return the minimum alt
|
||||
D->isAcceptState = true;
|
||||
D->prediction = D->configs->conflictingAlts->nextSetBit(0);
|
||||
D->prediction = D->configs->conflictingAlts.nextSetBit(0);
|
||||
}
|
||||
|
||||
if (D->isAcceptState && D->configs->hasSemanticContext) {
|
||||
|
@ -295,8 +296,7 @@ void ParserATNSimulator::predicateDFAState(dfa::DFAState *dfaState, DecisionStat
|
|||
|
||||
// Update DFA so reach becomes accept state with (predicate,alt)
|
||||
// pairs if preds found for conflicting alts
|
||||
BitSet *altsToCollectPredsFrom = nullptr;
|
||||
altsToCollectPredsFrom->data = getConflictingAltsOrUniqueAlt(dfaState->configs).data;
|
||||
BitSet altsToCollectPredsFrom = getConflictingAltsOrUniqueAlt(dfaState->configs);
|
||||
std::vector<SemanticContextRef> altToPred = getPredsForAmbigAlts(altsToCollectPredsFrom, dfaState->configs, nalts);
|
||||
if (!altToPred.empty()) {
|
||||
dfaState->predicates = getPredicatePredictions(altsToCollectPredsFrom, altToPred);
|
||||
|
@ -305,12 +305,12 @@ void ParserATNSimulator::predicateDFAState(dfa::DFAState *dfaState, DecisionStat
|
|||
// There are preds in configs but they might go away
|
||||
// when OR'd together like {p}? || NONE == NONE. If neither
|
||||
// alt has preds, resolve to min alt
|
||||
dfaState->prediction = altsToCollectPredsFrom->nextSetBit(0);
|
||||
dfaState->prediction = altsToCollectPredsFrom.nextSetBit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int ParserATNSimulator::execATNWithFullContext(dfa::DFA *dfa, dfa::DFAState *D, std::shared_ptr<ATNConfigSet> s0,
|
||||
TokenStream *input, size_t startIndex, ParserRuleContext *outerContext) {
|
||||
TokenStream *input, size_t startIndex, ParserRuleContextRef outerContext) {
|
||||
if (debug || debug_list_atn_decisions) {
|
||||
std::cout << "execATNWithFullContext " << s0 << std::endl;
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ int ParserATNSimulator::execATNWithFullContext(dfa::DFA *dfa, dfa::DFAState *D,
|
|||
the fact that we should predict alternative 1. We just can't say for
|
||||
sure that there is an ambiguity without looking further.
|
||||
*/
|
||||
reportAmbiguity(dfa, D, (size_t)startIndex, input->index(), foundExactAmbig, nullptr, reach);
|
||||
reportAmbiguity(dfa, D, (size_t)startIndex, input->index(), foundExactAmbig, BitSet(), reach);
|
||||
|
||||
return predictedAlt;
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ std::shared_ptr<ATNConfigSet> ParserATNSimulator::computeReachSet(std::shared_pt
|
|||
std::wcout << L"in computeReachSet, starting closure: " << closure << std::endl;
|
||||
}
|
||||
|
||||
std::shared_ptr<ATNConfigSet> intermediate = std::make_shared<ATNConfigSet>(fullCtx, std::shared_ptr<ConfigLookup>());
|
||||
std::shared_ptr<ATNConfigSet> intermediate = std::make_shared<ATNConfigSet>(fullCtx);
|
||||
|
||||
/* Configurations already in a rule stop state indicate reaching the end
|
||||
* of the decision rule (local context) or end of the start rule (full
|
||||
|
@ -443,7 +443,7 @@ std::shared_ptr<ATNConfigSet> ParserATNSimulator::computeReachSet(std::shared_pt
|
|||
std::vector<ATNConfig*> skippedStopStates;
|
||||
|
||||
// First figure out where we can reach on input t
|
||||
for (auto c : *closure->configLookup) {
|
||||
for (auto c : closure->configs) {
|
||||
if (debug) {
|
||||
std::wcout << L"testing " << getTokenName(t) << L" at " << c->toString() << std::endl;
|
||||
}
|
||||
|
@ -502,10 +502,10 @@ std::shared_ptr<ATNConfigSet> ParserATNSimulator::computeReachSet(std::shared_pt
|
|||
* operation on the intermediate set to compute its initial value.
|
||||
*/
|
||||
if (reach == nullptr) {
|
||||
reach = std::make_shared<ATNConfigSet>(fullCtx, std::shared_ptr<ConfigLookup>());
|
||||
reach = std::make_shared<ATNConfigSet>(fullCtx);
|
||||
std::set<ATNConfig*> closureBusy;
|
||||
|
||||
for (auto c : *intermediate->configLookup) {
|
||||
for (auto c : intermediate->configs) {
|
||||
this->closure(c, reach, closureBusy, false, fullCtx);
|
||||
}
|
||||
}
|
||||
|
@ -559,9 +559,9 @@ std::shared_ptr<ATNConfigSet> ParserATNSimulator::removeAllConfigsNotInRuleStopS
|
|||
return configs;
|
||||
}
|
||||
|
||||
std::shared_ptr<ATNConfigSet> result = std::make_shared<ATNConfigSet>(configs->fullCtx, std::shared_ptr<ConfigLookup>());
|
||||
std::shared_ptr<ATNConfigSet> result = std::make_shared<ATNConfigSet>(configs->fullCtx);
|
||||
|
||||
for (auto config : *configs->configLookup) {
|
||||
for (auto config : configs->configs) {
|
||||
if (dynamic_cast<RuleStopState*>(config->state) != nullptr) {
|
||||
result->add(config, &mergeCache);
|
||||
continue;
|
||||
|
@ -579,10 +579,10 @@ std::shared_ptr<ATNConfigSet> ParserATNSimulator::removeAllConfigsNotInRuleStopS
|
|||
return result;
|
||||
}
|
||||
|
||||
std::shared_ptr<ATNConfigSet> ParserATNSimulator::computeStartState(ATNState *p, RuleContext *ctx, bool fullCtx) {
|
||||
std::shared_ptr<ATNConfigSet> ParserATNSimulator::computeStartState(ATNState *p, RuleContextRef ctx, bool fullCtx) {
|
||||
// always at least the implicit call to start rule
|
||||
PredictionContextRef initialContext = PredictionContext::fromRuleContext(atn, ctx);
|
||||
std::shared_ptr<ATNConfigSet> configs = std::make_shared<ATNConfigSet>(fullCtx, std::shared_ptr<ConfigLookup>());
|
||||
std::shared_ptr<ATNConfigSet> configs = std::make_shared<ATNConfigSet>(fullCtx);
|
||||
|
||||
for (size_t i = 0; i < p->getNumberOfTransitions(); i++) {
|
||||
ATNState *target = p->transition(i)->target;
|
||||
|
@ -603,7 +603,7 @@ atn::ATNState *ParserATNSimulator::getReachableTarget(Transition *trans, int tty
|
|||
}
|
||||
|
||||
// Note that caller must memory manage the returned value from this function
|
||||
std::vector<SemanticContextRef> ParserATNSimulator::getPredsForAmbigAlts(BitSet *ambigAlts,
|
||||
std::vector<SemanticContextRef> ParserATNSimulator::getPredsForAmbigAlts(const BitSet &ambigAlts,
|
||||
std::shared_ptr<ATNConfigSet> configs, size_t nalts) {
|
||||
// REACH=[1|1|[]|0:0, 1|2|[]|0:1]
|
||||
/* altToPred starts as an array of all null contexts. The entry at index i
|
||||
|
@ -619,8 +619,8 @@ std::vector<SemanticContextRef> ParserATNSimulator::getPredsForAmbigAlts(BitSet
|
|||
*/
|
||||
std::vector<SemanticContextRef> altToPred;
|
||||
|
||||
for (auto c : *configs->configLookup) {
|
||||
if (ambigAlts->data.test((size_t)c->alt)) {
|
||||
for (auto c : configs->configs) {
|
||||
if (ambigAlts.test((size_t)c->alt)) {
|
||||
if (altToPred.size() <= (size_t)c->alt)
|
||||
altToPred.resize((size_t)c->alt + 1);
|
||||
altToPred[(size_t)c->alt] = std::make_shared<SemanticContext::OR>(altToPred[(size_t)c->alt], c->semanticContext);
|
||||
|
@ -646,7 +646,7 @@ std::vector<SemanticContextRef> ParserATNSimulator::getPredsForAmbigAlts(BitSet
|
|||
return altToPred;
|
||||
}
|
||||
|
||||
std::vector<dfa::DFAState::PredPrediction *> ParserATNSimulator::getPredicatePredictions(BitSet *ambigAlts,
|
||||
std::vector<dfa::DFAState::PredPrediction *> ParserATNSimulator::getPredicatePredictions(const antlrcpp::BitSet &ambigAlts,
|
||||
std::vector<SemanticContextRef> altToPred) {
|
||||
std::vector<dfa::DFAState::PredPrediction*> pairs;
|
||||
bool containsPredicate = false;
|
||||
|
@ -656,7 +656,7 @@ std::vector<dfa::DFAState::PredPrediction *> ParserATNSimulator::getPredicatePre
|
|||
// unpredicted is indicated by SemanticContext.NONE
|
||||
assert(pred != nullptr);
|
||||
|
||||
if (ambigAlts != nullptr && ambigAlts->data.test(i)) {
|
||||
if (ambigAlts.test(i)) {
|
||||
pairs.push_back(new dfa::DFAState::PredPrediction(pred, (int)i));
|
||||
}
|
||||
if (pred != SemanticContext::NONE) {
|
||||
|
@ -673,7 +673,7 @@ std::vector<dfa::DFAState::PredPrediction *> ParserATNSimulator::getPredicatePre
|
|||
|
||||
int ParserATNSimulator::getAltThatFinishedDecisionEntryRule(std::shared_ptr<ATNConfigSet> configs) {
|
||||
misc::IntervalSet *alts = nullptr;
|
||||
for (auto c : *configs->configLookup) {
|
||||
for (auto c : configs->configs) {
|
||||
if (c->reachesIntoOuterContext > 0 || (dynamic_cast<RuleStopState*>(c->state) != nullptr && c->context->hasEmptyPath())) {
|
||||
alts->add(c->alt);
|
||||
}
|
||||
|
@ -684,11 +684,12 @@ int ParserATNSimulator::getAltThatFinishedDecisionEntryRule(std::shared_ptr<ATNC
|
|||
return alts->getMinElement();
|
||||
}
|
||||
|
||||
BitSet *ParserATNSimulator::evalSemanticContext(std::vector<dfa::DFAState::PredPrediction*> predPredictions, ParserRuleContext *outerContext, bool complete) {
|
||||
BitSet *predictions = new BitSet();
|
||||
BitSet ParserATNSimulator::evalSemanticContext(std::vector<dfa::DFAState::PredPrediction*> predPredictions,
|
||||
ParserRuleContextRef outerContext, bool complete) {
|
||||
BitSet predictions;
|
||||
for (auto pair : predPredictions) {
|
||||
if (pair->pred == SemanticContext::NONE) {
|
||||
predictions->set((size_t)pair->alt);
|
||||
predictions.set((size_t)pair->alt);
|
||||
if (!complete) {
|
||||
break;
|
||||
}
|
||||
|
@ -704,7 +705,7 @@ BitSet *ParserATNSimulator::evalSemanticContext(std::vector<dfa::DFAState::PredP
|
|||
if (debug || dfa_debug) {
|
||||
std::wcout << L"PREDICT " << pair->alt << std::endl;
|
||||
}
|
||||
predictions->set((size_t)pair->alt);
|
||||
predictions.set((size_t)pair->alt);
|
||||
if (!complete) {
|
||||
break;
|
||||
}
|
||||
|
@ -954,7 +955,7 @@ BitSet ParserATNSimulator::getConflictingAltsOrUniqueAlt(std::shared_ptr<ATNConf
|
|||
if (configs->uniqueAlt != ATN::INVALID_ALT_NUMBER) {
|
||||
conflictingAlts.set((size_t)configs->uniqueAlt);
|
||||
} else {
|
||||
conflictingAlts = *configs->conflictingAlts;
|
||||
conflictingAlts = configs->conflictingAlts;
|
||||
}
|
||||
return conflictingAlts;
|
||||
}
|
||||
|
@ -981,7 +982,7 @@ std::wstring ParserATNSimulator::getLookaheadName(TokenStream *input) {
|
|||
|
||||
void ParserATNSimulator::dumpDeadEndConfigs(NoViableAltException *nvae) {
|
||||
std::wcerr << L"dead end configs: ";
|
||||
for (auto c : *nvae->getDeadEndConfigs()->configLookup) {
|
||||
for (auto c : nvae->getDeadEndConfigs()->configs) {
|
||||
std::wstring trans = L"no edges";
|
||||
if (c->state->getNumberOfTransitions() > 0) {
|
||||
Transition *t = c->state->transition(0);
|
||||
|
@ -1000,14 +1001,14 @@ void ParserATNSimulator::dumpDeadEndConfigs(NoViableAltException *nvae) {
|
|||
}
|
||||
}
|
||||
|
||||
NoViableAltException *ParserATNSimulator::noViableAlt(TokenStream *input, ParserRuleContext *outerContext,
|
||||
NoViableAltException *ParserATNSimulator::noViableAlt(TokenStream *input, ParserRuleContextRef outerContext,
|
||||
std::shared_ptr<ATNConfigSet> configs, size_t startIndex) {
|
||||
return new NoViableAltException(parser, input, input->get(startIndex), input->LT(1), configs, outerContext);
|
||||
}
|
||||
|
||||
int ParserATNSimulator::getUniqueAlt(std::shared_ptr<ATNConfigSet> configs) {
|
||||
int alt = ATN::INVALID_ALT_NUMBER;
|
||||
for (auto c : *configs->configLookup) {
|
||||
for (auto c : configs->configs) {
|
||||
if (alt == ATN::INVALID_ALT_NUMBER) {
|
||||
alt = c->alt; // found first alt
|
||||
} else if (c->alt != alt) {
|
||||
|
@ -1077,7 +1078,7 @@ dfa::DFAState *ParserATNSimulator::addDFAState(dfa::DFA *dfa, dfa::DFAState *D)
|
|||
}
|
||||
}
|
||||
|
||||
void ParserATNSimulator::reportAttemptingFullContext(dfa::DFA *dfa, BitSet *conflictingAlts,
|
||||
void ParserATNSimulator::reportAttemptingFullContext(dfa::DFA *dfa, const antlrcpp::BitSet &conflictingAlts,
|
||||
std::shared_ptr<ATNConfigSet> configs, size_t startIndex, size_t stopIndex) {
|
||||
if (debug || retry_debug) {
|
||||
misc::Interval interval = misc::Interval((int)startIndex, (int)stopIndex);
|
||||
|
@ -1100,7 +1101,7 @@ void ParserATNSimulator::reportContextSensitivity(dfa::DFA *dfa, int prediction,
|
|||
}
|
||||
|
||||
void ParserATNSimulator::reportAmbiguity(dfa::DFA *dfa, dfa::DFAState *D, size_t startIndex, size_t stopIndex,
|
||||
bool exact, BitSet *ambigAlts, std::shared_ptr<ATNConfigSet> configs) {
|
||||
bool exact, const antlrcpp::BitSet &ambigAlts, std::shared_ptr<ATNConfigSet> configs) {
|
||||
if (debug || retry_debug) {
|
||||
// ParserATNPathFinder finder = new ParserATNPathFinder(parser, atn);
|
||||
// int i = 1;
|
||||
|
|
|
@ -276,7 +276,7 @@ namespace atn {
|
|||
// LAME globals to avoid parameters!!!!! I need these down deep in predTransition
|
||||
TokenStream *_input;
|
||||
int _startIndex;
|
||||
ParserRuleContext *_outerContext;
|
||||
ParserRuleContextRef _outerContext;
|
||||
|
||||
/// <summary>
|
||||
/// Testing only! </summary>
|
||||
|
@ -289,7 +289,7 @@ namespace atn {
|
|||
|
||||
virtual void reset() override;
|
||||
|
||||
virtual int adaptivePredict(TokenStream *input, int decision, ParserRuleContext *outerContext);
|
||||
virtual int adaptivePredict(TokenStream *input, int decision, ParserRuleContextRef outerContext);
|
||||
|
||||
/// <summary>
|
||||
/// Performs ATN simulation to compute a predicted alternative based
|
||||
|
@ -323,7 +323,8 @@ namespace atn {
|
|||
/// conflict + preds
|
||||
/// </summary>
|
||||
protected:
|
||||
virtual int execATN(dfa::DFA *dfa, dfa::DFAState *s0, TokenStream *input, size_t startIndex, ParserRuleContext *outerContext);
|
||||
virtual int execATN(dfa::DFA *dfa, dfa::DFAState *s0, TokenStream *input, size_t startIndex,
|
||||
ParserRuleContextRef outerContext);
|
||||
|
||||
/// <summary>
|
||||
/// Get an existing target state for an edge in the DFA. If the target state
|
||||
|
@ -353,7 +354,8 @@ namespace atn {
|
|||
virtual void predicateDFAState(dfa::DFAState *dfaState, DecisionState *decisionState);
|
||||
|
||||
// comes back with reach.uniqueAlt set to a valid alt
|
||||
virtual int execATNWithFullContext(dfa::DFA *dfa, dfa::DFAState *D, std::shared_ptr<ATNConfigSet> s0, TokenStream *input, size_t startIndex, ParserRuleContext *outerContext); // how far we got before failing over
|
||||
virtual int execATNWithFullContext(dfa::DFA *dfa, dfa::DFAState *D, std::shared_ptr<ATNConfigSet> s0,
|
||||
TokenStream *input, size_t startIndex, ParserRuleContextRef outerContext); // how far we got before failing over
|
||||
|
||||
virtual std::shared_ptr<ATNConfigSet> computeReachSet(std::shared_ptr<ATNConfigSet> closure, ssize_t t, bool fullCtx);
|
||||
|
||||
|
@ -378,14 +380,14 @@ namespace atn {
|
|||
/// the configurations from {@code configs} which are in a rule stop state </returns>
|
||||
virtual std::shared_ptr<ATNConfigSet> removeAllConfigsNotInRuleStopState(std::shared_ptr<ATNConfigSet> configs, bool lookToEndOfRule);
|
||||
|
||||
virtual std::shared_ptr<ATNConfigSet> computeStartState(ATNState *p, RuleContext *ctx, bool fullCtx);
|
||||
virtual std::shared_ptr<ATNConfigSet> computeStartState(ATNState *p, RuleContextRef ctx, bool fullCtx);
|
||||
|
||||
virtual ATNState *getReachableTarget(Transition *trans, int ttype);
|
||||
|
||||
virtual std::vector<SemanticContextRef> getPredsForAmbigAlts(antlrcpp::BitSet *ambigAlts,
|
||||
virtual std::vector<SemanticContextRef> getPredsForAmbigAlts(const antlrcpp::BitSet &ambigAlts,
|
||||
std::shared_ptr<ATNConfigSet> configs, size_t nalts);
|
||||
|
||||
virtual std::vector<dfa::DFAState::PredPrediction*> getPredicatePredictions(antlrcpp::BitSet *ambigAlts,
|
||||
virtual std::vector<dfa::DFAState::PredPrediction*> getPredicatePredictions(const antlrcpp::BitSet &ambigAlts,
|
||||
std::vector<SemanticContextRef> altToPred);
|
||||
|
||||
virtual int getAltThatFinishedDecisionEntryRule(std::shared_ptr<ATNConfigSet> configs);
|
||||
|
@ -397,7 +399,8 @@ namespace atn {
|
|||
/// then we stop at the first predicate that evaluates to true. This
|
||||
/// includes pairs with null predicates.
|
||||
/// </summary>
|
||||
virtual antlrcpp::BitSet *evalSemanticContext(std::vector<dfa::DFAState::PredPrediction*> predPredictions, ParserRuleContext *outerContext, bool complete);
|
||||
virtual antlrcpp::BitSet evalSemanticContext(std::vector<dfa::DFAState::PredPrediction*> predPredictions,
|
||||
ParserRuleContextRef outerContext, bool complete);
|
||||
|
||||
|
||||
/* TO_DO: If we are doing predicates, there is no point in pursuing
|
||||
|
@ -486,7 +489,7 @@ namespace atn {
|
|||
virtual void dumpDeadEndConfigs(NoViableAltException *nvae);
|
||||
|
||||
protected:
|
||||
virtual NoViableAltException *noViableAlt(TokenStream *input, ParserRuleContext *outerContext,
|
||||
virtual NoViableAltException *noViableAlt(TokenStream *input, ParserRuleContextRef outerContext,
|
||||
std::shared_ptr<ATNConfigSet> configs, size_t startIndex);
|
||||
|
||||
static int getUniqueAlt(std::shared_ptr<ATNConfigSet> configs);
|
||||
|
@ -528,7 +531,7 @@ namespace atn {
|
|||
/// state was not already present. </returns>
|
||||
virtual dfa::DFAState *addDFAState(dfa::DFA *dfa, dfa::DFAState *D);
|
||||
|
||||
virtual void reportAttemptingFullContext(dfa::DFA *dfa, antlrcpp::BitSet *conflictingAlts,
|
||||
virtual void reportAttemptingFullContext(dfa::DFA *dfa, const antlrcpp::BitSet &conflictingAlts,
|
||||
std::shared_ptr<ATNConfigSet> configs, size_t startIndex, size_t stopIndex);
|
||||
|
||||
virtual void reportContextSensitivity(dfa::DFA *dfa, int prediction, std::shared_ptr<ATNConfigSet> configs,
|
||||
|
@ -537,7 +540,7 @@ namespace atn {
|
|||
/// <summary>
|
||||
/// If context sensitive parsing, we know it's ambiguity not conflict </summary>
|
||||
virtual void reportAmbiguity(dfa::DFA *dfa, dfa::DFAState *D, size_t startIndex, size_t stopIndex, bool exact,
|
||||
antlrcpp::BitSet *ambigAlts, std::shared_ptr<ATNConfigSet> configs);
|
||||
const antlrcpp::BitSet &ambigAlts, std::shared_ptr<ATNConfigSet> configs);
|
||||
|
||||
public:
|
||||
void setPredictionMode(PredictionMode mode);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "MurmurHash.h"
|
||||
#include "ArrayPredictionContext.h"
|
||||
#include "RuleContext.h"
|
||||
#include "ParserRuleContext.h"
|
||||
#include "RuleTransition.h"
|
||||
#include "Arrays.h"
|
||||
#include "CPPUtils.h"
|
||||
|
@ -45,26 +46,26 @@ using namespace org::antlr::v4::runtime::atn;
|
|||
using namespace antlrcpp;
|
||||
|
||||
int PredictionContext::globalNodeCount = 0;
|
||||
const std::shared_ptr<EmptyPredictionContext> PredictionContext::EMPTY;
|
||||
const std::shared_ptr<EmptyPredictionContext> PredictionContext::EMPTY = std::make_shared<EmptyPredictionContext>();
|
||||
const int PredictionContext::EMPTY_RETURN_STATE;
|
||||
const int PredictionContext::INITIAL_HASH;
|
||||
|
||||
PredictionContext::PredictionContext(size_t cachedHashCode) : id(globalNodeCount++), cachedHashCode(cachedHashCode) {
|
||||
}
|
||||
|
||||
PredictionContextRef PredictionContext::fromRuleContext(const ATN &atn, RuleContext *outerContext) {
|
||||
if (outerContext == nullptr) {
|
||||
outerContext = (RuleContext*)RuleContext::EMPTY;
|
||||
PredictionContextRef PredictionContext::fromRuleContext(const ATN &atn, RuleContextRef outerContext) {
|
||||
if (!outerContext) {
|
||||
outerContext = std::dynamic_pointer_cast<RuleContext>(RuleContext::EMPTY);
|
||||
}
|
||||
|
||||
// if we are in RuleContext of start rule, s, then PredictionContext
|
||||
// is EMPTY. Nobody called us. (if we are empty, return empty)
|
||||
if (outerContext->parent == nullptr || outerContext == (RuleContext*)RuleContext::EMPTY) {
|
||||
if (outerContext->parent.expired() || outerContext == RuleContext::EMPTY) {
|
||||
return PredictionContext::EMPTY;
|
||||
}
|
||||
|
||||
// If we have a parent, convert it to a PredictionContext graph
|
||||
PredictionContextRef parent = PredictionContext::fromRuleContext(atn, outerContext->parent);
|
||||
PredictionContextRef parent = PredictionContext::fromRuleContext(atn, outerContext->parent.lock());
|
||||
|
||||
ATNState *state = atn.states[(size_t)outerContext->invokingState];
|
||||
RuleTransition *transition = (RuleTransition *)state->transition(0);
|
||||
|
@ -549,11 +550,12 @@ void PredictionContext::getAllContextNodes_(PredictionContextRef context,
|
|||
}
|
||||
}
|
||||
|
||||
std::wstring PredictionContext::toString() {
|
||||
return L"PredictionContext (" + std::to_wstring((size_t)this) + L")";
|
||||
std::wstring PredictionContext::toString() const {
|
||||
|
||||
return antlrcpp::toString(this);
|
||||
}
|
||||
|
||||
std::wstring PredictionContext::toString(Recognizer *recog) {
|
||||
std::wstring PredictionContext::toString(Recognizer *recog) const {
|
||||
return toString();
|
||||
}
|
||||
|
||||
|
@ -571,7 +573,8 @@ std::vector<std::wstring> PredictionContext::toStrings(Recognizer *recognizer, P
|
|||
PredictionContext *p = this;
|
||||
int stateNumber = currentState;
|
||||
|
||||
std::wstringstream ss(L"[");
|
||||
std::wstringstream ss;
|
||||
ss << L"[";
|
||||
bool outerContinue = false;
|
||||
while (!p->isEmpty() && p != stop.get()) {
|
||||
size_t index = 0;
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Recognizer.h"
|
||||
#include "EqualityComparator.h"
|
||||
#include "ATN.h"
|
||||
#include "ATNState.h"
|
||||
|
||||
|
@ -94,7 +93,7 @@ namespace atn {
|
|||
public:
|
||||
/// Convert a RuleContext tree to a PredictionContext graph.
|
||||
/// Return EMPTY if outerContext is empty.
|
||||
static PredictionContextRef fromRuleContext(const ATN &atn, RuleContext *outerContext);
|
||||
static PredictionContextRef fromRuleContext(const ATN &atn,RuleContextRef outerContext);
|
||||
|
||||
virtual size_t size() const = 0;
|
||||
virtual std::weak_ptr<PredictionContext> getParent(size_t index) const = 0;
|
||||
|
@ -256,8 +255,8 @@ namespace atn {
|
|||
static void getAllContextNodes_(PredictionContextRef context,
|
||||
std::vector<PredictionContextRef> &nodes, std::map<PredictionContextRef, PredictionContextRef> &visited);
|
||||
|
||||
std::wstring toString();
|
||||
std::wstring toString(Recognizer *recog);
|
||||
virtual std::wstring toString() const;
|
||||
virtual std::wstring toString(Recognizer *recog) const;
|
||||
|
||||
std::vector<std::wstring> toStrings(Recognizer *recognizer, int currentState);
|
||||
std::vector<std::wstring> toStrings(Recognizer *recognizer, PredictionContextRef stop, int currentState);
|
||||
|
|
|
@ -76,8 +76,8 @@ bool PredictionModeClass::hasSLLConflictTerminatingPrediction(PredictionMode* mo
|
|||
// since we'll often fail over anyway.
|
||||
if (configs->hasSemanticContext) {
|
||||
// dup configs, tossing out semantic predicates
|
||||
std::shared_ptr<ATNConfigSet> dup = std::make_shared<ATNConfigSet>(true, std::shared_ptr<ConfigLookup>());
|
||||
for (ATNConfig config : *configs->configLookup) {
|
||||
std::shared_ptr<ATNConfigSet> dup = std::make_shared<ATNConfigSet>(true);
|
||||
for (ATNConfig config : configs->configs) {
|
||||
ATNConfig* c = new ATNConfig(&config, SemanticContext::NONE);
|
||||
dup->add(c);
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ bool PredictionModeClass::hasSLLConflictTerminatingPrediction(PredictionMode* mo
|
|||
}
|
||||
|
||||
bool PredictionModeClass::hasConfigInRuleStopState(std::shared_ptr<ATNConfigSet> configs) {
|
||||
for (ATNConfig c : *configs->configLookup) {
|
||||
for (ATNConfig c : configs->configs) {
|
||||
if (dynamic_cast<RuleStopState*>(c.state) != NULL) {
|
||||
return true;
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ bool PredictionModeClass::hasConfigInRuleStopState(std::shared_ptr<ATNConfigSet>
|
|||
}
|
||||
|
||||
bool PredictionModeClass::allConfigsInRuleStopStates(std::shared_ptr<ATNConfigSet> configs) {
|
||||
for (ATNConfig config : *configs->configLookup) {
|
||||
for (ATNConfig config : configs->configs) {
|
||||
if (dynamic_cast<RuleStopState*>(config.state) == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ bool PredictionModeClass::allSubsetsEqual(const std::vector<antlrcpp::BitSet>& a
|
|||
|
||||
const antlrcpp::BitSet& first = *altsets.begin();
|
||||
for (const antlrcpp::BitSet& alts : altsets) {
|
||||
if (alts.data != first.data) {
|
||||
if (alts != first) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ int PredictionModeClass::getUniqueAlt(const std::vector<antlrcpp::BitSet>& altse
|
|||
antlrcpp::BitSet PredictionModeClass::getAlts(const std::vector<antlrcpp::BitSet>& altsets) {
|
||||
antlrcpp::BitSet all;
|
||||
for (antlrcpp::BitSet alts : altsets) {
|
||||
all.data |= alts.data;
|
||||
all |= alts;
|
||||
}
|
||||
|
||||
return all;
|
||||
|
@ -172,7 +172,7 @@ antlrcpp::BitSet PredictionModeClass::getAlts(const std::vector<antlrcpp::BitSet
|
|||
|
||||
std::vector<antlrcpp::BitSet> PredictionModeClass::getConflictingAltSubsets(std::shared_ptr<ATNConfigSet> configs) {
|
||||
std::unordered_map<ATNConfig *, antlrcpp::BitSet, AltAndContextConfigHasher, AltAndContextConfigComparer> configToAlts;
|
||||
for (auto config : *configs->configLookup) {
|
||||
for (auto config : configs->configs) {
|
||||
configToAlts[config].set((size_t)config->alt);
|
||||
}
|
||||
std::vector<antlrcpp::BitSet> values;
|
||||
|
@ -184,7 +184,7 @@ std::vector<antlrcpp::BitSet> PredictionModeClass::getConflictingAltSubsets(std:
|
|||
|
||||
std::map<ATNState*, antlrcpp::BitSet> PredictionModeClass::getStateToAltMap(std::shared_ptr<ATNConfigSet> configs) {
|
||||
std::map<ATNState*, antlrcpp::BitSet> m;
|
||||
for (ATNConfig c : *configs->configLookup) {
|
||||
for (ATNConfig c : configs->configs) {
|
||||
m[c.state].set((size_t)c.alt);
|
||||
}
|
||||
return m;
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace atn {
|
|||
/// prediction, so we passed in the outer context here in case of context
|
||||
/// dependent predicate evaluation.
|
||||
/// </summary>
|
||||
virtual bool eval(Recognizer *parser, RuleContext *outerContext) = 0;
|
||||
virtual bool eval(Recognizer *parser, RuleContextRef outerContext) = 0;
|
||||
|
||||
static SemanticContextRef And(SemanticContextRef a, SemanticContextRef b);
|
||||
|
||||
|
@ -110,8 +110,10 @@ namespace atn {
|
|||
public:
|
||||
Predicate(int ruleIndex, int predIndex, bool isCtxDependent);
|
||||
|
||||
virtual bool eval(Recognizer *parser, RuleContext *outerContext) override {
|
||||
RuleContext *localctx = isCtxDependent ? outerContext : nullptr;
|
||||
virtual bool eval(Recognizer *parser, RuleContextRef outerContext) override {
|
||||
RuleContextRef localctx;
|
||||
if (isCtxDependent)
|
||||
localctx = outerContext;
|
||||
return parser->sempred(localctx, ruleIndex, predIndex);
|
||||
}
|
||||
|
||||
|
@ -130,7 +132,7 @@ namespace atn {
|
|||
public:
|
||||
PrecedencePredicate(int precedence);
|
||||
|
||||
virtual bool eval(Recognizer *parser, RuleContext *outerContext) override {
|
||||
virtual bool eval(Recognizer *parser, RuleContextRef outerContext) override {
|
||||
return parser->precpred(outerContext, precedence);
|
||||
}
|
||||
|
||||
|
@ -149,7 +151,7 @@ namespace atn {
|
|||
virtual bool operator == (const SemanticContext &other) const override;
|
||||
virtual size_t hashCode() override;
|
||||
|
||||
virtual bool eval(Recognizer *parser, RuleContext *outerContext) override {
|
||||
virtual bool eval(Recognizer *parser, RuleContextRef outerContext) override {
|
||||
for (auto opnd : opnds) {
|
||||
if (!opnd->eval(parser, outerContext)) {
|
||||
return false;
|
||||
|
@ -171,7 +173,7 @@ namespace atn {
|
|||
virtual bool operator == (const SemanticContext &other) const override;
|
||||
virtual size_t hashCode() override;
|
||||
|
||||
virtual bool eval(Recognizer *parser, RuleContext *outerContext) override {
|
||||
virtual bool eval(Recognizer *parser, RuleContextRef outerContext) override {
|
||||
for (auto opnd : opnds) {
|
||||
if (opnd->eval(parser, outerContext)) {
|
||||
return true;
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace atn {
|
|||
virtual std::weak_ptr<PredictionContext> getParent(size_t index) const override;
|
||||
virtual int getReturnState(size_t index) const override;
|
||||
virtual bool operator == (const PredictionContext &o) const override;
|
||||
virtual std::wstring toString() const;
|
||||
virtual std::wstring toString() const override;
|
||||
};
|
||||
|
||||
} // namespace atn
|
||||
|
|
|
@ -52,17 +52,18 @@ void DFAState::PredPrediction::InitializeInstanceFields() {
|
|||
alt = 0;
|
||||
}
|
||||
|
||||
DFAState::DFAState() : DFAState(-1) {
|
||||
}
|
||||
|
||||
DFAState::DFAState(int stateNumber) : DFAState(std::make_shared<ATNConfigSet>(true, std::shared_ptr<ConfigLookup>()),
|
||||
stateNumber) {
|
||||
}
|
||||
|
||||
DFAState::DFAState(std::shared_ptr<ATNConfigSet> configs, int stateNumber) : configs(configs), stateNumber(stateNumber) {
|
||||
DFAState::DFAState() {
|
||||
InitializeInstanceFields();
|
||||
}
|
||||
|
||||
DFAState::DFAState(int state) : DFAState() {
|
||||
stateNumber = state;
|
||||
}
|
||||
|
||||
DFAState::DFAState(std::shared_ptr<ATNConfigSet> configs) : DFAState() {
|
||||
this->configs = configs;
|
||||
}
|
||||
|
||||
std::set<int> *DFAState::getAltSet() {
|
||||
std::set<int> *alts = new std::set<int>();
|
||||
if (configs != nullptr) {
|
||||
|
@ -94,10 +95,13 @@ bool DFAState::operator == (const DFAState &o) {
|
|||
|
||||
std::wstring DFAState::toString() {
|
||||
std::wstringstream ss;
|
||||
ss << stateNumber << L":" << configs->toString();
|
||||
ss << stateNumber;
|
||||
if (configs) {
|
||||
ss << L":" << configs->toString();
|
||||
}
|
||||
if (isAcceptState) {
|
||||
ss << L" => ";
|
||||
if (predicates.size() != 0) {
|
||||
if (!predicates.empty()) {
|
||||
for (size_t i = 0; i < predicates.size(); i++) {
|
||||
ss << predicates[i]->toString();
|
||||
}
|
||||
|
@ -109,6 +113,7 @@ std::wstring DFAState::toString() {
|
|||
}
|
||||
|
||||
void DFAState::InitializeInstanceFields() {
|
||||
stateNumber = -1;
|
||||
isAcceptState = false;
|
||||
prediction = 0;
|
||||
lexerRuleIndex = -1;
|
||||
|
|
|
@ -123,8 +123,8 @@ namespace dfa {
|
|||
|
||||
/// Map a predicate to a predicted alternative.
|
||||
DFAState();
|
||||
DFAState(int stateNumber);
|
||||
DFAState(std::shared_ptr<atn::ATNConfigSet> configs, int stateNumber = -1);
|
||||
DFAState(int state);
|
||||
DFAState(std::shared_ptr<atn::ATNConfigSet> configs);
|
||||
|
||||
/// <summary>
|
||||
/// Get the set of all alts mentioned by all ATN configurations in this
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* [The "BSD license"]
|
||||
* Copyright (c) 2016 Mike Lischke
|
||||
* Copyright (c) 2013 Terence Parr
|
||||
* Copyright (c) 2013 Dan McLaughlin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "EqualityComparator.h"
|
||||
|
||||
using namespace org::antlr::v4::runtime::misc;
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* [The "BSD license"]
|
||||
* Copyright (c) 2016 Mike Lischke
|
||||
* Copyright (c) 2013 Terence Parr
|
||||
* Copyright (c) 2013 Dan McLaughlin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace org {
|
||||
namespace antlr {
|
||||
namespace v4 {
|
||||
namespace runtime {
|
||||
namespace misc {
|
||||
|
||||
template<typename T>
|
||||
class EqualityComparator {
|
||||
|
||||
public:
|
||||
virtual size_t hashCode(T obj) {
|
||||
return std::hash<T>()(obj);
|
||||
}
|
||||
|
||||
virtual bool equals(const T &a, const T &b) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
virtual bool equals(T *a, T *b) {
|
||||
return *a == *b;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace atn
|
||||
} // namespace runtime
|
||||
} // namespace v4
|
||||
} // namespace antlr
|
||||
} // namespace org
|
|
@ -32,53 +32,25 @@
|
|||
|
||||
namespace antlrcpp {
|
||||
|
||||
class BitSet {
|
||||
class BitSet : public std::bitset<1024> {
|
||||
public:
|
||||
BitSet() {}
|
||||
|
||||
BitSet(const BitSet &other) {
|
||||
data = other.data;
|
||||
}
|
||||
|
||||
static const int BITSET_SIZE = 1024;
|
||||
std::bitset<BITSET_SIZE> data;
|
||||
|
||||
void assign(size_t count, const BitSet & value ) {
|
||||
|
||||
}
|
||||
|
||||
int nextSetBit(size_t pos) {
|
||||
for (size_t i = pos; i < data.size(); i++){
|
||||
if (data.test(i)) return (int)i;
|
||||
for (size_t i = pos; i < size(); i++){
|
||||
if (test(i)) {
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void set(size_t pos){
|
||||
data.set(pos);
|
||||
}
|
||||
|
||||
void set(){
|
||||
data.set();
|
||||
}
|
||||
|
||||
size_t count(){
|
||||
return data.count();
|
||||
}
|
||||
|
||||
size_t size(){
|
||||
return data.size();
|
||||
}
|
||||
|
||||
// Prints a list of every index for which the bitset contains a bit in true.
|
||||
friend std::wostream& operator << (std::wostream& os, const BitSet& obj)
|
||||
{
|
||||
|
||||
os << L"{";
|
||||
size_t total = obj.data.count();
|
||||
for (size_t i = 0; i < obj.data.size(); i++){
|
||||
if (obj.data.test(i)){
|
||||
size_t total = obj.count();
|
||||
for (size_t i = 0; i < obj.size(); i++){
|
||||
if (obj.test(i)){
|
||||
os << i;
|
||||
--total;
|
||||
if (total > 1){
|
||||
|
@ -104,12 +76,13 @@ namespace antlrcpp {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring toString(){
|
||||
std::wstringstream stream;
|
||||
stream << L"{";
|
||||
size_t total = data.count();
|
||||
for (size_t i = 0; i < data.size(); i++){
|
||||
if (data.test(i)){
|
||||
size_t total = count();
|
||||
for (size_t i = 0; i < size(); i++){
|
||||
if (test(i)){
|
||||
stream << i;
|
||||
--total;
|
||||
if (total > 1){
|
||||
|
|
|
@ -68,6 +68,15 @@ namespace antlrcpp {
|
|||
return dynamic_cast<T1*>(obj.get()) != nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::wstring toString(const T &o) {
|
||||
std::wstringstream ss;
|
||||
// typeid gives the mangled class name, but that's all what's possible
|
||||
// in a portable way.
|
||||
ss << typeid(o).name() << "@" << std::hex << (size_t)&o;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
} // namespace antlrcpp
|
||||
|
||||
namespace std {
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace org {
|
|||
class BailErrorStrategy;
|
||||
class BaseErrorListener;
|
||||
class BufferedTokenStream;
|
||||
class CharStream;
|
||||
class CharStream; typedef std::shared_ptr<CharStream> CharStreamRef;
|
||||
class CommonToken;
|
||||
class CommonTokenFactory;
|
||||
class CommonTokenStream;
|
||||
|
@ -67,7 +67,7 @@ namespace org {
|
|||
class DiagnosticErrorListener;
|
||||
class FailedPredicateException;
|
||||
class InputMismatchException;
|
||||
class IntStream;
|
||||
class IntStream; typedef std::shared_ptr<IntStream> IntStreamRef;
|
||||
class InterpreterRuleContext;
|
||||
class IRecognizer;
|
||||
class Lexer;
|
||||
|
@ -77,24 +77,21 @@ namespace org {
|
|||
class NoViableAltException;
|
||||
class Parser;
|
||||
class ParserInterpreter;
|
||||
class ParserRuleContext;
|
||||
class ParserRuleContext; typedef std::shared_ptr<ParserRuleContext> ParserRuleContextRef;
|
||||
class ProxyErrorListener;
|
||||
class RecognitionException;
|
||||
class Recognizer;
|
||||
class RuleContext;
|
||||
class Token;
|
||||
class RuleContext; typedef std::shared_ptr<RuleContext> RuleContextRef;
|
||||
class Token; typedef std::shared_ptr<Token> TokenRef;
|
||||
template<typename Symbol> class TokenFactory;
|
||||
class TokenSource;
|
||||
class TokenStream;
|
||||
class TokenStream; typedef std::shared_ptr<TokenStream> TokenStreamRef;
|
||||
class TokenStreamRewriter;
|
||||
class UnbufferedCharStream;
|
||||
class UnbufferedTokenStream;
|
||||
class WritableToken;
|
||||
class WritableToken; typedef std::shared_ptr<WritableToken> WritableTokenRef;
|
||||
|
||||
namespace misc {
|
||||
template<typename T> class AbstractEqualityComparator;
|
||||
template<typename T> class EqualityComparator;
|
||||
|
||||
class Interval;
|
||||
class IntervalSet;
|
||||
class JFileChooserConfirmOverwrite;
|
||||
|
|
|
@ -66,13 +66,13 @@ namespace tree {
|
|||
/// </summary>
|
||||
virtual T* visitChildren(RuleNode *node) override {
|
||||
T* result = defaultResult();
|
||||
int n = node->getChildCount();
|
||||
size_t n = node->getChildCount();
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (!shouldVisitNextChild(node, result)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ParseTree *c = node->getChild(i);
|
||||
std::shared_ptr<ParseTree> c = node->getChild(i);
|
||||
T childResult = c->accept(this);
|
||||
result = aggregateResult(result, childResult);
|
||||
}
|
||||
|
|
|
@ -37,5 +37,5 @@ using namespace org::antlr::v4::runtime;
|
|||
using namespace org::antlr::v4::runtime::misc;
|
||||
using namespace org::antlr::v4::runtime::tree;
|
||||
|
||||
ErrorNodeImpl::ErrorNodeImpl(Token *token) : TerminalNodeImpl(token) {
|
||||
ErrorNodeImpl::ErrorNodeImpl(TokenRef token) : TerminalNodeImpl(token) {
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace tree {
|
|||
/// </summary>
|
||||
class ErrorNodeImpl : public virtual TerminalNodeImpl, public virtual ErrorNode {
|
||||
public:
|
||||
ErrorNodeImpl(Token *token);
|
||||
ErrorNodeImpl(TokenRef token);
|
||||
|
||||
template<typename T, typename T1>
|
||||
T accept(ParseTreeVisitor<T1> *visitor) {
|
||||
|
|
|
@ -50,8 +50,8 @@ namespace tree {
|
|||
class ParseTree : public SyntaxTree {
|
||||
// the following methods narrow the return type; they are not additional methods
|
||||
public:
|
||||
virtual ParseTree *getParent() override = 0;
|
||||
virtual ParseTree *getChild(std::size_t i) override = 0;
|
||||
std::weak_ptr<ParseTree> getParent() { return std::dynamic_pointer_cast<ParseTree>(getParentReference().lock()); };
|
||||
virtual std::shared_ptr<ParseTree> getChild(size_t i) { return std::dynamic_pointer_cast<ParseTree>(getChildReference(i)); };
|
||||
|
||||
/// <summary>
|
||||
/// The <seealso cref="ParseTreeVisitor"/> needs a double dispatch method. </summary>
|
||||
|
|
|
@ -39,10 +39,14 @@ namespace tree {
|
|||
|
||||
class ParseTreeListener {
|
||||
public:
|
||||
virtual void visitTerminal(TerminalNode *node) = 0;
|
||||
virtual void visitErrorNode(ErrorNode *node) = 0;
|
||||
virtual void enterEveryRule(ParserRuleContext *ctx) = 0;
|
||||
virtual void exitEveryRule(ParserRuleContext *ctx) = 0;
|
||||
virtual void visitTerminal(std::shared_ptr<TerminalNode> node) = 0;
|
||||
virtual void visitErrorNode(std::shared_ptr<ErrorNode> node) = 0;
|
||||
virtual void enterEveryRule(std::shared_ptr<ParserRuleContext> ctx) = 0;
|
||||
virtual void exitEveryRule(std::shared_ptr<ParserRuleContext> ctx) = 0;
|
||||
|
||||
bool operator == (const ParseTreeListener &other) {
|
||||
return this == &other;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tree
|
||||
|
|
|
@ -32,22 +32,24 @@
|
|||
#include "ErrorNode.h"
|
||||
#include "ParserRuleContext.h"
|
||||
#include "ParseTreeListener.h"
|
||||
#include "CPPUtils.h"
|
||||
|
||||
#include "ParseTreeWalker.h"
|
||||
|
||||
using namespace org::antlr::v4::runtime::tree;
|
||||
using namespace antlrcpp;
|
||||
|
||||
ParseTreeWalker *const ParseTreeWalker::DEFAULT = new ParseTreeWalker();
|
||||
const std::shared_ptr<ParseTreeWalker> ParseTreeWalker::DEFAULT = std::make_shared<ParseTreeWalker>();
|
||||
|
||||
void ParseTreeWalker::walk(ParseTreeListener *listener, ParseTree *t) {
|
||||
if (dynamic_cast<ErrorNode*>(t) != nullptr) {
|
||||
listener->visitErrorNode(dynamic_cast<ErrorNode*>(t));
|
||||
void ParseTreeWalker::walk(std::shared_ptr<ParseTreeListener> listener, std::shared_ptr<ParseTree> t) {
|
||||
if (is<ErrorNode>(t)) {
|
||||
listener->visitErrorNode(std::dynamic_pointer_cast<ErrorNode>(t));
|
||||
return;
|
||||
} else if (dynamic_cast<TerminalNode*>(t) != nullptr) {
|
||||
listener->visitTerminal(static_cast<TerminalNode*>(t));
|
||||
} else if (is<TerminalNode>(t)) {
|
||||
listener->visitTerminal(std::dynamic_pointer_cast<TerminalNode>(t));
|
||||
return;
|
||||
}
|
||||
RuleNode *r = static_cast<RuleNode*>(t);
|
||||
std::shared_ptr<RuleNode> r = std::dynamic_pointer_cast<RuleNode>(t);
|
||||
enterRule(listener, r);
|
||||
std::size_t n = r->getChildCount();
|
||||
for (std::size_t i = 0; i < n; i++) {
|
||||
|
@ -56,14 +58,14 @@ void ParseTreeWalker::walk(ParseTreeListener *listener, ParseTree *t) {
|
|||
exitRule(listener, r);
|
||||
}
|
||||
|
||||
void ParseTreeWalker::enterRule(ParseTreeListener *listener, RuleNode *r) {
|
||||
ParserRuleContext *ctx = dynamic_cast<ParserRuleContext*>(r->getRuleContext());
|
||||
void ParseTreeWalker::enterRule(std::shared_ptr<ParseTreeListener> listener, std::shared_ptr<RuleNode> r) {
|
||||
ParserRuleContextRef ctx = std::dynamic_pointer_cast<ParserRuleContext>(r->getRuleContext());
|
||||
listener->enterEveryRule(ctx);
|
||||
ctx->enterRule(listener);
|
||||
}
|
||||
|
||||
void ParseTreeWalker::exitRule(ParseTreeListener *listener, RuleNode *r) {
|
||||
ParserRuleContext *ctx = dynamic_cast<ParserRuleContext*>(r->getRuleContext());
|
||||
void ParseTreeWalker::exitRule(std::shared_ptr<ParseTreeListener> listener, std::shared_ptr<RuleNode> r) {
|
||||
ParserRuleContextRef ctx = std::dynamic_pointer_cast<ParserRuleContext>(r->getRuleContext());
|
||||
ctx->exitRule(listener);
|
||||
listener->exitEveryRule(ctx);
|
||||
}
|
||||
|
|
|
@ -39,9 +39,9 @@ namespace tree {
|
|||
|
||||
class ParseTreeWalker {
|
||||
public:
|
||||
static ParseTreeWalker *const DEFAULT;
|
||||
static const std::shared_ptr<ParseTreeWalker> DEFAULT;
|
||||
|
||||
virtual void walk(ParseTreeListener *listener, ParseTree *t);
|
||||
virtual void walk(std::shared_ptr<ParseTreeListener> listener, std::shared_ptr<ParseTree> t);
|
||||
|
||||
/// <summary>
|
||||
/// The discovery of a rule node, involves sending two events: the generic
|
||||
|
@ -50,9 +50,9 @@ namespace tree {
|
|||
/// the rule specific. We to them in reverse order upon finishing the node.
|
||||
/// </summary>
|
||||
protected:
|
||||
virtual void enterRule(ParseTreeListener *listener, RuleNode *r);
|
||||
virtual void enterRule(std::shared_ptr<ParseTreeListener> listener, std::shared_ptr<RuleNode> r);
|
||||
|
||||
virtual void exitRule(ParseTreeListener *listener, RuleNode *r);
|
||||
virtual void exitRule(std::shared_ptr<ParseTreeListener> listener, std::shared_ptr<RuleNode> r);
|
||||
};
|
||||
|
||||
} // namespace tree
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace tree {
|
|||
|
||||
class RuleNode : public ParseTree {
|
||||
public:
|
||||
virtual runtime::RuleContext *getRuleContext() = 0;
|
||||
virtual runtime::RuleContextRef getRuleContext() = 0;
|
||||
};
|
||||
|
||||
} // namespace tree
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace tree {
|
|||
|
||||
class TerminalNode : public ParseTree {
|
||||
public:
|
||||
virtual Token *getSymbol() = 0;
|
||||
virtual TokenRef getSymbol() = 0;
|
||||
};
|
||||
|
||||
} // namespace tree
|
||||
|
|
|
@ -37,22 +37,14 @@
|
|||
using namespace org::antlr::v4::runtime;
|
||||
using namespace org::antlr::v4::runtime::tree;
|
||||
|
||||
TerminalNodeImpl::TerminalNodeImpl(Token *symbol) {
|
||||
TerminalNodeImpl::TerminalNodeImpl(TokenRef symbol) {
|
||||
this->symbol = symbol;
|
||||
}
|
||||
|
||||
ParseTree *TerminalNodeImpl::getChild(std::size_t i) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Token *TerminalNodeImpl::getSymbol() {
|
||||
TokenRef TerminalNodeImpl::getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
ParseTree *TerminalNodeImpl::getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
misc::Interval TerminalNodeImpl::getSourceInterval() {
|
||||
if (symbol == nullptr) {
|
||||
return misc::Interval::INVALID;
|
||||
|
@ -84,3 +76,11 @@ std::wstring TerminalNodeImpl::toString() {
|
|||
std::wstring TerminalNodeImpl::toStringTree() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
std::weak_ptr<Tree> TerminalNodeImpl::getParentReference() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
std::shared_ptr<Tree> TerminalNodeImpl::getChildReference(size_t i) {
|
||||
return std::shared_ptr<Tree>();
|
||||
}
|
||||
|
|
|
@ -41,14 +41,12 @@ namespace tree {
|
|||
|
||||
class TerminalNodeImpl : public virtual TerminalNode {
|
||||
public:
|
||||
Token *symbol;
|
||||
ParseTree *parent;
|
||||
TokenRef symbol;
|
||||
std::weak_ptr<ParseTree> parent;
|
||||
|
||||
TerminalNodeImpl(Token *symbol);
|
||||
TerminalNodeImpl(TokenRef symbol);
|
||||
|
||||
virtual ParseTree *getChild(std::size_t i) override;
|
||||
virtual Token *getSymbol() override;
|
||||
virtual ParseTree *getParent() override;
|
||||
virtual TokenRef getSymbol() override;
|
||||
virtual misc::Interval getSourceInterval() override;
|
||||
|
||||
virtual std::size_t getChildCount() override;
|
||||
|
@ -60,10 +58,12 @@ namespace tree {
|
|||
|
||||
virtual std::wstring getText() override;
|
||||
virtual std::wstring toStringTree(Parser *parser) override;
|
||||
|
||||
virtual std::wstring toString() override;
|
||||
|
||||
virtual std::wstring toStringTree() override;
|
||||
|
||||
protected:
|
||||
virtual std::weak_ptr<Tree> getParentReference() override;
|
||||
virtual std::shared_ptr<Tree> getChildReference(size_t i) override;
|
||||
};
|
||||
|
||||
} // namespace tree
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace tree {
|
|||
/// node is the root of the tree.
|
||||
/// </summary>
|
||||
public:
|
||||
virtual Tree *getParent() = 0;
|
||||
std::weak_ptr<Tree> getParent() { return getParentReference(); };
|
||||
|
||||
/// <summary>
|
||||
/// This method returns whatever object represents the data at this note. For
|
||||
|
@ -62,7 +62,7 @@ namespace tree {
|
|||
|
||||
/// <summary>
|
||||
/// If there are children, get the {@code i}th value indexed from 0. </summary>
|
||||
virtual Tree *getChild(std::size_t i) = 0;
|
||||
std::shared_ptr<Tree> getChild(size_t i) { return getChildReference(i); };
|
||||
|
||||
/// <summary>
|
||||
/// How many children are there? If there is none, then this
|
||||
|
@ -77,6 +77,10 @@ namespace tree {
|
|||
virtual std::wstring toStringTree() = 0;
|
||||
|
||||
virtual std::wstring toString() = 0;
|
||||
|
||||
protected:
|
||||
virtual std::weak_ptr<Tree> getParentReference() = 0;
|
||||
virtual std::shared_ptr<Tree> getChildReference(size_t i) = 0;
|
||||
};
|
||||
|
||||
} // namespace tree
|
||||
|
|
|
@ -42,15 +42,15 @@ using namespace org::antlr::v4::runtime::tree;
|
|||
|
||||
using namespace antlrcpp;
|
||||
|
||||
std::wstring Trees::toStringTree(Tree *t) {
|
||||
std::wstring Trees::toStringTree(std::shared_ptr<Tree> t) {
|
||||
return toStringTree(t, nullptr);
|
||||
}
|
||||
|
||||
std::wstring Trees::toStringTree(Tree *t, Parser *recog) {
|
||||
std::wstring Trees::toStringTree(std::shared_ptr<Tree> t, Parser *recog) {
|
||||
return toStringTree(t, recog->getRuleNames());
|
||||
}
|
||||
|
||||
std::wstring Trees::toStringTree(Tree *t, const std::vector<std::wstring> &ruleNames) {
|
||||
std::wstring Trees::toStringTree(std::shared_ptr<Tree> t, const std::vector<std::wstring> &ruleNames) {
|
||||
std::wstring tmp = Trees::getNodeText(t, ruleNames);
|
||||
std::wstring s = antlrcpp::escapeWhitespace(tmp, false);
|
||||
if (t->getChildCount() == 0) {
|
||||
|
@ -69,22 +69,22 @@ std::wstring Trees::toStringTree(Tree *t, const std::vector<std::wstring> &ruleN
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
std::wstring Trees::getNodeText(Tree *t, Parser *recog) {
|
||||
std::wstring Trees::getNodeText(std::shared_ptr<Tree> t, Parser *recog) {
|
||||
return getNodeText(t, recog->getRuleNames());
|
||||
}
|
||||
|
||||
std::wstring Trees::getNodeText(Tree *t, const std::vector<std::wstring> &ruleNames) {
|
||||
std::wstring Trees::getNodeText(std::shared_ptr<Tree> t, const std::vector<std::wstring> &ruleNames) {
|
||||
if (ruleNames.size() > 0) {
|
||||
if (dynamic_cast<RuleNode*>(t) != nullptr) {
|
||||
ssize_t ruleIndex = (static_cast<RuleNode*>(t))->getRuleContext()->getRuleIndex();
|
||||
if (is<RuleNode>(t)) {
|
||||
ssize_t ruleIndex = (std::static_pointer_cast<RuleNode>(t))->getRuleContext()->getRuleIndex();
|
||||
if (ruleIndex < 0)
|
||||
return L"Invalid Rule Index";
|
||||
std::wstring ruleName = ruleNames[(size_t)ruleIndex];
|
||||
return ruleName;
|
||||
} else if (dynamic_cast<ErrorNode*>(t) != nullptr) {
|
||||
} else if (is<ErrorNode>(t)) {
|
||||
return t->toString();
|
||||
} else if (dynamic_cast<TerminalNode*>(t) != nullptr) {
|
||||
Token *symbol = (static_cast<TerminalNode*>(t))->getSymbol();
|
||||
} else if (is<TerminalNode>(t)) {
|
||||
TokenRef symbol = (std::static_pointer_cast<TerminalNode>(t))->getSymbol();
|
||||
if (symbol != nullptr) {
|
||||
std::wstring s = symbol->getText();
|
||||
return s;
|
||||
|
@ -92,45 +92,44 @@ std::wstring Trees::getNodeText(Tree *t, const std::vector<std::wstring> &ruleNa
|
|||
}
|
||||
}
|
||||
// no recog for rule names
|
||||
if (is<RuleContext*>(t)) {
|
||||
return ((RuleContext*)t)->getText();
|
||||
if (is<RuleContext>(t)) {
|
||||
return std::static_pointer_cast<RuleContext>(t)->getText();
|
||||
}
|
||||
|
||||
if (is<TerminalNodeImpl*>(t)) {
|
||||
return dynamic_cast<TerminalNodeImpl*>(t)->getSymbol()->getText();
|
||||
if (is<TerminalNodeImpl>(t)) {
|
||||
return std::dynamic_pointer_cast<TerminalNodeImpl>(t)->getSymbol()->getText();
|
||||
}
|
||||
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::vector<Tree*> Trees::getChildren(Tree *t) {
|
||||
std::vector<Tree*> kids;
|
||||
std::vector<std::shared_ptr<Tree>> Trees::getChildren(std::shared_ptr<Tree> t) {
|
||||
std::vector<std::shared_ptr<Tree>> kids;
|
||||
for (size_t i = 0; i < t->getChildCount(); i++) {
|
||||
kids.push_back(t->getChild(i));
|
||||
}
|
||||
return kids;
|
||||
}
|
||||
|
||||
std::vector<Tree*> Trees::getAncestors(Tree *t) {
|
||||
std::vector<Tree*> ancestors;
|
||||
t = t->getParent();
|
||||
while (t != nullptr) {
|
||||
std::vector<std::weak_ptr<Tree>> Trees::getAncestors(std::shared_ptr<Tree> t) {
|
||||
std::vector<std::weak_ptr<Tree>> ancestors;
|
||||
while (!t->getParent().expired()) {
|
||||
t = t->getParent().lock();
|
||||
ancestors.insert(ancestors.begin(), t); // insert at start
|
||||
t = t->getParent();
|
||||
}
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void _findAllNodes(ParseTree *t, int index, bool findTokens, std::vector<T> &nodes) {
|
||||
static void _findAllNodes(std::shared_ptr<ParseTree> t, int index, bool findTokens, std::vector<T> &nodes) {
|
||||
// check this node (the root) first
|
||||
if (findTokens && is<TerminalNode*>(t)) {
|
||||
TerminalNode *tnode = (TerminalNode*)(t);
|
||||
if (findTokens && is<TerminalNode>(t)) {
|
||||
std::shared_ptr<TerminalNode> tnode = std::dynamic_pointer_cast<TerminalNode>(t);
|
||||
if (tnode->getSymbol()->getType() == index) {
|
||||
nodes.push_back(t);
|
||||
}
|
||||
} else if (!findTokens && is<ParserRuleContext*>(t)) {
|
||||
ParserRuleContext *ctx = (ParserRuleContext*)(t);
|
||||
} else if (!findTokens && is<ParserRuleContext>(t)) {
|
||||
ParserRuleContextRef ctx = std::dynamic_pointer_cast<ParserRuleContext>(t);
|
||||
if (ctx->getRuleIndex() == index) {
|
||||
nodes.push_back(t);
|
||||
}
|
||||
|
@ -141,28 +140,28 @@ static void _findAllNodes(ParseTree *t, int index, bool findTokens, std::vector<
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<ParseTree*> Trees::findAllTokenNodes(ParseTree *t, int ttype) {
|
||||
std::vector<std::shared_ptr<ParseTree>> Trees::findAllTokenNodes(std::shared_ptr<ParseTree> t, int ttype) {
|
||||
return findAllNodes(t, ttype, true);
|
||||
}
|
||||
|
||||
std::vector<ParseTree*> Trees::findAllRuleNodes(ParseTree *t, int ruleIndex) {
|
||||
std::vector<std::shared_ptr<ParseTree>> Trees::findAllRuleNodes(std::shared_ptr<ParseTree> t, int ruleIndex) {
|
||||
return findAllNodes(t, ruleIndex, false);
|
||||
}
|
||||
|
||||
std::vector<ParseTree*> Trees::findAllNodes(ParseTree *t, int index, bool findTokens) {
|
||||
std::vector<ParseTree*> nodes;
|
||||
_findAllNodes<ParseTree*>(t, index, findTokens, nodes);
|
||||
std::vector<std::shared_ptr<ParseTree>> Trees::findAllNodes(std::shared_ptr<ParseTree> t, int index, bool findTokens) {
|
||||
std::vector<std::shared_ptr<ParseTree>> nodes;
|
||||
_findAllNodes<std::shared_ptr<ParseTree>>(t, index, findTokens, nodes);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
std::vector<ParseTree*> Trees::descendants(ParseTree *t) {
|
||||
std::vector<ParseTree*> nodes;
|
||||
std::vector<std::shared_ptr<ParseTree>> Trees::descendants(std::shared_ptr<ParseTree> t) {
|
||||
std::vector<std::shared_ptr<ParseTree>> nodes;
|
||||
nodes.push_back(t);
|
||||
std::size_t n = t->getChildCount();
|
||||
for (size_t i = 0 ; i < n ; i++) {
|
||||
std::vector<ParseTree*> tmp = descendants(t->getChild(i));
|
||||
for (auto foo: tmp) {
|
||||
nodes.push_back(foo);
|
||||
auto descentants = descendants(t->getChild(i));
|
||||
for (auto entry: descentants) {
|
||||
nodes.push_back(entry);
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
|
|
|
@ -48,31 +48,31 @@ namespace tree {
|
|||
/// Print out a whole tree in LISP form. getNodeText is used on the
|
||||
/// node payloads to get the text for the nodes. Detect
|
||||
/// parse trees and extract data appropriately.
|
||||
static std::wstring toStringTree(Tree *t);
|
||||
static std::wstring toStringTree(std::shared_ptr<Tree> t);
|
||||
|
||||
/// Print out a whole tree in LISP form. getNodeText is used on the
|
||||
/// node payloads to get the text for the nodes. Detect
|
||||
/// parse trees and extract data appropriately.
|
||||
static std::wstring toStringTree(Tree *t, Parser *recog);
|
||||
static std::wstring toStringTree(std::shared_ptr<Tree> t, Parser *recog);
|
||||
|
||||
/// Print out a whole tree in LISP form. getNodeText is used on the
|
||||
/// node payloads to get the text for the nodes. Detect
|
||||
/// parse trees and extract data appropriately.
|
||||
static std::wstring toStringTree(Tree *t, const std::vector<std::wstring> &ruleNames);
|
||||
static std::wstring getNodeText(Tree *t, Parser *recog);
|
||||
static std::wstring getNodeText(Tree *t, const std::vector<std::wstring> &ruleNames);
|
||||
static std::wstring toStringTree(std::shared_ptr<Tree> t, const std::vector<std::wstring> &ruleNames);
|
||||
static std::wstring getNodeText(std::shared_ptr<Tree> t, Parser *recog);
|
||||
static std::wstring getNodeText(std::shared_ptr<Tree> t, const std::vector<std::wstring> &ruleNames);
|
||||
|
||||
/// Return ordered list of all children of this node.
|
||||
static std::vector<Tree*> getChildren(Tree *t);
|
||||
static std::vector<std::shared_ptr<Tree>> getChildren(std::shared_ptr<Tree> t);
|
||||
|
||||
/// Return a list of all ancestors of this node. The first node of
|
||||
/// list is the root and the last is the parent of this node.
|
||||
static std::vector<Tree*> getAncestors(Tree *t);
|
||||
static std::vector<ParseTree*> findAllTokenNodes(ParseTree *t, int ttype);
|
||||
static std::vector<ParseTree*> findAllRuleNodes(ParseTree *t, int ruleIndex);
|
||||
static std::vector<ParseTree*> findAllNodes(ParseTree *t, int index, bool findTokens);
|
||||
static std::vector<std::weak_ptr<Tree>> getAncestors(std::shared_ptr<Tree> t);
|
||||
static std::vector<std::shared_ptr<ParseTree>> findAllTokenNodes(std::shared_ptr<ParseTree> t, int ttype);
|
||||
static std::vector<std::shared_ptr<ParseTree>> findAllRuleNodes(std::shared_ptr<ParseTree> t, int ruleIndex);
|
||||
static std::vector<std::shared_ptr<ParseTree>> findAllNodes(std::shared_ptr<ParseTree> t, int index, bool findTokens);
|
||||
|
||||
static std::vector<ParseTree*> descendants(ParseTree *t);
|
||||
static std::vector<std::shared_ptr<ParseTree>> descendants(std::shared_ptr<ParseTree> t);
|
||||
|
||||
private:
|
||||
Trees();
|
||||
|
|
|
@ -36,20 +36,16 @@
|
|||
using namespace org::antlr::v4::runtime::tree;
|
||||
using namespace org::antlr::v4::runtime::tree::pattern;
|
||||
|
||||
ParseTreeMatch::ParseTreeMatch(ParseTree *tree, ParseTreePattern *pattern,
|
||||
const std::map<std::wstring, std::vector<ParseTree*>> &labels,
|
||||
ParseTree *mismatchedNode)
|
||||
ParseTreeMatch::ParseTreeMatch(std::shared_ptr<ParseTree> tree, const ParseTreePattern &pattern,
|
||||
const std::map<std::wstring, std::vector<std::shared_ptr<ParseTree>>> &labels,
|
||||
std::shared_ptr<ParseTree> mismatchedNode)
|
||||
: _tree(tree), _pattern(pattern), _labels(labels), _mismatchedNode(mismatchedNode) {
|
||||
if (tree == nullptr) {
|
||||
throw IllegalArgumentException("tree cannot be null");
|
||||
}
|
||||
|
||||
if (pattern == nullptr) {
|
||||
throw IllegalArgumentException("pattern cannot be null");
|
||||
}
|
||||
}
|
||||
|
||||
ParseTree* ParseTreeMatch::get(const std::wstring &label) {
|
||||
std::shared_ptr<ParseTree> ParseTreeMatch::get(const std::wstring &label) {
|
||||
auto iterator = _labels.find(label);
|
||||
if (iterator == _labels.end()) {
|
||||
return nullptr;
|
||||
|
@ -58,20 +54,20 @@ ParseTree* ParseTreeMatch::get(const std::wstring &label) {
|
|||
return iterator->second.back(); // return last if multiple
|
||||
}
|
||||
|
||||
std::vector<ParseTree*> ParseTreeMatch::getAll(const std::wstring &label) {
|
||||
std::vector<std::shared_ptr<ParseTree>> ParseTreeMatch::getAll(const std::wstring &label) {
|
||||
auto iterator = _labels.find(label);
|
||||
if (iterator == _labels.end()) {
|
||||
return std::vector<ParseTree*>();
|
||||
return std::vector<std::shared_ptr<ParseTree>>();
|
||||
}
|
||||
|
||||
return iterator->second;
|
||||
}
|
||||
|
||||
std::map<std::wstring, std::vector<ParseTree*>>& ParseTreeMatch::getLabels() {
|
||||
std::map<std::wstring, std::vector<std::shared_ptr<ParseTree>>>& ParseTreeMatch::getLabels() {
|
||||
return _labels;
|
||||
}
|
||||
|
||||
ParseTree *ParseTreeMatch::getMismatchedNode() {
|
||||
std::shared_ptr<ParseTree> ParseTreeMatch::getMismatchedNode() {
|
||||
return _mismatchedNode;
|
||||
}
|
||||
|
||||
|
@ -79,11 +75,11 @@ bool ParseTreeMatch::succeeded() {
|
|||
return _mismatchedNode == nullptr;
|
||||
}
|
||||
|
||||
ParseTreePattern *ParseTreeMatch::getPattern() {
|
||||
const ParseTreePattern& ParseTreeMatch::getPattern() {
|
||||
return _pattern;
|
||||
}
|
||||
|
||||
ParseTree *ParseTreeMatch::getTree() {
|
||||
std::shared_ptr<ParseTree> ParseTreeMatch::getTree() {
|
||||
return _tree;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,16 +42,16 @@ namespace pattern {
|
|||
class ParseTreeMatch {
|
||||
private:
|
||||
/// This is the backing field for getTree().
|
||||
ParseTree *_tree;
|
||||
std::shared_ptr<ParseTree> _tree;
|
||||
|
||||
/// This is the backing field for getPattern().
|
||||
ParseTreePattern *_pattern;
|
||||
const ParseTreePattern &_pattern;
|
||||
|
||||
/// This is the backing field for getLabels().
|
||||
std::map<std::wstring, std::vector<ParseTree*>> _labels;
|
||||
std::map<std::wstring, std::vector<std::shared_ptr<ParseTree>>> _labels;
|
||||
|
||||
/// This is the backing field for getMismatchedNode().
|
||||
ParseTree *_mismatchedNode;
|
||||
std::shared_ptr<ParseTree> _mismatchedNode;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of <seealso cref="ParseTreeMatch"/> from the specified
|
||||
|
@ -68,8 +68,9 @@ namespace pattern {
|
|||
/// <exception cref="IllegalArgumentException"> if {@code pattern} is {@code null} </exception>
|
||||
/// <exception cref="IllegalArgumentException"> if {@code labels} is {@code null} </exception>
|
||||
public:
|
||||
ParseTreeMatch(ParseTree *tree, ParseTreePattern *pattern, const std::map<std::wstring, std::vector<ParseTree*>> &labels,
|
||||
ParseTree *mismatchedNode);
|
||||
ParseTreeMatch(std::shared_ptr<ParseTree> tree, const ParseTreePattern &pattern,
|
||||
const std::map<std::wstring, std::vector<std::shared_ptr<ParseTree>>> &labels,
|
||||
std::shared_ptr<ParseTree> mismatchedNode);
|
||||
|
||||
/// <summary>
|
||||
/// Get the last node associated with a specific {@code label}.
|
||||
|
@ -86,7 +87,7 @@ namespace pattern {
|
|||
/// </param>
|
||||
/// <returns> The last <seealso cref="ParseTree"/> to match a tag with the specified
|
||||
/// label, or {@code null} if no parse tree matched a tag with the label. </returns>
|
||||
virtual ParseTree *get(const std::wstring &label);
|
||||
virtual std::shared_ptr<ParseTree> get(const std::wstring &label);
|
||||
|
||||
/// <summary>
|
||||
/// Return all nodes matching a rule or token tag with the specified label.
|
||||
|
@ -110,7 +111,7 @@ namespace pattern {
|
|||
/// <returns> A collection of all <seealso cref="ParseTree"/> nodes matching tags with
|
||||
/// the specified {@code label}. If no nodes matched the label, an empty list
|
||||
/// is returned. </returns>
|
||||
virtual std::vector<ParseTree*> getAll(const std::wstring &label);
|
||||
virtual std::vector<std::shared_ptr<ParseTree>> getAll(const std::wstring &label);
|
||||
|
||||
/// <summary>
|
||||
/// Return a mapping from label → [list of nodes].
|
||||
|
@ -121,14 +122,14 @@ namespace pattern {
|
|||
/// </summary>
|
||||
/// <returns> A mapping from labels to parse tree nodes. If the parse tree
|
||||
/// pattern did not contain any rule or token tags, this map will be empty. </returns>
|
||||
virtual std::map<std::wstring, std::vector<ParseTree*>>& getLabels();
|
||||
virtual std::map<std::wstring, std::vector<std::shared_ptr<ParseTree>>>& getLabels();
|
||||
|
||||
/// <summary>
|
||||
/// Get the node at which we first detected a mismatch.
|
||||
/// </summary>
|
||||
/// <returns> the node at which we first detected a mismatch, or {@code null}
|
||||
/// if the match was successful. </returns>
|
||||
virtual ParseTree *getMismatchedNode();
|
||||
virtual std::shared_ptr<ParseTree> getMismatchedNode();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the match operation succeeded.
|
||||
|
@ -141,13 +142,13 @@ namespace pattern {
|
|||
/// Get the tree pattern we are matching against.
|
||||
/// </summary>
|
||||
/// <returns> The tree pattern we are matching against. </returns>
|
||||
virtual ParseTreePattern *getPattern();
|
||||
virtual const ParseTreePattern& getPattern();
|
||||
|
||||
/// <summary>
|
||||
/// Get the parse tree we are trying to match to a pattern.
|
||||
/// </summary>
|
||||
/// <returns> The <seealso cref="ParseTree"/> we are trying to match to a pattern. </returns>
|
||||
virtual ParseTree *getTree();
|
||||
virtual std::shared_ptr<ParseTree> getTree();
|
||||
|
||||
/// <summary>
|
||||
/// {@inheritDoc}
|
||||
|
|
|
@ -38,15 +38,17 @@
|
|||
using namespace org::antlr::v4::runtime::tree;
|
||||
using namespace org::antlr::v4::runtime::tree::pattern;
|
||||
|
||||
ParseTreePattern::ParseTreePattern(ParseTreePatternMatcher *matcher, const std::wstring &pattern, int patternRuleIndex, ParseTree *patternTree) : patternRuleIndex(patternRuleIndex), pattern(pattern), patternTree(patternTree), matcher(matcher) {
|
||||
ParseTreePattern::ParseTreePattern(ParseTreePatternMatcher *matcher, const std::wstring &pattern, int patternRuleIndex,
|
||||
std::shared_ptr<ParseTree> patternTree)
|
||||
: patternRuleIndex(patternRuleIndex), pattern(pattern), patternTree(patternTree), matcher(matcher) {
|
||||
}
|
||||
|
||||
ParseTreeMatch *ParseTreePattern::match(ParseTree *tree) {
|
||||
return matcher->match(tree, this);
|
||||
ParseTreeMatch ParseTreePattern::match(std::shared_ptr<ParseTree> tree) {
|
||||
return matcher->match(tree, *this);
|
||||
}
|
||||
|
||||
bool ParseTreePattern::matches(ParseTree *tree) {
|
||||
return matcher->match(tree, this)->succeeded();
|
||||
bool ParseTreePattern::matches(std::shared_ptr<ParseTree> tree) {
|
||||
return matcher->match(tree, *this).succeeded();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -63,18 +65,18 @@ std::vector<ParseTreeMatch*> ParseTreePattern::findAll(ParseTree *tree, const st
|
|||
}
|
||||
*/
|
||||
|
||||
ParseTreePatternMatcher *ParseTreePattern::getMatcher() {
|
||||
ParseTreePatternMatcher *ParseTreePattern::getMatcher() const {
|
||||
return matcher;
|
||||
}
|
||||
|
||||
std::wstring ParseTreePattern::getPattern() {
|
||||
std::wstring ParseTreePattern::getPattern() const {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
int ParseTreePattern::getPatternRuleIndex() {
|
||||
int ParseTreePattern::getPatternRuleIndex() const {
|
||||
return patternRuleIndex;
|
||||
}
|
||||
|
||||
ParseTree *ParseTreePattern::getPatternTree() {
|
||||
std::shared_ptr<ParseTree> ParseTreePattern::getPatternTree() const {
|
||||
return patternTree;
|
||||
}
|
||||
|
|
|
@ -43,27 +43,7 @@ namespace pattern {
|
|||
/// <seealso cref="ParseTreePatternMatcher#compile(String, int)"/>.
|
||||
/// </summary>
|
||||
class ParseTreePattern {
|
||||
/// <summary>
|
||||
/// This is the backing field for <seealso cref="#getPatternRuleIndex()"/>.
|
||||
/// </summary>
|
||||
private:
|
||||
const int patternRuleIndex;
|
||||
|
||||
/// <summary>
|
||||
/// This is the backing field for <seealso cref="#getPattern()"/>.
|
||||
/// </summary>
|
||||
const std::wstring pattern;
|
||||
|
||||
/// <summary>
|
||||
/// This is the backing field for <seealso cref="#getPatternTree()"/>.
|
||||
/// </summary>
|
||||
ParseTree *const patternTree;
|
||||
|
||||
/// <summary>
|
||||
/// This is the backing field for <seealso cref="#getMatcher()"/>.
|
||||
/// </summary>
|
||||
ParseTreePatternMatcher *const matcher;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Construct a new instance of the <seealso cref="ParseTreePattern"/> class.
|
||||
/// </summary>
|
||||
|
@ -73,8 +53,8 @@ namespace pattern {
|
|||
/// <param name="patternRuleIndex"> The parser rule which serves as the root of the
|
||||
/// tree pattern. </param>
|
||||
/// <param name="patternTree"> The tree pattern in <seealso cref="ParseTree"/> form. </param>
|
||||
public:
|
||||
ParseTreePattern(ParseTreePatternMatcher *matcher, const std::wstring &pattern, int patternRuleIndex, ParseTree *patternTree);
|
||||
ParseTreePattern(ParseTreePatternMatcher *matcher, const std::wstring &pattern, int patternRuleIndex,
|
||||
std::shared_ptr<ParseTree> patternTree);
|
||||
|
||||
/// <summary>
|
||||
/// Match a specific parse tree against this tree pattern.
|
||||
|
@ -83,7 +63,7 @@ namespace pattern {
|
|||
/// <returns> A <seealso cref="ParseTreeMatch"/> object describing the result of the
|
||||
/// match operation. The <seealso cref="ParseTreeMatch#succeeded()"/> method can be
|
||||
/// used to determine whether or not the match was successful. </returns>
|
||||
virtual ParseTreeMatch *match(ParseTree *tree);
|
||||
virtual ParseTreeMatch match(std::shared_ptr<ParseTree> tree);
|
||||
|
||||
/// <summary>
|
||||
/// Determine whether or not a parse tree matches this tree pattern.
|
||||
|
@ -91,7 +71,7 @@ namespace pattern {
|
|||
/// <param name="tree"> The parse tree to match against this tree pattern. </param>
|
||||
/// <returns> {@code true} if {@code tree} is a match for the current tree
|
||||
/// pattern; otherwise, {@code false}. </returns>
|
||||
virtual bool matches(ParseTree *tree);
|
||||
virtual bool matches(std::shared_ptr<ParseTree> tree);
|
||||
|
||||
/// Find all nodes using XPath and then try to match those subtrees against
|
||||
/// this tree pattern.
|
||||
|
@ -111,13 +91,13 @@ namespace pattern {
|
|||
/// </summary>
|
||||
/// <returns> The <seealso cref="ParseTreePatternMatcher"/> which created this tree
|
||||
/// pattern. </returns>
|
||||
virtual ParseTreePatternMatcher *getMatcher();
|
||||
virtual ParseTreePatternMatcher *getMatcher() const;
|
||||
|
||||
/// <summary>
|
||||
/// Get the tree pattern in concrete syntax form.
|
||||
/// </summary>
|
||||
/// <returns> The tree pattern in concrete syntax form. </returns>
|
||||
virtual std::wstring getPattern();
|
||||
virtual std::wstring getPattern() const;
|
||||
|
||||
/// <summary>
|
||||
/// Get the parser rule which serves as the outermost rule for the tree
|
||||
|
@ -125,7 +105,7 @@ namespace pattern {
|
|||
/// </summary>
|
||||
/// <returns> The parser rule which serves as the outermost rule for the tree
|
||||
/// pattern. </returns>
|
||||
virtual int getPatternRuleIndex();
|
||||
virtual int getPatternRuleIndex() const;
|
||||
|
||||
/// <summary>
|
||||
/// Get the tree pattern as a <seealso cref="ParseTree"/>. The rule and token tags from
|
||||
|
@ -133,7 +113,23 @@ namespace pattern {
|
|||
/// of type <seealso cref="RuleTagToken"/> or <seealso cref="TokenTagToken"/>.
|
||||
/// </summary>
|
||||
/// <returns> The tree pattern as a <seealso cref="ParseTree"/>. </returns>
|
||||
virtual ParseTree *getPatternTree();
|
||||
virtual std::shared_ptr<ParseTree> getPatternTree() const;
|
||||
|
||||
private:
|
||||
const int patternRuleIndex;
|
||||
|
||||
/// <summary>
|
||||
/// This is the backing field for <seealso cref="#getPattern()"/>.
|
||||
/// </summary>
|
||||
const std::wstring pattern;
|
||||
|
||||
/// This is the backing field for <seealso cref="#getPatternTree()"/>.
|
||||
std::shared_ptr<ParseTree> patternTree;
|
||||
|
||||
/// <summary>
|
||||
/// This is the backing field for <seealso cref="#getMatcher()"/>.
|
||||
/// </summary>
|
||||
ParseTreePatternMatcher *const matcher;
|
||||
};
|
||||
|
||||
} // namespace pattern
|
||||
|
|
|
@ -47,85 +47,85 @@
|
|||
#include "Arrays.h"
|
||||
#include "Exceptions.h"
|
||||
#include "Strings.h"
|
||||
#include "CPPUtils.h"
|
||||
|
||||
#include "ParseTreePatternMatcher.h"
|
||||
|
||||
using namespace org::antlr::v4::runtime;
|
||||
using namespace org::antlr::v4::runtime::tree;
|
||||
using namespace org::antlr::v4::runtime::tree::pattern;
|
||||
using namespace antlrcpp;
|
||||
|
||||
ParseTreePatternMatcher::CannotInvokeStartRule::CannotInvokeStartRule(std::exception e) {
|
||||
}
|
||||
|
||||
ParseTreePatternMatcher::ParseTreePatternMatcher(Lexer *lexer, Parser *parser) : lexer(lexer), parser(parser) {
|
||||
ParseTreePatternMatcher::ParseTreePatternMatcher(Lexer *lexer, Parser *parser) : _lexer(lexer), _parser(parser) {
|
||||
InitializeInstanceFields();
|
||||
}
|
||||
|
||||
void ParseTreePatternMatcher::setDelimiters(const std::wstring &start, const std::wstring &stop, const std::wstring &escapeLeft) {
|
||||
if (start == L"" || start.length() == 0) {
|
||||
if (start.empty()) {
|
||||
throw IllegalArgumentException("start cannot be null or empty");
|
||||
}
|
||||
|
||||
if (stop == L"" || stop.length() == 0) {
|
||||
if (stop.empty()) {
|
||||
throw IllegalArgumentException("stop cannot be null or empty");
|
||||
}
|
||||
|
||||
this->start = start;
|
||||
this->stop = stop;
|
||||
this->escape = escapeLeft;
|
||||
_start = start;
|
||||
_stop = stop;
|
||||
_escape = escapeLeft;
|
||||
}
|
||||
|
||||
bool ParseTreePatternMatcher::matches(ParseTree *tree, const std::wstring &pattern, int patternRuleIndex) {
|
||||
ParseTreePattern *p = compile(pattern, patternRuleIndex);
|
||||
bool ParseTreePatternMatcher::matches(std::shared_ptr<ParseTree> tree, const std::wstring &pattern, int patternRuleIndex) {
|
||||
ParseTreePattern p = compile(pattern, patternRuleIndex);
|
||||
return matches(tree, p);
|
||||
}
|
||||
|
||||
bool ParseTreePatternMatcher::matches(ParseTree *tree, ParseTreePattern *pattern) {
|
||||
std::map<std::wstring, std::vector<ParseTree*>> labels;
|
||||
ParseTree *mismatchedNode = matchImpl(tree, pattern->getPatternTree(), labels);
|
||||
bool ParseTreePatternMatcher::matches(std::shared_ptr<ParseTree> tree, const ParseTreePattern &pattern) {
|
||||
std::map<std::wstring, std::vector<std::shared_ptr<ParseTree>>> labels;
|
||||
std::shared_ptr<ParseTree> mismatchedNode = matchImpl(tree, pattern.getPatternTree(), labels);
|
||||
return mismatchedNode == nullptr;
|
||||
}
|
||||
|
||||
ParseTreeMatch *ParseTreePatternMatcher::match(ParseTree *tree, const std::wstring &pattern, int patternRuleIndex) {
|
||||
ParseTreePattern *p = compile(pattern, patternRuleIndex);
|
||||
ParseTreeMatch ParseTreePatternMatcher::match(std::shared_ptr<ParseTree> tree, const std::wstring &pattern, int patternRuleIndex) {
|
||||
ParseTreePattern p = compile(pattern, patternRuleIndex);
|
||||
return match(tree, p);
|
||||
}
|
||||
|
||||
ParseTreeMatch *ParseTreePatternMatcher::match(ParseTree *tree, ParseTreePattern *pattern) {
|
||||
std::map<std::wstring, std::vector<ParseTree*>> labels;
|
||||
ParseTree *mismatchedNode = matchImpl(tree, pattern->getPatternTree(), labels);
|
||||
return new ParseTreeMatch(tree, pattern, labels, mismatchedNode);
|
||||
ParseTreeMatch ParseTreePatternMatcher::match(std::shared_ptr<ParseTree> tree, const ParseTreePattern &pattern) {
|
||||
std::map<std::wstring, std::vector<std::shared_ptr<ParseTree>>> labels;
|
||||
std::shared_ptr<tree::ParseTree> mismatchedNode = matchImpl(tree, pattern.getPatternTree(), labels);
|
||||
return ParseTreeMatch(tree, pattern, labels, mismatchedNode);
|
||||
}
|
||||
|
||||
ParseTreePattern *ParseTreePatternMatcher::compile(const std::wstring &pattern, int patternRuleIndex) {
|
||||
std::vector<Token*> tokenList = tokenize(pattern);
|
||||
ListTokenSource *tokenSrc = new ListTokenSource(tokenList);
|
||||
ParseTreePattern ParseTreePatternMatcher::compile(const std::wstring &pattern, int patternRuleIndex) {
|
||||
std::vector<TokenRef> tokenList = tokenize(pattern);
|
||||
ListTokenSource *tokenSrc = new ListTokenSource(tokenList); // XXX: mem leak
|
||||
CommonTokenStream *tokens = new CommonTokenStream(tokenSrc);
|
||||
|
||||
ParserInterpreter *parserInterp = new ParserInterpreter(
|
||||
parser->getGrammarFileName(), parser->getTokenNames(),
|
||||
parser->getRuleNames(), parser->getATNWithBypassAlts(), tokens);
|
||||
ParserInterpreter parserInterp(_parser->getGrammarFileName(), _parser->getTokenNames(),
|
||||
_parser->getRuleNames(), _parser->getATNWithBypassAlts(), tokens);
|
||||
|
||||
ParseTree *tree = nullptr;
|
||||
try {
|
||||
tree = parserInterp->parse(patternRuleIndex);
|
||||
// System.out.println("pattern tree = "+tree.toStringTree(parserInterp));
|
||||
ParserRuleContextRef context = parserInterp.parse(patternRuleIndex);
|
||||
return ParseTreePattern(this, pattern, patternRuleIndex, context);
|
||||
} catch (std::exception &e) {
|
||||
throw CannotInvokeStartRule(e);
|
||||
std::throw_with_nested("Cannot invoke start rule");
|
||||
}
|
||||
|
||||
return new ParseTreePattern(this, pattern, patternRuleIndex, tree);
|
||||
}
|
||||
|
||||
Lexer *ParseTreePatternMatcher::getLexer() {
|
||||
return lexer;
|
||||
Lexer* ParseTreePatternMatcher::getLexer() {
|
||||
return _lexer;
|
||||
}
|
||||
|
||||
Parser *ParseTreePatternMatcher::getParser() {
|
||||
return parser;
|
||||
Parser* ParseTreePatternMatcher::getParser() {
|
||||
return _parser;
|
||||
}
|
||||
|
||||
tree::ParseTree *ParseTreePatternMatcher::matchImpl(ParseTree *tree, ParseTree *patternTree, std::map<std::wstring, std::vector<ParseTree*>> &labels) {
|
||||
std::shared_ptr<ParseTree> ParseTreePatternMatcher::matchImpl(std::shared_ptr<ParseTree> tree,
|
||||
std::shared_ptr<ParseTree> patternTree, std::map<std::wstring, std::vector<std::shared_ptr<ParseTree>>> &labels) {
|
||||
if (tree == nullptr) {
|
||||
throw IllegalArgumentException("tree cannot be null");
|
||||
}
|
||||
|
@ -135,14 +135,16 @@ tree::ParseTree *ParseTreePatternMatcher::matchImpl(ParseTree *tree, ParseTree *
|
|||
}
|
||||
|
||||
// x and <ID>, x and y, or x and x; or could be mismatched types
|
||||
if (dynamic_cast<TerminalNode*>(tree) != nullptr && dynamic_cast<TerminalNode*>(patternTree) != nullptr) {
|
||||
TerminalNode *t1 = static_cast<TerminalNode*>(tree);
|
||||
TerminalNode *t2 = static_cast<TerminalNode*>(patternTree);
|
||||
ParseTree *mismatchedNode = nullptr;
|
||||
if (is<TerminalNode>(tree) && is<TerminalNode>(patternTree)) {
|
||||
std::shared_ptr<TerminalNode> t1 = std::static_pointer_cast<TerminalNode>(tree);
|
||||
std::shared_ptr<TerminalNode> t2 = std::static_pointer_cast<TerminalNode>(patternTree);
|
||||
|
||||
std::shared_ptr<ParseTree> mismatchedNode;
|
||||
// both are tokens and they have same type
|
||||
if (t1->getSymbol()->getType() == t2->getSymbol()->getType()) {
|
||||
if (dynamic_cast<TokenTagToken*>(t2->getSymbol()) != nullptr) { // x and <ID>
|
||||
TokenTagToken *tokenTagToken = static_cast<TokenTagToken*>(t2->getSymbol());
|
||||
if (is<TokenTagToken>(t2->getSymbol())) { // x and <ID>
|
||||
std::shared_ptr<TokenTagToken> tokenTagToken = std::dynamic_pointer_cast<TokenTagToken>(t2->getSymbol());
|
||||
|
||||
// track label->list-of-nodes for both token name and label (if any)
|
||||
labels[tokenTagToken->getTokenName()].push_back(tree);
|
||||
if (tokenTagToken->getLabel() != L"") {
|
||||
|
@ -165,12 +167,13 @@ tree::ParseTree *ParseTreePatternMatcher::matchImpl(ParseTree *tree, ParseTree *
|
|||
return mismatchedNode;
|
||||
}
|
||||
|
||||
if (dynamic_cast<ParserRuleContext*>(tree) != nullptr && dynamic_cast<ParserRuleContext*>(patternTree) != nullptr) {
|
||||
ParserRuleContext *r1 = static_cast<ParserRuleContext*>(tree);
|
||||
ParserRuleContext *r2 = static_cast<ParserRuleContext*>(patternTree);
|
||||
ParseTree *mismatchedNode = nullptr;
|
||||
if (is<ParserRuleContext>(tree) && is<ParserRuleContext>(patternTree)) {
|
||||
ParserRuleContextRef r1 = std::dynamic_pointer_cast<ParserRuleContext>(tree);
|
||||
ParserRuleContextRef r2 = std::dynamic_pointer_cast<ParserRuleContext>(patternTree);
|
||||
std::shared_ptr<ParseTree> mismatchedNode;
|
||||
|
||||
// (expr ...) and <expr>
|
||||
RuleTagToken *ruleTagToken = getRuleTagToken(r2);
|
||||
std::shared_ptr<RuleTagToken> ruleTagToken = getRuleTagToken(r2);
|
||||
if (ruleTagToken != nullptr) {
|
||||
//ParseTreeMatch *m = nullptr; // unused?
|
||||
if (r1->RuleContext::getRuleContext()->getRuleIndex() == r2->RuleContext::getRuleContext()->getRuleIndex()) {
|
||||
|
@ -180,7 +183,7 @@ tree::ParseTree *ParseTreePatternMatcher::matchImpl(ParseTree *tree, ParseTree *
|
|||
labels[ruleTagToken->getLabel()].push_back(tree);
|
||||
}
|
||||
} else {
|
||||
if (mismatchedNode == nullptr) {
|
||||
if (!mismatchedNode) {
|
||||
mismatchedNode = r1;
|
||||
}
|
||||
}
|
||||
|
@ -198,9 +201,9 @@ tree::ParseTree *ParseTreePatternMatcher::matchImpl(ParseTree *tree, ParseTree *
|
|||
}
|
||||
|
||||
std::size_t n = r1->getChildCount();
|
||||
for (std::size_t i = 0; i < n; i++) {
|
||||
ParseTree *childMatch = matchImpl(r1->getChild(i), patternTree->getChild(i), labels);
|
||||
if (childMatch != nullptr) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
std::shared_ptr<ParseTree> childMatch = matchImpl(r1->getChild(i), patternTree->getChild(i), labels);
|
||||
if (childMatch) {
|
||||
return childMatch;
|
||||
}
|
||||
}
|
||||
|
@ -212,56 +215,56 @@ tree::ParseTree *ParseTreePatternMatcher::matchImpl(ParseTree *tree, ParseTree *
|
|||
return tree;
|
||||
}
|
||||
|
||||
RuleTagToken *ParseTreePatternMatcher::getRuleTagToken(ParseTree *t) {
|
||||
if (dynamic_cast<RuleNode*>(t) != nullptr) {
|
||||
RuleNode *r = static_cast<RuleNode*>(t);
|
||||
if (r->getChildCount() == 1 && dynamic_cast<TerminalNode*>(r->getChild(0)) != nullptr) {
|
||||
TerminalNode *c = static_cast<TerminalNode*>(r->getChild(0));
|
||||
if (dynamic_cast<RuleTagToken*>(c->getSymbol()) != nullptr) {
|
||||
// System.out.println("rule tag subtree "+t.toStringTree(parser));
|
||||
return static_cast<RuleTagToken*>(c->getSymbol());
|
||||
std::shared_ptr<RuleTagToken> ParseTreePatternMatcher::getRuleTagToken(std::shared_ptr<ParseTree> t) {
|
||||
if (is<RuleNode>(t)) {
|
||||
std::shared_ptr<RuleNode> r = std::dynamic_pointer_cast<RuleNode>(t);
|
||||
if (r->getChildCount() == 1 && is<TerminalNode>(r->getChild(0))) {
|
||||
std::shared_ptr<TerminalNode> c = std::dynamic_pointer_cast<TerminalNode>(r->getChild(0));
|
||||
if (is<RuleTagToken>(c->getSymbol())) {
|
||||
return std::dynamic_pointer_cast<RuleTagToken>(c->getSymbol());
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Token*> ParseTreePatternMatcher::tokenize(const std::wstring &pattern) {
|
||||
std::vector<TokenRef> ParseTreePatternMatcher::tokenize(const std::wstring &pattern) {
|
||||
// split pattern into chunks: sea (raw input) and islands (<ID>, <expr>)
|
||||
std::vector<Chunk*> chunks = split(pattern);
|
||||
|
||||
// create token stream from text and tags
|
||||
std::vector<Token*> tokens;
|
||||
std::vector<TokenRef> tokens;
|
||||
for (auto chunk : chunks) {
|
||||
if (dynamic_cast<TagChunk*>(chunk) != nullptr) {
|
||||
TagChunk *tagChunk = static_cast<TagChunk*>(chunk);
|
||||
// add special rule token or conjure up new token from name
|
||||
if (isupper(tagChunk->getTag()[0])) {
|
||||
int ttype = parser->getTokenType(tagChunk->getTag());
|
||||
int ttype = _parser->getTokenType(tagChunk->getTag());
|
||||
if (ttype == Token::INVALID_TYPE) {
|
||||
throw IllegalArgumentException(std::string("Unknown token ") + antlrcpp::ws2s(tagChunk->getTag()) + std::string(" in pattern: ") + antlrcpp::ws2s(pattern));
|
||||
}
|
||||
TokenTagToken *t = new TokenTagToken(tagChunk->getTag(), ttype, tagChunk->getLabel());
|
||||
std::shared_ptr<TokenTagToken> t = std::make_shared<TokenTagToken>(tagChunk->getTag(), ttype, tagChunk->getLabel());
|
||||
tokens.push_back(t);
|
||||
} else if (islower(tagChunk->getTag()[0])) {
|
||||
int ruleIndex = parser->getRuleIndex(tagChunk->getTag());
|
||||
int ruleIndex = _parser->getRuleIndex(tagChunk->getTag());
|
||||
if (ruleIndex == -1) {
|
||||
throw IllegalArgumentException(std::string("Unknown rule ") + antlrcpp::ws2s(tagChunk->getTag()) + " in pattern: " + antlrcpp::ws2s(pattern));
|
||||
}
|
||||
int ruleImaginaryTokenType = parser->getATNWithBypassAlts().ruleToTokenType[(size_t)ruleIndex];
|
||||
tokens.push_back(new RuleTagToken(tagChunk->getTag(), ruleImaginaryTokenType, tagChunk->getLabel()));
|
||||
int ruleImaginaryTokenType = _parser->getATNWithBypassAlts().ruleToTokenType[(size_t)ruleIndex];
|
||||
tokens.push_back(std::make_shared<RuleTagToken>(tagChunk->getTag(), ruleImaginaryTokenType, tagChunk->getLabel()));
|
||||
} else {
|
||||
throw IllegalArgumentException(std::string("invalid tag: ") + antlrcpp::ws2s(tagChunk->getTag()) + " in pattern: " + antlrcpp::ws2s(pattern));
|
||||
}
|
||||
} else {
|
||||
TextChunk *textChunk = static_cast<TextChunk*>(chunk);
|
||||
ANTLRInputStream input(textChunk->getText());
|
||||
lexer->setInputStream(&input);
|
||||
Token *t = lexer->nextToken();
|
||||
_lexer->setInputStream(&input);
|
||||
TokenRef t = _lexer->nextToken();
|
||||
while (t->getType() != EOF) {
|
||||
tokens.push_back(t);
|
||||
t = lexer->nextToken();
|
||||
t = _lexer->nextToken();
|
||||
}
|
||||
_lexer->setInputStream(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,16 +280,16 @@ std::vector<Chunk*> ParseTreePatternMatcher::split(const std::wstring &pattern)
|
|||
std::vector<size_t> starts;
|
||||
std::vector<size_t> stops;
|
||||
while (p < n) {
|
||||
if (p == pattern.find(escape + start,p)) {
|
||||
p += escape.length() + start.length();
|
||||
} else if (p == pattern.find(escape + stop,p)) {
|
||||
p += escape.length() + stop.length();
|
||||
} else if (p == pattern.find(start,p)) {
|
||||
if (p == pattern.find(_escape + _start,p)) {
|
||||
p += _escape.length() + _start.length();
|
||||
} else if (p == pattern.find(_escape + _stop,p)) {
|
||||
p += _escape.length() + _stop.length();
|
||||
} else if (p == pattern.find(_start,p)) {
|
||||
starts.push_back(p);
|
||||
p += start.length();
|
||||
} else if (p == pattern.find(stop,p)) {
|
||||
p += _start.length();
|
||||
} else if (p == pattern.find(_stop,p)) {
|
||||
stops.push_back(p);
|
||||
p += stop.length();
|
||||
p += _stop.length();
|
||||
} else {
|
||||
p++;
|
||||
}
|
||||
|
@ -319,7 +322,7 @@ std::vector<Chunk*> ParseTreePatternMatcher::split(const std::wstring &pattern)
|
|||
}
|
||||
for (size_t i = 0; i < ntags; i++) {
|
||||
// copy inside of <tag>
|
||||
std::wstring tag = pattern.substr(starts[i] + start.length(), stops[i] - (starts[i] + start.length()));
|
||||
std::wstring tag = pattern.substr(starts[i] + _start.length(), stops[i] - (starts[i] + _start.length()));
|
||||
std::wstring ruleOrToken = tag;
|
||||
std::wstring label = L"";
|
||||
size_t colon = tag.find(L':');
|
||||
|
@ -330,12 +333,12 @@ std::vector<Chunk*> ParseTreePatternMatcher::split(const std::wstring &pattern)
|
|||
chunks.push_back(new TagChunk(label, ruleOrToken));
|
||||
if (i + 1 < ntags) {
|
||||
// copy from end of <tag> to start of next
|
||||
std::wstring text = pattern.substr(stops[i] + stop.length(), starts[i + 1] - (stops[i] + stop.length()));
|
||||
std::wstring text = pattern.substr(stops[i] + _stop.length(), starts[i + 1] - (stops[i] + _stop.length()));
|
||||
chunks.push_back(new TextChunk(text));
|
||||
}
|
||||
}
|
||||
if (ntags > 0) {
|
||||
size_t afterLastTag = stops[ntags - 1] + stop.length();
|
||||
size_t afterLastTag = stops[ntags - 1] + _stop.length();
|
||||
if (afterLastTag < n) { // copy text from end of last tag to end
|
||||
std::wstring text = pattern.substr(afterLastTag, n - afterLastTag);
|
||||
chunks.push_back(new TextChunk(text));
|
||||
|
@ -359,7 +362,7 @@ std::vector<Chunk*> ParseTreePatternMatcher::split(const std::wstring &pattern)
|
|||
}
|
||||
|
||||
void ParseTreePatternMatcher::InitializeInstanceFields() {
|
||||
start = L"<";
|
||||
stop = L">";
|
||||
escape = L"\\";
|
||||
_start = L"<";
|
||||
_stop = L">";
|
||||
_escape = L"\\";
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue