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:
Mike Lischke 2016-04-13 19:05:56 +02:00
parent 6f344b376b
commit eb0241f767
104 changed files with 1421 additions and 1641 deletions

View File

@ -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;
}

View File

@ -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 */,

View File

@ -41,6 +41,7 @@ fragment LETTER : [a-zA-Z\u0080-\u00FF_] ;
LessThan: '<' -> pushMode(Mode1);
GreaterThan: '>' -> popMode;
Equal: '=';
And: 'and';
Colon: ':';
Semicolon: ';';

View File

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

View File

@ -1,5 +1,5 @@
grammar Test;
main: ID;
main: ID ID;
ID: [a..z]+;
ID: [a-z]+;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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>

View File

@ -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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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:

View File

@ -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);
}

View File

@ -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

View File

@ -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++;
}

View File

@ -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:

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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()) {
}

View File

@ -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) {
}

View File

@ -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;
};

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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);
}
}

View File

@ -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&lt;String&gt; 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();
};

View File

@ -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);

View File

@ -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);

View File

@ -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'}';
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

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

View File

@ -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() {

View File

@ -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);

View File

@ -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);
}

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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;
}

View File

@ -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:

View File

@ -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)) {

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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() {

View File

@ -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();

View File

@ -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", ";

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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>());
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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){

View File

@ -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 {

View File

@ -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;

View File

@ -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);
}

View File

@ -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) {
}

View File

@ -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) {

View File

@ -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>

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -41,7 +41,7 @@ namespace tree {
class RuleNode : public ParseTree {
public:
virtual runtime::RuleContext *getRuleContext() = 0;
virtual runtime::RuleContextRef getRuleContext() = 0;
};
} // namespace tree

View File

@ -41,7 +41,7 @@ namespace tree {
class TerminalNode : public ParseTree {
public:
virtual Token *getSymbol() = 0;
virtual TokenRef getSymbol() = 0;
};
} // namespace tree

View File

@ -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>();
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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;
}

View File

@ -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 &rarr; [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}

View File

@ -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;
}

View File

@ -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

View File

@ -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