From 8e4cbbfd8711b5c36be61da1fc996d45d2901383 Mon Sep 17 00:00:00 2001 From: zhm <1978583449@qq.com> Date: Tue, 12 May 2026 01:06:45 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4src/include=E4=B8=AD=E7=9A=84?= =?UTF-8?q?ANTLR=E9=87=8D=E5=A4=8D=E5=A4=B4=E6=96=87=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E4=BD=BF=E7=94=A8/extlibs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/ANTLRErrorListener.cpp | 10 - src/include/ANTLRErrorListener.h | 167 -- src/include/ANTLRErrorStrategy.cpp | 10 - src/include/ANTLRErrorStrategy.h | 121 -- src/include/ANTLRFileStream.cpp | 23 - src/include/ANTLRFileStream.h | 30 - src/include/ANTLRInputStream.cpp | 180 --- src/include/ANTLRInputStream.h | 79 - src/include/antlr4-common.h | 101 -- src/include/antlr4-runtime.h | 168 -- src/include/atn/ATN.cpp | 159 -- src/include/atn/ATN.h | 133 -- src/include/atn/ATNConfig.cpp | 106 -- src/include/atn/ATNConfig.h | 157 -- src/include/atn/ATNConfigSet.cpp | 233 --- src/include/atn/ATNConfigSet.h | 157 -- src/include/atn/ATNDeserializationOptions.cpp | 39 - src/include/atn/ATNDeserializationOptions.h | 48 - src/include/atn/ATNDeserializer.cpp | 628 -------- src/include/atn/ATNDeserializer.h | 32 - src/include/atn/ATNSimulator.cpp | 33 - src/include/atn/ATNSimulator.h | 71 - src/include/atn/ATNState.cpp | 56 - src/include/atn/ATNState.h | 139 -- src/include/atn/ATNStateType.cpp | 33 - src/include/atn/ATNStateType.h | 36 - src/include/atn/ATNType.h | 20 - src/include/atn/ActionTransition.cpp | 29 - src/include/atn/ActionTransition.h | 35 - src/include/atn/AmbiguityInfo.cpp | 16 - src/include/atn/AmbiguityInfo.h | 68 - src/include/atn/ArrayPredictionContext.cpp | 129 -- src/include/atn/ArrayPredictionContext.h | 51 - src/include/atn/AtomTransition.cpp | 27 - src/include/atn/AtomTransition.h | 33 - src/include/atn/BasicBlockStartState.h | 24 - src/include/atn/BasicState.h | 23 - src/include/atn/BlockEndState.h | 26 - src/include/atn/BlockStartState.h | 30 - src/include/atn/ContextSensitivityInfo.cpp | 14 - src/include/atn/ContextSensitivityInfo.h | 47 - src/include/atn/DecisionEventInfo.cpp | 14 - src/include/atn/DecisionEventInfo.h | 70 - src/include/atn/DecisionInfo.cpp | 25 - src/include/atn/DecisionInfo.h | 227 --- src/include/atn/DecisionState.cpp | 12 - src/include/atn/DecisionState.h | 34 - src/include/atn/EpsilonTransition.cpp | 31 - src/include/atn/EpsilonTransition.h | 42 - src/include/atn/ErrorInfo.cpp | 15 - src/include/atn/ErrorInfo.h | 43 - src/include/atn/HashUtils.h | 18 - src/include/atn/LL1Analyzer.cpp | 189 --- src/include/atn/LL1Analyzer.h | 76 - src/include/atn/LexerATNConfig.cpp | 67 - src/include/atn/LexerATNConfig.h | 44 - src/include/atn/LexerATNSimulator.cpp | 621 -------- src/include/atn/LexerATNSimulator.h | 199 --- src/include/atn/LexerAction.cpp | 15 - src/include/atn/LexerAction.h | 100 -- src/include/atn/LexerActionExecutor.cpp | 108 -- src/include/atn/LexerActionExecutor.h | 128 -- src/include/atn/LexerActionType.h | 57 - src/include/atn/LexerChannelAction.cpp | 43 - src/include/atn/LexerChannelAction.h | 59 - src/include/atn/LexerCustomAction.cpp | 45 - src/include/atn/LexerCustomAction.h | 75 - src/include/atn/LexerIndexedCustomAction.cpp | 50 - src/include/atn/LexerIndexedCustomAction.h | 76 - src/include/atn/LexerModeAction.cpp | 43 - src/include/atn/LexerModeAction.h | 57 - src/include/atn/LexerMoreAction.cpp | 36 - src/include/atn/LexerMoreAction.h | 53 - src/include/atn/LexerPopModeAction.cpp | 36 - src/include/atn/LexerPopModeAction.h | 53 - src/include/atn/LexerPushModeAction.cpp | 43 - src/include/atn/LexerPushModeAction.h | 57 - src/include/atn/LexerSkipAction.cpp | 36 - src/include/atn/LexerSkipAction.h | 51 - src/include/atn/LexerTypeAction.cpp | 43 - src/include/atn/LexerTypeAction.h | 51 - src/include/atn/LookaheadEventInfo.cpp | 16 - src/include/atn/LookaheadEventInfo.h | 42 - src/include/atn/LoopEndState.h | 26 - src/include/atn/NotSetTransition.cpp | 22 - src/include/atn/NotSetTransition.h | 27 - src/include/atn/OrderedATNConfigSet.cpp | 16 - src/include/atn/OrderedATNConfigSet.h | 25 - src/include/atn/ParseInfo.cpp | 102 -- src/include/atn/ParseInfo.h | 102 -- src/include/atn/ParserATNSimulator.cpp | 1413 ----------------- src/include/atn/ParserATNSimulator.h | 911 ----------- src/include/atn/ParserATNSimulatorOptions.h | 50 - src/include/atn/PlusBlockStartState.h | 29 - src/include/atn/PlusLoopbackState.h | 25 - .../atn/PrecedencePredicateTransition.cpp | 23 - .../atn/PrecedencePredicateTransition.h | 35 - src/include/atn/PredicateEvalInfo.cpp | 17 - src/include/atn/PredicateEvalInfo.h | 62 - src/include/atn/PredicateTransition.cpp | 24 - src/include/atn/PredicateTransition.h | 50 - src/include/atn/PredictionContext.cpp | 601 ------- src/include/atn/PredictionContext.h | 225 --- src/include/atn/PredictionContextCache.cpp | 56 - src/include/atn/PredictionContextCache.h | 63 - .../atn/PredictionContextMergeCache.cpp | 167 -- src/include/atn/PredictionContextMergeCache.h | 101 -- .../atn/PredictionContextMergeCacheOptions.h | 71 - src/include/atn/PredictionContextType.h | 21 - src/include/atn/PredictionMode.cpp | 202 --- src/include/atn/PredictionMode.h | 436 ----- src/include/atn/ProfilingATNSimulator.cpp | 179 --- src/include/atn/ProfilingATNSimulator.h | 60 - src/include/atn/RangeTransition.cpp | 26 - src/include/atn/RangeTransition.h | 31 - src/include/atn/RuleStartState.h | 26 - src/include/atn/RuleStopState.h | 27 - src/include/atn/RuleTransition.cpp | 33 - src/include/atn/RuleTransition.h | 42 - src/include/atn/SemanticContext.cpp | 418 ----- src/include/atn/SemanticContext.h | 237 --- src/include/atn/SemanticContextType.h | 23 - src/include/atn/SerializedATNView.h | 101 -- src/include/atn/SetTransition.cpp | 28 - src/include/atn/SetTransition.h | 38 - .../atn/SingletonPredictionContext.cpp | 79 - src/include/atn/SingletonPredictionContext.h | 43 - src/include/atn/StarBlockStartState.h | 24 - src/include/atn/StarLoopEntryState.h | 37 - src/include/atn/StarLoopbackState.cpp | 19 - src/include/atn/StarLoopbackState.h | 25 - src/include/atn/TokensStartState.h | 24 - src/include/atn/Transition.cpp | 36 - src/include/atn/Transition.h | 65 - src/include/atn/TransitionType.cpp | 27 - src/include/atn/TransitionType.h | 33 - src/include/atn/WildcardTransition.cpp | 21 - src/include/atn/WildcardTransition.h | 27 - src/include/dfa/DFA.cpp | 115 -- src/include/dfa/DFA.h | 96 -- src/include/dfa/DFASerializer.cpp | 60 - src/include/dfa/DFASerializer.h | 32 - src/include/dfa/DFAState.cpp | 59 - src/include/dfa/DFAState.h | 154 -- src/include/dfa/LexerDFASerializer.cpp | 17 - src/include/dfa/LexerDFASerializer.h | 22 - src/include/internal/Synchronization.cpp | 100 -- src/include/internal/Synchronization.h | 154 -- src/include/misc/InterpreterDataReader.cpp | 124 -- src/include/misc/InterpreterDataReader.h | 33 - src/include/misc/Interval.cpp | 61 - src/include/misc/Interval.h | 84 - src/include/misc/IntervalSet.cpp | 508 ------ src/include/misc/IntervalSet.h | 190 --- src/include/misc/MurmurHash.cpp | 120 -- src/include/misc/MurmurHash.h | 102 -- src/include/misc/Predicate.cpp | 4 - src/include/misc/Predicate.h | 21 - src/include/support/Any.cpp | 8 - src/include/support/Any.h | 16 - src/include/support/Arrays.cpp | 43 - src/include/support/Arrays.h | 149 -- src/include/support/BitSet.h | 76 - src/include/support/CPPUtils.cpp | 207 --- src/include/support/CPPUtils.h | 65 - src/include/support/Casts.h | 34 - src/include/support/Declarations.h | 161 -- src/include/support/StringUtils.cpp | 38 - src/include/support/StringUtils.h | 16 - src/include/support/Unicode.h | 28 - src/include/support/Utf8.cpp | 242 --- src/include/support/Utf8.h | 54 - src/include/tree/AbstractParseTreeVisitor.h | 129 -- src/include/tree/ErrorNode.h | 24 - src/include/tree/ErrorNodeImpl.cpp | 54 - src/include/tree/ErrorNodeImpl.h | 43 - src/include/tree/IterativeParseTreeWalker.cpp | 66 - src/include/tree/IterativeParseTreeWalker.h | 53 - src/include/tree/ParseTree.cpp | 12 - src/include/tree/ParseTree.h | 111 -- src/include/tree/ParseTreeListener.cpp | 9 - src/include/tree/ParseTreeListener.h | 39 - src/include/tree/ParseTreeProperty.h | 50 - src/include/tree/ParseTreeType.h | 22 - src/include/tree/ParseTreeVisitor.cpp | 9 - src/include/tree/ParseTreeVisitor.h | 57 - src/include/tree/ParseTreeWalker.cpp | 48 - src/include/tree/ParseTreeWalker.h | 55 - src/include/tree/TerminalNode.h | 40 - src/include/tree/TerminalNodeImpl.cpp | 54 - src/include/tree/TerminalNodeImpl.h | 32 - src/include/tree/Trees.cpp | 241 --- src/include/tree/Trees.h | 78 - src/include/tree/pattern/Chunk.cpp | 9 - src/include/tree/pattern/Chunk.h | 44 - src/include/tree/pattern/ParseTreeMatch.cpp | 69 - src/include/tree/pattern/ParseTreeMatch.h | 132 -- src/include/tree/pattern/ParseTreePattern.cpp | 64 - src/include/tree/pattern/ParseTreePattern.h | 105 -- .../tree/pattern/ParseTreePatternMatcher.cpp | 370 ----- .../tree/pattern/ParseTreePatternMatcher.h | 185 --- src/include/tree/pattern/RuleTagToken.cpp | 77 - src/include/tree/pattern/RuleTagToken.h | 117 -- src/include/tree/pattern/TagChunk.cpp | 39 - src/include/tree/pattern/TagChunk.h | 86 - src/include/tree/pattern/TextChunk.cpp | 28 - src/include/tree/pattern/TextChunk.h | 51 - src/include/tree/pattern/TokenTagToken.cpp | 36 - src/include/tree/pattern/TokenTagToken.h | 80 - src/include/tree/xpath/XPath.cpp | 154 -- src/include/tree/xpath/XPath.h | 86 - src/include/tree/xpath/XPathElement.cpp | 31 - src/include/tree/xpath/XPathElement.h | 40 - src/include/tree/xpath/XPathLexer.cpp | 180 --- src/include/tree/xpath/XPathLexer.g4 | 64 - src/include/tree/xpath/XPathLexer.h | 53 - .../tree/xpath/XPathLexerErrorListener.cpp | 13 - .../tree/xpath/XPathLexerErrorListener.h | 22 - .../tree/xpath/XPathRuleAnywhereElement.cpp | 20 - .../tree/xpath/XPathRuleAnywhereElement.h | 27 - src/include/tree/xpath/XPathRuleElement.cpp | 30 - src/include/tree/xpath/XPathRuleElement.h | 26 - .../tree/xpath/XPathTokenAnywhereElement.cpp | 20 - .../tree/xpath/XPathTokenAnywhereElement.h | 25 - src/include/tree/xpath/XPathTokenElement.cpp | 33 - src/include/tree/xpath/XPathTokenElement.h | 26 - .../xpath/XPathWildcardAnywhereElement.cpp | 23 - .../tree/xpath/XPathWildcardAnywhereElement.h | 23 - .../tree/xpath/XPathWildcardElement.cpp | 24 - src/include/tree/xpath/XPathWildcardElement.h | 23 - 230 files changed, 20106 deletions(-) delete mode 100644 src/include/ANTLRErrorListener.cpp delete mode 100755 src/include/ANTLRErrorListener.h delete mode 100644 src/include/ANTLRErrorStrategy.cpp delete mode 100755 src/include/ANTLRErrorStrategy.h delete mode 100755 src/include/ANTLRFileStream.cpp delete mode 100755 src/include/ANTLRFileStream.h delete mode 100755 src/include/ANTLRInputStream.cpp delete mode 100755 src/include/ANTLRInputStream.h delete mode 100644 src/include/antlr4-common.h delete mode 100644 src/include/antlr4-runtime.h delete mode 100755 src/include/atn/ATN.cpp delete mode 100755 src/include/atn/ATN.h delete mode 100755 src/include/atn/ATNConfig.cpp delete mode 100755 src/include/atn/ATNConfig.h delete mode 100755 src/include/atn/ATNConfigSet.cpp delete mode 100755 src/include/atn/ATNConfigSet.h delete mode 100755 src/include/atn/ATNDeserializationOptions.cpp delete mode 100755 src/include/atn/ATNDeserializationOptions.h delete mode 100755 src/include/atn/ATNDeserializer.cpp delete mode 100755 src/include/atn/ATNDeserializer.h delete mode 100755 src/include/atn/ATNSimulator.cpp delete mode 100755 src/include/atn/ATNSimulator.h delete mode 100755 src/include/atn/ATNState.cpp delete mode 100755 src/include/atn/ATNState.h delete mode 100644 src/include/atn/ATNStateType.cpp delete mode 100644 src/include/atn/ATNStateType.h delete mode 100755 src/include/atn/ATNType.h delete mode 100755 src/include/atn/ActionTransition.cpp delete mode 100755 src/include/atn/ActionTransition.h delete mode 100755 src/include/atn/AmbiguityInfo.cpp delete mode 100755 src/include/atn/AmbiguityInfo.h delete mode 100755 src/include/atn/ArrayPredictionContext.cpp delete mode 100755 src/include/atn/ArrayPredictionContext.h delete mode 100755 src/include/atn/AtomTransition.cpp delete mode 100755 src/include/atn/AtomTransition.h delete mode 100755 src/include/atn/BasicBlockStartState.h delete mode 100755 src/include/atn/BasicState.h delete mode 100755 src/include/atn/BlockEndState.h delete mode 100755 src/include/atn/BlockStartState.h delete mode 100755 src/include/atn/ContextSensitivityInfo.cpp delete mode 100755 src/include/atn/ContextSensitivityInfo.h delete mode 100755 src/include/atn/DecisionEventInfo.cpp delete mode 100755 src/include/atn/DecisionEventInfo.h delete mode 100755 src/include/atn/DecisionInfo.cpp delete mode 100755 src/include/atn/DecisionInfo.h delete mode 100755 src/include/atn/DecisionState.cpp delete mode 100755 src/include/atn/DecisionState.h delete mode 100755 src/include/atn/EpsilonTransition.cpp delete mode 100755 src/include/atn/EpsilonTransition.h delete mode 100755 src/include/atn/ErrorInfo.cpp delete mode 100755 src/include/atn/ErrorInfo.h delete mode 100644 src/include/atn/HashUtils.h delete mode 100755 src/include/atn/LL1Analyzer.cpp delete mode 100755 src/include/atn/LL1Analyzer.h delete mode 100755 src/include/atn/LexerATNConfig.cpp delete mode 100755 src/include/atn/LexerATNConfig.h delete mode 100755 src/include/atn/LexerATNSimulator.cpp delete mode 100755 src/include/atn/LexerATNSimulator.h delete mode 100644 src/include/atn/LexerAction.cpp delete mode 100755 src/include/atn/LexerAction.h delete mode 100755 src/include/atn/LexerActionExecutor.cpp delete mode 100755 src/include/atn/LexerActionExecutor.h delete mode 100755 src/include/atn/LexerActionType.h delete mode 100755 src/include/atn/LexerChannelAction.cpp delete mode 100755 src/include/atn/LexerChannelAction.h delete mode 100755 src/include/atn/LexerCustomAction.cpp delete mode 100755 src/include/atn/LexerCustomAction.h delete mode 100755 src/include/atn/LexerIndexedCustomAction.cpp delete mode 100755 src/include/atn/LexerIndexedCustomAction.h delete mode 100755 src/include/atn/LexerModeAction.cpp delete mode 100755 src/include/atn/LexerModeAction.h delete mode 100755 src/include/atn/LexerMoreAction.cpp delete mode 100755 src/include/atn/LexerMoreAction.h delete mode 100755 src/include/atn/LexerPopModeAction.cpp delete mode 100755 src/include/atn/LexerPopModeAction.h delete mode 100755 src/include/atn/LexerPushModeAction.cpp delete mode 100755 src/include/atn/LexerPushModeAction.h delete mode 100755 src/include/atn/LexerSkipAction.cpp delete mode 100755 src/include/atn/LexerSkipAction.h delete mode 100755 src/include/atn/LexerTypeAction.cpp delete mode 100755 src/include/atn/LexerTypeAction.h delete mode 100755 src/include/atn/LookaheadEventInfo.cpp delete mode 100755 src/include/atn/LookaheadEventInfo.h delete mode 100755 src/include/atn/LoopEndState.h delete mode 100755 src/include/atn/NotSetTransition.cpp delete mode 100755 src/include/atn/NotSetTransition.h delete mode 100755 src/include/atn/OrderedATNConfigSet.cpp delete mode 100755 src/include/atn/OrderedATNConfigSet.h delete mode 100755 src/include/atn/ParseInfo.cpp delete mode 100755 src/include/atn/ParseInfo.h delete mode 100755 src/include/atn/ParserATNSimulator.cpp delete mode 100755 src/include/atn/ParserATNSimulator.h delete mode 100644 src/include/atn/ParserATNSimulatorOptions.h delete mode 100755 src/include/atn/PlusBlockStartState.h delete mode 100755 src/include/atn/PlusLoopbackState.h delete mode 100755 src/include/atn/PrecedencePredicateTransition.cpp delete mode 100755 src/include/atn/PrecedencePredicateTransition.h delete mode 100755 src/include/atn/PredicateEvalInfo.cpp delete mode 100755 src/include/atn/PredicateEvalInfo.h delete mode 100755 src/include/atn/PredicateTransition.cpp delete mode 100755 src/include/atn/PredicateTransition.h delete mode 100755 src/include/atn/PredictionContext.cpp delete mode 100755 src/include/atn/PredictionContext.h delete mode 100644 src/include/atn/PredictionContextCache.cpp delete mode 100644 src/include/atn/PredictionContextCache.h delete mode 100644 src/include/atn/PredictionContextMergeCache.cpp delete mode 100644 src/include/atn/PredictionContextMergeCache.h delete mode 100644 src/include/atn/PredictionContextMergeCacheOptions.h delete mode 100644 src/include/atn/PredictionContextType.h delete mode 100755 src/include/atn/PredictionMode.cpp delete mode 100755 src/include/atn/PredictionMode.h delete mode 100755 src/include/atn/ProfilingATNSimulator.cpp delete mode 100755 src/include/atn/ProfilingATNSimulator.h delete mode 100755 src/include/atn/RangeTransition.cpp delete mode 100755 src/include/atn/RangeTransition.h delete mode 100755 src/include/atn/RuleStartState.h delete mode 100755 src/include/atn/RuleStopState.h delete mode 100755 src/include/atn/RuleTransition.cpp delete mode 100755 src/include/atn/RuleTransition.h delete mode 100755 src/include/atn/SemanticContext.cpp delete mode 100755 src/include/atn/SemanticContext.h delete mode 100644 src/include/atn/SemanticContextType.h delete mode 100644 src/include/atn/SerializedATNView.h delete mode 100755 src/include/atn/SetTransition.cpp delete mode 100755 src/include/atn/SetTransition.h delete mode 100755 src/include/atn/SingletonPredictionContext.cpp delete mode 100755 src/include/atn/SingletonPredictionContext.h delete mode 100755 src/include/atn/StarBlockStartState.h delete mode 100755 src/include/atn/StarLoopEntryState.h delete mode 100755 src/include/atn/StarLoopbackState.cpp delete mode 100755 src/include/atn/StarLoopbackState.h delete mode 100755 src/include/atn/TokensStartState.h delete mode 100755 src/include/atn/Transition.cpp delete mode 100755 src/include/atn/Transition.h delete mode 100644 src/include/atn/TransitionType.cpp delete mode 100644 src/include/atn/TransitionType.h delete mode 100755 src/include/atn/WildcardTransition.cpp delete mode 100755 src/include/atn/WildcardTransition.h delete mode 100755 src/include/dfa/DFA.cpp delete mode 100755 src/include/dfa/DFA.h delete mode 100755 src/include/dfa/DFASerializer.cpp delete mode 100755 src/include/dfa/DFASerializer.h delete mode 100755 src/include/dfa/DFAState.cpp delete mode 100755 src/include/dfa/DFAState.h delete mode 100755 src/include/dfa/LexerDFASerializer.cpp delete mode 100755 src/include/dfa/LexerDFASerializer.h delete mode 100644 src/include/internal/Synchronization.cpp delete mode 100644 src/include/internal/Synchronization.h delete mode 100755 src/include/misc/InterpreterDataReader.cpp delete mode 100755 src/include/misc/InterpreterDataReader.h delete mode 100755 src/include/misc/Interval.cpp delete mode 100755 src/include/misc/Interval.h delete mode 100755 src/include/misc/IntervalSet.cpp delete mode 100755 src/include/misc/IntervalSet.h delete mode 100755 src/include/misc/MurmurHash.cpp delete mode 100755 src/include/misc/MurmurHash.h delete mode 100644 src/include/misc/Predicate.cpp delete mode 100755 src/include/misc/Predicate.h delete mode 100644 src/include/support/Any.cpp delete mode 100644 src/include/support/Any.h delete mode 100644 src/include/support/Arrays.cpp delete mode 100644 src/include/support/Arrays.h delete mode 100644 src/include/support/BitSet.h delete mode 100755 src/include/support/CPPUtils.cpp delete mode 100644 src/include/support/CPPUtils.h delete mode 100644 src/include/support/Casts.h delete mode 100644 src/include/support/Declarations.h delete mode 100644 src/include/support/StringUtils.cpp delete mode 100644 src/include/support/StringUtils.h delete mode 100644 src/include/support/Unicode.h delete mode 100644 src/include/support/Utf8.cpp delete mode 100644 src/include/support/Utf8.h delete mode 100755 src/include/tree/AbstractParseTreeVisitor.h delete mode 100755 src/include/tree/ErrorNode.h delete mode 100755 src/include/tree/ErrorNodeImpl.cpp delete mode 100755 src/include/tree/ErrorNodeImpl.h delete mode 100644 src/include/tree/IterativeParseTreeWalker.cpp delete mode 100644 src/include/tree/IterativeParseTreeWalker.h delete mode 100755 src/include/tree/ParseTree.cpp delete mode 100755 src/include/tree/ParseTree.h delete mode 100644 src/include/tree/ParseTreeListener.cpp delete mode 100755 src/include/tree/ParseTreeListener.h delete mode 100755 src/include/tree/ParseTreeProperty.h delete mode 100644 src/include/tree/ParseTreeType.h delete mode 100644 src/include/tree/ParseTreeVisitor.cpp delete mode 100755 src/include/tree/ParseTreeVisitor.h delete mode 100755 src/include/tree/ParseTreeWalker.cpp delete mode 100755 src/include/tree/ParseTreeWalker.h delete mode 100755 src/include/tree/TerminalNode.h delete mode 100755 src/include/tree/TerminalNodeImpl.cpp delete mode 100755 src/include/tree/TerminalNodeImpl.h delete mode 100755 src/include/tree/Trees.cpp delete mode 100755 src/include/tree/Trees.h delete mode 100644 src/include/tree/pattern/Chunk.cpp delete mode 100755 src/include/tree/pattern/Chunk.h delete mode 100755 src/include/tree/pattern/ParseTreeMatch.cpp delete mode 100755 src/include/tree/pattern/ParseTreeMatch.h delete mode 100755 src/include/tree/pattern/ParseTreePattern.cpp delete mode 100755 src/include/tree/pattern/ParseTreePattern.h delete mode 100755 src/include/tree/pattern/ParseTreePatternMatcher.cpp delete mode 100755 src/include/tree/pattern/ParseTreePatternMatcher.h delete mode 100755 src/include/tree/pattern/RuleTagToken.cpp delete mode 100755 src/include/tree/pattern/RuleTagToken.h delete mode 100755 src/include/tree/pattern/TagChunk.cpp delete mode 100755 src/include/tree/pattern/TagChunk.h delete mode 100755 src/include/tree/pattern/TextChunk.cpp delete mode 100755 src/include/tree/pattern/TextChunk.h delete mode 100755 src/include/tree/pattern/TokenTagToken.cpp delete mode 100755 src/include/tree/pattern/TokenTagToken.h delete mode 100755 src/include/tree/xpath/XPath.cpp delete mode 100755 src/include/tree/xpath/XPath.h delete mode 100755 src/include/tree/xpath/XPathElement.cpp delete mode 100755 src/include/tree/xpath/XPathElement.h delete mode 100644 src/include/tree/xpath/XPathLexer.cpp delete mode 100644 src/include/tree/xpath/XPathLexer.g4 delete mode 100644 src/include/tree/xpath/XPathLexer.h delete mode 100755 src/include/tree/xpath/XPathLexerErrorListener.cpp delete mode 100755 src/include/tree/xpath/XPathLexerErrorListener.h delete mode 100755 src/include/tree/xpath/XPathRuleAnywhereElement.cpp delete mode 100755 src/include/tree/xpath/XPathRuleAnywhereElement.h delete mode 100755 src/include/tree/xpath/XPathRuleElement.cpp delete mode 100755 src/include/tree/xpath/XPathRuleElement.h delete mode 100755 src/include/tree/xpath/XPathTokenAnywhereElement.cpp delete mode 100755 src/include/tree/xpath/XPathTokenAnywhereElement.h delete mode 100755 src/include/tree/xpath/XPathTokenElement.cpp delete mode 100755 src/include/tree/xpath/XPathTokenElement.h delete mode 100755 src/include/tree/xpath/XPathWildcardAnywhereElement.cpp delete mode 100755 src/include/tree/xpath/XPathWildcardAnywhereElement.h delete mode 100755 src/include/tree/xpath/XPathWildcardElement.cpp delete mode 100755 src/include/tree/xpath/XPathWildcardElement.h diff --git a/src/include/ANTLRErrorListener.cpp b/src/include/ANTLRErrorListener.cpp deleted file mode 100644 index 6ceadb87..00000000 --- a/src/include/ANTLRErrorListener.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "ANTLRErrorListener.h" - -antlr4::ANTLRErrorListener::~ANTLRErrorListener() -{ -} diff --git a/src/include/ANTLRErrorListener.h b/src/include/ANTLRErrorListener.h deleted file mode 100755 index d6efad1d..00000000 --- a/src/include/ANTLRErrorListener.h +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "RecognitionException.h" - -namespace antlrcpp { - class BitSet; -} - -namespace antlr4 { - - /// How to emit recognition errors (an interface in Java). - class ANTLR4CPP_PUBLIC ANTLRErrorListener { - public: - virtual ~ANTLRErrorListener(); - - /// - /// Upon syntax error, notify any interested parties. This is not how to - /// recover from errors or compute error messages. - /// specifies how to recover from syntax errors and how to compute error - /// messages. This listener's job is simply to emit a computed message, - /// though it has enough information to create its own message in many cases. - ///

- /// The is non-null for all syntax errors except - /// when we discover mismatched token errors that we can recover from - /// in-line, without returning from the surrounding rule (via the single - /// token insertion and deletion mechanism). - ///

- /// - /// What parser got the error. From this - /// object, you can access the context as well - /// as the input stream. - /// - /// The offending token in the input token - /// stream, unless recognizer is a lexer (then it's null). If - /// no viable alternative error, {@code e} has token at which we - /// started production for the decision. - /// - /// The line number in the input where the error occurred. - /// - /// The character position within that line where the error occurred. - /// - /// The message to emit. - /// - /// The exception generated by the parser that led to - /// 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. - virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line, - size_t charPositionInLine, const std::string &msg, std::exception_ptr e) = 0; - - /** - * This method is called by the parser when a full-context prediction - * results in an ambiguity. - * - *

Each full-context prediction which does not result in a syntax error - * will call either {@link #reportContextSensitivity} or - * {@link #reportAmbiguity}.

- * - *

When {@code ambigAlts} is not null, it contains the set of potentially - * viable alternatives identified by the prediction algorithm. When - * {@code ambigAlts} is null, use {@link ATNConfigSet#getAlts} to obtain the - * represented alternatives from the {@code configs} argument.

- * - *

When {@code exact} is {@code true}, all of the potentially - * viable alternatives are truly viable, i.e. this is reporting an exact - * ambiguity. When {@code exact} is {@code false}, at least two of - * the potentially viable alternatives are viable for the current input, but - * the prediction algorithm terminated as soon as it determined that at - * least the minimum potentially viable alternative is truly - * viable.

- * - *

When the {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} prediction - * mode is used, the parser is required to identify exact ambiguities so - * {@code exact} will always be {@code true}.

- * - *

This method is not used by lexers.

- * - * @param recognizer the parser instance - * @param dfa the DFA for the current decision - * @param startIndex the input index where the decision started - * @param stopIndex the input input where the ambiguity was identified - * @param exact {@code true} if the ambiguity is exactly known, otherwise - * {@code false}. This is always {@code true} when - * {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} is used. - * @param ambigAlts the potentially ambiguous alternatives, or {@code null} - * to indicate that the potentially ambiguous alternatives are the complete - * set of represented alternatives in {@code configs} - * @param configs the ATN configuration set where the ambiguity was - * identified - */ - virtual void reportAmbiguity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact, - const antlrcpp::BitSet &ambigAlts, atn::ATNConfigSet *configs) = 0; - - /** - * This method is called when an SLL conflict occurs and the parser is about - * to use the full context information to make an LL decision. - * - *

If one or more configurations in {@code configs} contains a semantic - * predicate, the predicates are evaluated before this method is called. The - * subset of alternatives which are still viable after predicates are - * evaluated is reported in {@code conflictingAlts}.

- * - *

This method is not used by lexers.

- * - * @param recognizer the parser instance - * @param dfa the DFA for the current decision - * @param startIndex the input index where the decision started - * @param stopIndex the input index where the SLL conflict occurred - * @param conflictingAlts The specific conflicting alternatives. If this is - * {@code null}, the conflicting alternatives are all alternatives - * represented in {@code configs}. At the moment, conflictingAlts is non-null - * (for the reference implementation, but Sam's optimized version can see this - * as null). - * @param configs the ATN configuration set where the SLL conflict was - * detected - */ - virtual void reportAttemptingFullContext(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex, - const antlrcpp::BitSet &conflictingAlts, atn::ATNConfigSet *configs) = 0; - - /** - * This method is called by the parser when a full-context prediction has a - * unique result. - * - *

Each full-context prediction which does not result in a syntax error - * will call either {@link #reportContextSensitivity} or - * {@link #reportAmbiguity}.

- * - *

For prediction implementations that only evaluate full-context - * predictions when an SLL conflict is found (including the default - * {@link ParserATNSimulator} implementation), this method reports cases - * where SLL conflicts were resolved to unique full-context predictions, - * i.e. the decision was context-sensitive. This report does not necessarily - * indicate a problem, and it may appear even in completely unambiguous - * grammars.

- * - *

{@code configs} may have more than one represented alternative if the - * full-context prediction algorithm does not evaluate predicates before - * beginning the full-context prediction. In all cases, the final prediction - * is passed as the {@code prediction} argument.

- * - *

Note that the definition of "context sensitivity" in this method - * differs from the concept in {@link DecisionInfo#contextSensitivities}. - * This method reports all instances where an SLL conflict occurred but LL - * parsing produced a unique result, whether or not that unique result - * matches the minimum alternative in the SLL conflicting set.

- * - *

This method is not used by lexers.

- * - * @param recognizer the parser instance - * @param dfa the DFA for the current decision - * @param startIndex the input index where the decision started - * @param stopIndex the input index where the context sensitivity was - * finally determined - * @param prediction the unambiguous result of the full-context prediction - * @param configs the ATN configuration set where the unambiguous prediction - * was determined - */ - virtual void reportContextSensitivity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex, - size_t prediction, atn::ATNConfigSet *configs) = 0; - }; - -} // namespace antlr4 diff --git a/src/include/ANTLRErrorStrategy.cpp b/src/include/ANTLRErrorStrategy.cpp deleted file mode 100644 index 1655a573..00000000 --- a/src/include/ANTLRErrorStrategy.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "ANTLRErrorStrategy.h" - -antlr4::ANTLRErrorStrategy::~ANTLRErrorStrategy() -{ -} diff --git a/src/include/ANTLRErrorStrategy.h b/src/include/ANTLRErrorStrategy.h deleted file mode 100755 index a3eecd14..00000000 --- a/src/include/ANTLRErrorStrategy.h +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "Token.h" - -namespace antlr4 { - - /// - /// The interface for defining strategies to deal with syntax errors encountered - /// during a parse by ANTLR-generated parsers. We distinguish between three - /// different kinds of errors: - /// - /// - /// - /// Implementations of this interface report syntax errors by calling - /// . - ///

- /// TODO: what to do about lexers - ///

- class ANTLR4CPP_PUBLIC ANTLRErrorStrategy { - public: - - /// - /// Reset the error handler state for the specified {@code recognizer}. - /// the parser instance - virtual ~ANTLRErrorStrategy(); - - virtual void reset(Parser *recognizer) = 0; - - /** - * This method is called when an unexpected symbol is encountered during an - * inline match operation, such as {@link Parser#match}. If the error - * strategy successfully recovers from the match failure, this method - * returns the {@link Token} instance which should be treated as the - * successful result of the match. - * - *

This method handles the consumption of any tokens - the caller should - * not call {@link Parser#consume} after a successful recovery.

- * - *

Note that the calling code will not report an error if this method - * returns successfully. The error strategy implementation is responsible - * for calling {@link Parser#notifyErrorListeners} as appropriate.

- * - * @param recognizer the parser instance - * @throws RecognitionException if the error strategy was not able to - * recover from the unexpected input symbol - */ - virtual Token* recoverInline(Parser *recognizer) = 0; - - /// - /// This method is called to recover from exception {@code e}. This method is - /// called after by the default exception handler - /// generated for a rule method. - /// - /// - /// the parser instance - /// the recognition exception to recover from - /// if the error strategy could not recover from - /// the recognition exception - virtual void recover(Parser *recognizer, std::exception_ptr e) = 0; - - /// - /// This method provides the error handler with an opportunity to handle - /// syntactic or semantic errors in the input stream before they result in a - /// . - ///

- /// The generated code currently contains calls to after - /// entering the decision state of a closure block ({@code (...)*} or - /// {@code (...)+}). - ///

- /// For an implementation based on Jim Idle's "magic sync" mechanism, see - /// . - ///

- /// - /// the parser instance - /// if an error is detected by the error - /// strategy but cannot be automatically recovered at the current state in - /// the parsing process - virtual void sync(Parser *recognizer) = 0; - - /// - /// Tests whether or not {@code recognizer} is in the process of recovering - /// from an error. In error recovery mode, adds - /// symbols to the parse tree by calling - /// {@link Parser#createErrorNode(ParserRuleContext, Token)} then - /// {@link ParserRuleContext#addErrorNode(ErrorNode)} instead of - /// {@link Parser#createTerminalNode(ParserRuleContext, Token)}. - /// - /// the parser instance - /// {@code true} if the parser is currently recovering from a parse - /// error, otherwise {@code false} - virtual bool inErrorRecoveryMode(Parser *recognizer) = 0; - - /// - /// This method is called by when the parser successfully matches an input - /// symbol. - /// - /// the parser instance - virtual void reportMatch(Parser *recognizer) = 0; - - /// - /// Report any kind of . This method is called by - /// the default exception handler generated for a rule method. - /// - /// the parser instance - /// the recognition exception to report - virtual void reportError(Parser *recognizer, const RecognitionException &e) = 0; - }; - -} // namespace antlr4 diff --git a/src/include/ANTLRFileStream.cpp b/src/include/ANTLRFileStream.cpp deleted file mode 100755 index 674817ac..00000000 --- a/src/include/ANTLRFileStream.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "ANTLRFileStream.h" - -using namespace antlr4; - -void ANTLRFileStream::loadFromFile(const std::string &fileName) { - _fileName = fileName; - if (_fileName.empty()) { - return; - } - - std::ifstream stream(fileName, std::ios::binary); - - ANTLRInputStream::load(stream); -} - -std::string ANTLRFileStream::getSourceName() const { - return _fileName; -} diff --git a/src/include/ANTLRFileStream.h b/src/include/ANTLRFileStream.h deleted file mode 100755 index 6c7d619a..00000000 --- a/src/include/ANTLRFileStream.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "ANTLRInputStream.h" - -namespace antlr4 { - - /// This is an ANTLRInputStream that is loaded from a file all at once - /// when you construct the object (or call load()). - // TODO: this class needs testing. - class ANTLR4CPP_PUBLIC ANTLRFileStream : public ANTLRInputStream { - public: - ANTLRFileStream() = default; - ANTLRFileStream(const std::string &) = delete; - ANTLRFileStream(const char *data, size_t length) = delete; - ANTLRFileStream(std::istream &stream) = delete; - - // Assumes a file name encoded in UTF-8 and file content in the same encoding (with or w/o BOM). - virtual void loadFromFile(const std::string &fileName); - virtual std::string getSourceName() const override; - - private: - std::string _fileName; // UTF-8 encoded file name. - }; - -} // namespace antlr4 diff --git a/src/include/ANTLRInputStream.cpp b/src/include/ANTLRInputStream.cpp deleted file mode 100755 index b6470af9..00000000 --- a/src/include/ANTLRInputStream.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include - -#include "Exceptions.h" -#include "misc/Interval.h" -#include "IntStream.h" - -#include "support/Utf8.h" -#include "support/CPPUtils.h" - -#include "ANTLRInputStream.h" - -using namespace antlr4; -using namespace antlrcpp; - -using misc::Interval; - -ANTLRInputStream::ANTLRInputStream() { - InitializeInstanceFields(); -} - -ANTLRInputStream::ANTLRInputStream(std::string_view input): ANTLRInputStream() { - load(input.data(), input.length()); -} - -ANTLRInputStream::ANTLRInputStream(const char *data, size_t length) { - load(data, length); -} - -ANTLRInputStream::ANTLRInputStream(std::istream &stream): ANTLRInputStream() { - load(stream); -} - -void ANTLRInputStream::load(const std::string &input, bool lenient) { - load(input.data(), input.size(), lenient); -} - -void ANTLRInputStream::load(const char *data, size_t length, bool lenient) { - // Remove the UTF-8 BOM if present. - const char *bom = "\xef\xbb\xbf"; - if (length >= 3 && strncmp(data, bom, 3) == 0) { - data += 3; - length -= 3; - } - if (lenient) { - _data = Utf8::lenientDecode(std::string_view(data, length)); - } else { - auto maybe_utf32 = Utf8::strictDecode(std::string_view(data, length)); - if (!maybe_utf32.has_value()) { - throw IllegalArgumentException("UTF-8 string contains an illegal byte sequence"); - } - _data = std::move(maybe_utf32).value(); - } - p = 0; -} - -void ANTLRInputStream::load(std::istream &stream, bool lenient) { - if (!stream.good() || stream.eof()) // No fail, bad or EOF. - return; - - _data.clear(); - - std::string s((std::istreambuf_iterator(stream)), std::istreambuf_iterator()); - load(s.data(), s.length(), lenient); -} - -void ANTLRInputStream::reset() { - p = 0; -} - -void ANTLRInputStream::consume() { - if (p >= _data.size()) { - assert(LA(1) == IntStream::EOF); - throw IllegalStateException("cannot consume EOF"); - } - - if (p < _data.size()) { - p++; - } -} - -size_t ANTLRInputStream::LA(ssize_t i) { - if (i == 0) { - return 0; // undefined - } - - ssize_t position = static_cast(p); - if (i < 0) { - i++; // e.g., translate LA(-1) to use offset i=0; then _data[p+0-1] - if ((position + i - 1) < 0) { - return IntStream::EOF; // invalid; no char before first char - } - } - - if ((position + i - 1) >= static_cast(_data.size())) { - return IntStream::EOF; - } - - return _data[static_cast((position + i - 1))]; -} - -size_t ANTLRInputStream::LT(ssize_t i) { - return LA(i); -} - -size_t ANTLRInputStream::index() { - return p; -} - -size_t ANTLRInputStream::size() { - return _data.size(); -} - -// Mark/release do nothing. We have entire buffer. -ssize_t ANTLRInputStream::mark() { - return -1; -} - -void ANTLRInputStream::release(ssize_t /* marker */) { -} - -void ANTLRInputStream::seek(size_t index) { - if (index <= p) { - p = index; // just jump; don't update stream state (line, ...) - return; - } - // seek forward, consume until p hits index or n (whichever comes first) - index = std::min(index, _data.size()); - while (p < index) { - consume(); - } -} - -std::string ANTLRInputStream::getText(const Interval &interval) { - if (interval.a < 0 || interval.b < 0) { - return ""; - } - - size_t start = static_cast(interval.a); - size_t stop = static_cast(interval.b); - - - if (stop >= _data.size()) { - stop = _data.size() - 1; - } - - size_t count = stop - start + 1; - if (start >= _data.size()) { - return ""; - } - - auto maybeUtf8 = Utf8::strictEncode(std::u32string_view(_data).substr(start, count)); - if (!maybeUtf8.has_value()) { - throw IllegalArgumentException("Input stream contains invalid Unicode code points"); - } - return std::move(maybeUtf8).value(); -} - -std::string ANTLRInputStream::getSourceName() const { - if (name.empty()) { - return IntStream::UNKNOWN_SOURCE_NAME; - } - return name; -} - -std::string ANTLRInputStream::toString() const { - auto maybeUtf8 = Utf8::strictEncode(_data); - if (!maybeUtf8.has_value()) { - throw IllegalArgumentException("Input stream contains invalid Unicode code points"); - } - return std::move(maybeUtf8).value(); -} - -void ANTLRInputStream::InitializeInstanceFields() { - p = 0; -} diff --git a/src/include/ANTLRInputStream.h b/src/include/ANTLRInputStream.h deleted file mode 100755 index 413eadef..00000000 --- a/src/include/ANTLRInputStream.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include - -#include "CharStream.h" - -namespace antlr4 { - - // Vacuum all input from a stream and then treat it - // like a string. Can also pass in a string or char[] to use. - // Input is expected to be encoded in UTF-8 and converted to UTF-32 internally. - class ANTLR4CPP_PUBLIC ANTLRInputStream : public CharStream { - protected: - /// The data being scanned. - // UTF-32 - std::u32string _data; - - /// 0..n-1 index into string of next char - size_t p; - - public: - /// What is name or source of this char stream? - std::string name; - - ANTLRInputStream(); - - ANTLRInputStream(std::string_view input); - - ANTLRInputStream(const char *data, size_t length); - ANTLRInputStream(std::istream &stream); - - virtual void load(const std::string &input, bool lenient); - virtual void load(const char *data, size_t length, bool lenient); - virtual void load(std::istream &stream, bool lenient); - - virtual void load(const std::string &input) { load(input, false); } - virtual void load(const char *data, size_t length) { load(data, length, false); } - virtual void load(std::istream &stream) { load(stream, false); } - - /// Reset the stream so that it's in the same state it was - /// when the object was created *except* the data array is not - /// touched. - virtual void reset(); - virtual void consume() override; - virtual size_t LA(ssize_t i) override; - virtual size_t LT(ssize_t i); - - /// - /// Return the current input symbol index 0..n where n indicates the - /// last symbol has been read. The index is the index of char to - /// be returned from LA(1). - /// - virtual size_t index() override; - virtual size_t size() override; - - /// - /// mark/release do nothing; we have entire buffer - virtual ssize_t mark() override; - virtual void release(ssize_t marker) override; - - /// - /// consume() ahead until p==index; can't just set p=index as we must - /// update line and charPositionInLine. If we seek backwards, just set p - /// - virtual void seek(size_t index) override; - virtual std::string getText(const misc::Interval &interval) override; - virtual std::string getSourceName() const override; - virtual std::string toString() const override; - - private: - void InitializeInstanceFields(); - }; - -} // namespace antlr4 diff --git a/src/include/antlr4-common.h b/src/include/antlr4-common.h deleted file mode 100644 index d7f9a65f..00000000 --- a/src/include/antlr4-common.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Defines for the Guid class and other platform dependent stuff. -#ifdef _WIN32 - #ifdef _MSC_VER - #pragma warning (disable: 4250) // Class inherits by dominance. - #pragma warning (disable: 4512) // assignment operator could not be generated - - #if _MSC_VER < 1900 - // Before VS 2015 code like "while (true)" will create a (useless) warning in level 4. - #pragma warning (disable: 4127) // conditional expression is constant - #endif - #endif - - #ifdef _WIN64 - typedef __int64 ssize_t; - #else - typedef __int32 ssize_t; - #endif - - #ifdef ANTLR4CPP_EXPORTS - #define ANTLR4CPP_PUBLIC __declspec(dllexport) - #else - #ifdef ANTLR4CPP_STATIC - #define ANTLR4CPP_PUBLIC - #else - #define ANTLR4CPP_PUBLIC __declspec(dllimport) - #endif - #endif - -#elif defined(__APPLE__) - #if __GNUC__ >= 4 - #define ANTLR4CPP_PUBLIC __attribute__ ((visibility ("default"))) - #else - #define ANTLR4CPP_PUBLIC - #endif -#else - #if __GNUC__ >= 6 - #define ANTLR4CPP_PUBLIC __attribute__ ((visibility ("default"))) - #else - #define ANTLR4CPP_PUBLIC - #endif -#endif - -#ifdef __has_builtin -#define ANTLR4CPP_HAVE_BUILTIN(x) __has_builtin(x) -#else -#define ANTLR4CPP_HAVE_BUILTIN(x) 0 -#endif - -#define ANTLR4CPP_INTERNAL_STRINGIFY(x) #x -#define ANTLR4CPP_STRINGIFY(x) ANTLR4CPP_INTERNAL_STRINGIFY(x) - -// We use everything from the C++ standard library by default. -#ifndef ANTLR4CPP_USING_ABSEIL -#define ANTLR4CPP_USING_ABSEIL 0 -#endif - -#include "support/Declarations.h" - -// We have to undefine this symbol as ANTLR will use this name for own members and even -// generated functions. Because EOF is a global macro we cannot use e.g. a namespace scope to disambiguate. -#ifdef EOF -#undef EOF -#endif - -#define INVALID_INDEX std::numeric_limits::max() -template using Ref = std::shared_ptr; diff --git a/src/include/antlr4-runtime.h b/src/include/antlr4-runtime.h deleted file mode 100644 index 50b85aa4..00000000 --- a/src/include/antlr4-runtime.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -// This is the umbrella header for all ANTLR4 C++ runtime headers. - -#include "antlr4-common.h" - -#include "ANTLRErrorListener.h" -#include "ANTLRErrorStrategy.h" -#include "ANTLRFileStream.h" -#include "ANTLRInputStream.h" -#include "BailErrorStrategy.h" -#include "BaseErrorListener.h" -#include "BufferedTokenStream.h" -#include "CharStream.h" -#include "CommonToken.h" -#include "CommonTokenFactory.h" -#include "CommonTokenStream.h" -#include "ConsoleErrorListener.h" -#include "DefaultErrorStrategy.h" -#include "DiagnosticErrorListener.h" -#include "Exceptions.h" -#include "FailedPredicateException.h" -#include "InputMismatchException.h" -#include "IntStream.h" -#include "InterpreterRuleContext.h" -#include "Lexer.h" -#include "LexerInterpreter.h" -#include "LexerNoViableAltException.h" -#include "ListTokenSource.h" -#include "NoViableAltException.h" -#include "Parser.h" -#include "ParserInterpreter.h" -#include "ParserRuleContext.h" -#include "ProxyErrorListener.h" -#include "RecognitionException.h" -#include "Recognizer.h" -#include "RuleContext.h" -#include "RuleContextWithAltNum.h" -#include "RuntimeMetaData.h" -#include "Token.h" -#include "TokenFactory.h" -#include "TokenSource.h" -#include "TokenStream.h" -#include "TokenStreamRewriter.h" -#include "UnbufferedCharStream.h" -#include "UnbufferedTokenStream.h" -#include "Version.h" -#include "Vocabulary.h" -#include "Vocabulary.h" -#include "WritableToken.h" -#include "atn/ATN.h" -#include "atn/ATNConfig.h" -#include "atn/ATNConfigSet.h" -#include "atn/ATNDeserializationOptions.h" -#include "atn/ATNDeserializer.h" -#include "atn/ATNSimulator.h" -#include "atn/ATNState.h" -#include "atn/ATNType.h" -#include "atn/ActionTransition.h" -#include "atn/AmbiguityInfo.h" -#include "atn/ArrayPredictionContext.h" -#include "atn/AtomTransition.h" -#include "atn/BasicBlockStartState.h" -#include "atn/BasicState.h" -#include "atn/BlockEndState.h" -#include "atn/BlockStartState.h" -#include "atn/ContextSensitivityInfo.h" -#include "atn/DecisionEventInfo.h" -#include "atn/DecisionInfo.h" -#include "atn/DecisionState.h" -#include "atn/EpsilonTransition.h" -#include "atn/ErrorInfo.h" -#include "atn/LL1Analyzer.h" -#include "atn/LexerATNConfig.h" -#include "atn/LexerATNSimulator.h" -#include "atn/LexerAction.h" -#include "atn/LexerActionExecutor.h" -#include "atn/LexerActionType.h" -#include "atn/LexerChannelAction.h" -#include "atn/LexerCustomAction.h" -#include "atn/LexerIndexedCustomAction.h" -#include "atn/LexerModeAction.h" -#include "atn/LexerMoreAction.h" -#include "atn/LexerPopModeAction.h" -#include "atn/LexerPushModeAction.h" -#include "atn/LexerSkipAction.h" -#include "atn/LexerTypeAction.h" -#include "atn/LookaheadEventInfo.h" -#include "atn/LoopEndState.h" -#include "atn/NotSetTransition.h" -#include "atn/OrderedATNConfigSet.h" -#include "atn/ParseInfo.h" -#include "atn/ParserATNSimulator.h" -#include "atn/ParserATNSimulatorOptions.h" -#include "atn/PlusBlockStartState.h" -#include "atn/PlusLoopbackState.h" -#include "atn/PrecedencePredicateTransition.h" -#include "atn/PredicateEvalInfo.h" -#include "atn/PredicateTransition.h" -#include "atn/PredictionContext.h" -#include "atn/PredictionContextCache.h" -#include "atn/PredictionContextMergeCache.h" -#include "atn/PredictionContextMergeCacheOptions.h" -#include "atn/PredictionMode.h" -#include "atn/ProfilingATNSimulator.h" -#include "atn/RangeTransition.h" -#include "atn/RuleStartState.h" -#include "atn/RuleStopState.h" -#include "atn/RuleTransition.h" -#include "atn/SemanticContext.h" -#include "atn/SerializedATNView.h" -#include "atn/SetTransition.h" -#include "atn/SingletonPredictionContext.h" -#include "atn/StarBlockStartState.h" -#include "atn/StarLoopEntryState.h" -#include "atn/StarLoopbackState.h" -#include "atn/TokensStartState.h" -#include "atn/Transition.h" -#include "atn/WildcardTransition.h" -#include "dfa/DFA.h" -#include "dfa/DFASerializer.h" -#include "dfa/DFAState.h" -#include "dfa/LexerDFASerializer.h" -#include "misc/InterpreterDataReader.h" -#include "misc/Interval.h" -#include "misc/IntervalSet.h" -#include "misc/MurmurHash.h" -#include "misc/Predicate.h" -#include "support/Any.h" -#include "support/Arrays.h" -#include "support/BitSet.h" -#include "support/Casts.h" -#include "support/CPPUtils.h" -#include "tree/AbstractParseTreeVisitor.h" -#include "tree/ErrorNode.h" -#include "tree/ErrorNodeImpl.h" -#include "tree/ParseTree.h" -#include "tree/ParseTreeListener.h" -#include "tree/ParseTreeProperty.h" -#include "tree/ParseTreeVisitor.h" -#include "tree/ParseTreeWalker.h" -#include "tree/TerminalNode.h" -#include "tree/TerminalNodeImpl.h" -#include "tree/Trees.h" -#include "tree/pattern/Chunk.h" -#include "tree/pattern/ParseTreeMatch.h" -#include "tree/pattern/ParseTreePattern.h" -#include "tree/pattern/ParseTreePatternMatcher.h" -#include "tree/pattern/RuleTagToken.h" -#include "tree/pattern/TagChunk.h" -#include "tree/pattern/TextChunk.h" -#include "tree/pattern/TokenTagToken.h" -#include "tree/xpath/XPath.h" -#include "tree/xpath/XPathElement.h" -#include "tree/xpath/XPathLexer.h" -#include "tree/xpath/XPathLexerErrorListener.h" -#include "tree/xpath/XPathRuleAnywhereElement.h" -#include "tree/xpath/XPathRuleElement.h" -#include "tree/xpath/XPathTokenAnywhereElement.h" -#include "tree/xpath/XPathTokenElement.h" -#include "tree/xpath/XPathWildcardAnywhereElement.h" -#include "tree/xpath/XPathWildcardElement.h" -#include "internal/Synchronization.h" diff --git a/src/include/atn/ATN.cpp b/src/include/atn/ATN.cpp deleted file mode 100755 index c434c933..00000000 --- a/src/include/atn/ATN.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/LL1Analyzer.h" -#include "Token.h" -#include "atn/RuleTransition.h" -#include "misc/IntervalSet.h" -#include "RuleContext.h" -#include "atn/DecisionState.h" -#include "Recognizer.h" -#include "atn/ATNType.h" -#include "Exceptions.h" -#include "support/CPPUtils.h" - -#include "atn/ATN.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::internal; -using namespace antlrcpp; - -ATN::ATN() : ATN(ATNType::LEXER, 0) {} - -ATN::ATN(ATNType grammarType_, size_t maxTokenType_) : grammarType(grammarType_), maxTokenType(maxTokenType_) {} - -ATN::~ATN() { - for (ATNState *state : states) { - delete state; - } -} - -misc::IntervalSet ATN::nextTokens(ATNState *s, RuleContext *ctx) const { - LL1Analyzer analyzer(*this); - return analyzer.LOOK(s, ctx); - -} - -misc::IntervalSet const& ATN::nextTokens(ATNState *s) const { - if (!s->_nextTokenUpdated) { - UniqueLock lock(_mutex); - if (!s->_nextTokenUpdated) { - s->_nextTokenWithinRule = nextTokens(s, nullptr); - s->_nextTokenUpdated = true; - } - } - return s->_nextTokenWithinRule; -} - -void ATN::addState(ATNState *state) { - if (state != nullptr) { - //state->atn = this; - state->stateNumber = static_cast(states.size()); - } - - states.push_back(state); -} - -void ATN::removeState(ATNState *state) { - delete states.at(state->stateNumber);// just free mem, don't shift states in list - states.at(state->stateNumber) = nullptr; -} - -int ATN::defineDecisionState(DecisionState *s) { - decisionToState.push_back(s); - s->decision = static_cast(decisionToState.size() - 1); - return s->decision; -} - -DecisionState *ATN::getDecisionState(size_t decision) const { - if (!decisionToState.empty()) { - return decisionToState[decision]; - } - return nullptr; -} - -size_t ATN::getNumberOfDecisions() const { - return decisionToState.size(); -} - -misc::IntervalSet ATN::getExpectedTokens(size_t stateNumber, RuleContext *context) const { - if (stateNumber == ATNState::INVALID_STATE_NUMBER || stateNumber >= states.size()) { - throw IllegalArgumentException("Invalid state number."); - } - - RuleContext *ctx = context; - ATNState *s = states.at(stateNumber); - misc::IntervalSet following = nextTokens(s); - if (!following.contains(Token::EPSILON)) { - return following; - } - - misc::IntervalSet expected; - expected.addAll(following); - expected.remove(Token::EPSILON); - while (ctx && ctx->invokingState != ATNState::INVALID_STATE_NUMBER && following.contains(Token::EPSILON)) { - ATNState *invokingState = states.at(ctx->invokingState); - const RuleTransition *rt = static_cast(invokingState->transitions[0].get()); - following = nextTokens(rt->followState); - expected.addAll(following); - expected.remove(Token::EPSILON); - - if (ctx->parent == nullptr) { - break; - } - ctx = static_cast(ctx->parent); - } - - if (following.contains(Token::EPSILON)) { - expected.add(Token::EOF); - } - - return expected; -} - -std::string ATN::toString() const { - std::stringstream ss; - std::string type; - switch (grammarType) { - case ATNType::LEXER: - type = "LEXER "; - break; - - case ATNType::PARSER: - type = "PARSER "; - break; - - default: - break; - } - ss << "(" << type << "ATN " << std::hex << this << std::dec << ") maxTokenType: " << maxTokenType << std::endl; - ss << "states (" << states.size() << ") {" << std::endl; - - size_t index = 0; - for (auto *state : states) { - if (state == nullptr) { - ss << " " << index++ << ": nul" << std::endl; - } else { - std::string text = state->toString(); - ss << " " << index++ << ": " << indent(text, " ", false) << std::endl; - } - } - - index = 0; - for (auto *state : decisionToState) { - if (state == nullptr) { - ss << " " << index++ << ": nul" << std::endl; - } else { - std::string text = state->toString(); - ss << " " << index++ << ": " << indent(text, " ", false) << std::endl; - } - } - - ss << "}"; - - return ss.str(); -} - diff --git a/src/include/atn/ATN.h b/src/include/atn/ATN.h deleted file mode 100755 index 1fc3fa32..00000000 --- a/src/include/atn/ATN.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "RuleContext.h" -#include "internal/Synchronization.h" - -// GCC generates a warning when forward-declaring ATN if ATN has already been -// declared due to the attributes added by ANTLR4CPP_PUBLIC. -// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39159 -// Add constant that can be checked so forward-declarations can be omitted. -#define ANTLR4CPP_ATN_DECLARED - -namespace antlr4 { -namespace atn { - - class LexerATNSimulator; - class ParserATNSimulator; - - class ANTLR4CPP_PUBLIC ATN { - public: - static constexpr size_t INVALID_ALT_NUMBER = 0; - - /// Used for runtime deserialization of ATNs from strings. - ATN(); - - ATN(ATNType grammarType, size_t maxTokenType); - - ATN(const ATN&) = delete; - - ATN(ATN&&) = delete; - - ~ATN(); - - ATN& operator=(const ATN&) = delete; - - ATN& operator=(ATN&&) = delete; - - std::vector states; - - /// Each subrule/rule is a decision point and we must track them so we - /// can go back later and build DFA predictors for them. This includes - /// all the rules, subrules, optional blocks, ()+, ()* etc... - std::vector decisionToState; - - /// Maps from rule index to starting state number. - std::vector ruleToStartState; - - /// Maps from rule index to stop state number. - std::vector ruleToStopState; - - /// The type of the ATN. - ATNType grammarType; - - /// The maximum value for any symbol recognized by a transition in the ATN. - size_t maxTokenType; - - /// - /// For lexer ATNs, this maps the rule index to the resulting token type. - /// For parser ATNs, this maps the rule index to the generated bypass token - /// type if the - /// - /// deserialization option was specified; otherwise, this is {@code null}. - /// - std::vector ruleToTokenType; - - /// For lexer ATNs, this is an array of {@link LexerAction} objects which may - /// be referenced by action transitions in the ATN. - std::vector> lexerActions; - - std::vector modeToStartState; - - /// - /// Compute the set of valid tokens that can occur starting in state {@code s}. - /// If {@code ctx} is null, the set of tokens will not include what can follow - /// the rule surrounding {@code s}. In other words, the set will be - /// restricted to tokens reachable staying within {@code s}'s rule. - /// - misc::IntervalSet nextTokens(ATNState *s, RuleContext *ctx) const; - - /// - /// Compute the set of valid tokens that can occur starting in {@code s} and - /// staying in same rule. is in set if we reach end of - /// rule. - /// - misc::IntervalSet const& nextTokens(ATNState *s) const; - - void addState(ATNState *state); - - void removeState(ATNState *state); - - int defineDecisionState(DecisionState *s); - - DecisionState *getDecisionState(size_t decision) const; - - size_t getNumberOfDecisions() const; - - /// - /// Computes the set of input symbols which could follow ATN state number - /// {@code stateNumber} in the specified full {@code context}. This method - /// considers the complete parser context, but does not evaluate semantic - /// predicates (i.e. all predicates encountered during the calculation are - /// assumed true). If a path in the ATN exists from the starting state to the - /// of the outermost context without matching any - /// symbols, is added to the returned set. - ///

- /// If {@code context} is {@code null}, it is treated as - /// . - ///

- /// the ATN state number - /// the full parse context - /// The set of potentially valid input symbols which could follow the - /// specified state in the specified context. - /// if the ATN does not contain a state with - /// number {@code stateNumber} - misc::IntervalSet getExpectedTokens(size_t stateNumber, RuleContext *context) const; - - std::string toString() const; - - private: - friend class LexerATNSimulator; - friend class ParserATNSimulator; - - mutable internal::Mutex _mutex; - mutable internal::SharedMutex _stateMutex; - mutable internal::SharedMutex _edgeMutex; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ATNConfig.cpp b/src/include/atn/ATNConfig.cpp deleted file mode 100755 index 2d7132f6..00000000 --- a/src/include/atn/ATNConfig.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "atn/PredictionContext.h" -#include "SemanticContext.h" - -#include "atn/ATNConfig.h" - -using namespace antlr4::atn; - -namespace { - -/** - * This field stores the bit mask for implementing the - * {@link #isPrecedenceFilterSuppressed} property as a bit within the - * existing {@link #reachesIntoOuterContext} field. - */ -inline constexpr size_t SUPPRESS_PRECEDENCE_FILTER = 0x40000000; - -} - -ATNConfig::ATNConfig(ATNState *state, size_t alt, Ref context) - : ATNConfig(state, alt, std::move(context), 0, SemanticContext::Empty::Instance) {} - -ATNConfig::ATNConfig(ATNState *state, size_t alt, Ref context, Ref semanticContext) - : ATNConfig(state, alt, std::move(context), 0, std::move(semanticContext)) {} - -ATNConfig::ATNConfig(ATNConfig const& other, Ref semanticContext) - : ATNConfig(other.state, other.alt, other.context, other.reachesIntoOuterContext, std::move(semanticContext)) {} - -ATNConfig::ATNConfig(ATNConfig const& other, ATNState *state) - : ATNConfig(state, other.alt, other.context, other.reachesIntoOuterContext, other.semanticContext) {} - -ATNConfig::ATNConfig(ATNConfig const& other, ATNState *state, Ref semanticContext) - : ATNConfig(state, other.alt, other.context, other.reachesIntoOuterContext, std::move(semanticContext)) {} - -ATNConfig::ATNConfig(ATNConfig const& other, ATNState *state, Ref context) - : ATNConfig(state, other.alt, std::move(context), other.reachesIntoOuterContext, other.semanticContext) {} - -ATNConfig::ATNConfig(ATNConfig const& other, ATNState *state, Ref context, Ref semanticContext) - : ATNConfig(state, other.alt, std::move(context), other.reachesIntoOuterContext, std::move(semanticContext)) {} - -ATNConfig::ATNConfig(ATNState *state, size_t alt, Ref context, size_t reachesIntoOuterContext, Ref semanticContext) - : state(state), alt(alt), context(std::move(context)), reachesIntoOuterContext(reachesIntoOuterContext), semanticContext(std::move(semanticContext)) {} - -size_t ATNConfig::hashCode() const { - size_t hashCode = misc::MurmurHash::initialize(7); - hashCode = misc::MurmurHash::update(hashCode, state->stateNumber); - hashCode = misc::MurmurHash::update(hashCode, alt); - hashCode = misc::MurmurHash::update(hashCode, context); - hashCode = misc::MurmurHash::update(hashCode, semanticContext); - hashCode = misc::MurmurHash::finish(hashCode, 4); - return hashCode; -} - -size_t ATNConfig::getOuterContextDepth() const { - return reachesIntoOuterContext & ~SUPPRESS_PRECEDENCE_FILTER; -} - -bool ATNConfig::isPrecedenceFilterSuppressed() const { - return (reachesIntoOuterContext & SUPPRESS_PRECEDENCE_FILTER) != 0; -} - -void ATNConfig::setPrecedenceFilterSuppressed(bool value) { - if (value) { - reachesIntoOuterContext |= SUPPRESS_PRECEDENCE_FILTER; - } else { - reachesIntoOuterContext &= ~SUPPRESS_PRECEDENCE_FILTER; - } -} - -bool ATNConfig::operator==(const ATNConfig &other) const { - return state->stateNumber == other.state->stateNumber && alt == other.alt && - ((context == other.context) || (*context == *other.context)) && - *semanticContext == *other.semanticContext && - isPrecedenceFilterSuppressed() == other.isPrecedenceFilterSuppressed(); -} - -std::string ATNConfig::toString() const { - return toString(true); -} - -std::string ATNConfig::toString(bool showAlt) const { - std::stringstream ss; - ss << "("; - - ss << state->toString(); - if (showAlt) { - ss << "," << alt; - } - if (context) { - ss << ",[" << context->toString() << "]"; - } - if (semanticContext != nullptr && semanticContext != SemanticContext::Empty::Instance) { - ss << "," << semanticContext->toString(); - } - if (getOuterContextDepth() > 0) { - ss << ",up=" << getOuterContextDepth(); - } - ss << ")"; - - return ss.str(); -} diff --git a/src/include/atn/ATNConfig.h b/src/include/atn/ATNConfig.h deleted file mode 100755 index 1d2e7ae1..00000000 --- a/src/include/atn/ATNConfig.h +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include - -#include "antlr4-common.h" -#include "atn/SemanticContext.h" - -namespace antlr4 { -namespace atn { - - /// - /// A tuple: (ATN state, predicted alt, syntactic, semantic context). - /// The syntactic context is a graph-structured stack node whose - /// path(s) to the root is the rule invocation(s) - /// chain used to arrive at the state. The semantic context is - /// the tree of semantic predicates encountered before reaching - /// an ATN state. - /// - class ANTLR4CPP_PUBLIC ATNConfig { - public: - struct Hasher - { - size_t operator()(Ref const& k) const { - return k->hashCode(); - } - - size_t operator()(ATNConfig const& k) const { - return k.hashCode(); - } - }; - - struct Comparer { - bool operator()(Ref const& lhs, Ref const& rhs) const { - return (lhs == rhs) || (*lhs == *rhs); - } - - bool operator()(ATNConfig const& lhs, ATNConfig const& rhs) const { - return (&lhs == &rhs) || (lhs == rhs); - } - }; - - using Set = std::unordered_set, Hasher, Comparer>; - - /// The ATN state associated with this configuration. - ATNState *state = nullptr; - - /// What alt (or lexer rule) is predicted by this configuration. - const size_t alt = 0; - - /// The stack of invoking states leading to the rule/states associated - /// with this config. We track only those contexts pushed during - /// execution of the ATN simulator. - /// - /// Can be shared between multiple ANTConfig instances. - Ref context; - - /** - * We cannot execute predicates dependent upon local context unless - * we know for sure we are in the correct context. Because there is - * no way to do this efficiently, we simply cannot evaluate - * dependent predicates unless we are in the rule that initially - * invokes the ATN simulator. - * - *

- * closure() tracks the depth of how far we dip into the outer context: - * depth > 0. Note that it may not be totally accurate depth since I - * don't ever decrement. TODO: make it a boolean then

- * - *

- * For memory efficiency, the {@link #isPrecedenceFilterSuppressed} method - * is also backed by this field. Since the field is publicly accessible, the - * highest bit which would not cause the value to become negative is used to - * store this field. This choice minimizes the risk that code which only - * compares this value to 0 would be affected by the new purpose of the - * flag. It also ensures the performance of the existing {@link ATNConfig} - * constructors as well as certain operations like - * {@link ATNConfigSet#add(ATNConfig, DoubleKeyMap)} method are - * completely unaffected by the change.

- */ - size_t reachesIntoOuterContext = 0; - - /// Can be shared between multiple ATNConfig instances. - Ref semanticContext; - - ATNConfig(ATNState *state, size_t alt, Ref context); - ATNConfig(ATNState *state, size_t alt, Ref context, Ref semanticContext); - - ATNConfig(ATNConfig const& other, Ref semanticContext); - ATNConfig(ATNConfig const& other, ATNState *state); - ATNConfig(ATNConfig const& other, ATNState *state, Ref semanticContext); - ATNConfig(ATNConfig const& other, ATNState *state, Ref context); - ATNConfig(ATNConfig const& other, ATNState *state, Ref context, Ref semanticContext); - - ATNConfig(ATNConfig const&) = default; - - ATNConfig(ATNConfig&&) = default; - - virtual ~ATNConfig() = default; - - virtual size_t hashCode() const; - - /** - * This method gets the value of the {@link #reachesIntoOuterContext} field - * as it existed prior to the introduction of the - * {@link #isPrecedenceFilterSuppressed} method. - */ - size_t getOuterContextDepth() const; - bool isPrecedenceFilterSuppressed() const; - void setPrecedenceFilterSuppressed(bool value); - - /// An ATN configuration is equal to another if both have - /// the same state, they predict the same alternative, and - /// syntactic/semantic contexts are the same. - bool operator==(const ATNConfig &other) const; - bool operator!=(const ATNConfig &other) const; - - virtual std::string toString() const; - std::string toString(bool showAlt) const; - - private: - ATNConfig(ATNState *state, size_t alt, Ref context, size_t reachesIntoOuterContext, Ref semanticContext); - }; - -} // namespace atn -} // namespace antlr4 - - -// Hash function for ATNConfig. - -namespace std { - using antlr4::atn::ATNConfig; - - template <> struct hash - { - size_t operator() (const ATNConfig &x) const - { - return x.hashCode(); - } - }; - - template <> struct hash>> - { - size_t operator() (const std::vector> &vector) const - { - std::size_t seed = 0; - for (const auto &config : vector) { - seed ^= config->hashCode() + 0x9e3779b9 + (seed << 6) + (seed >> 2); - } - return seed; - } - }; -} diff --git a/src/include/atn/ATNConfigSet.cpp b/src/include/atn/ATNConfigSet.cpp deleted file mode 100755 index 4c5e8470..00000000 --- a/src/include/atn/ATNConfigSet.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/PredictionContext.h" -#include "atn/ATNConfig.h" -#include "atn/ATNSimulator.h" -#include "Exceptions.h" -#include "atn/SemanticContext.h" -#include "support/Arrays.h" - -#include "atn/ATNConfigSet.h" - -using namespace antlr4::atn; -using namespace antlrcpp; - -namespace { - -} - -ATNConfigSet::ATNConfigSet() : ATNConfigSet(true) {} - -ATNConfigSet::ATNConfigSet(const ATNConfigSet &other) - : fullCtx(other.fullCtx), _configLookup(other._configLookup.bucket_count(), ATNConfigHasher{this}, ATNConfigComparer{this}) { - addAll(other); - uniqueAlt = other.uniqueAlt; - conflictingAlts = other.conflictingAlts; - hasSemanticContext = other.hasSemanticContext; - dipsIntoOuterContext = other.dipsIntoOuterContext; -} - -ATNConfigSet::ATNConfigSet(bool fullCtx) - : fullCtx(fullCtx), _configLookup(0, ATNConfigHasher{this}, ATNConfigComparer{this}) {} - -bool ATNConfigSet::add(const Ref &config) { - return add(config, nullptr); -} - -bool ATNConfigSet::add(const Ref &config, PredictionContextMergeCache *mergeCache) { - assert(config); - - if (_readonly) { - throw IllegalStateException("This set is readonly"); - } - if (config->semanticContext != SemanticContext::Empty::Instance) { - hasSemanticContext = true; - } - if (config->getOuterContextDepth() > 0) { - dipsIntoOuterContext = true; - } - - auto existing = _configLookup.find(config.get()); - if (existing == _configLookup.end()) { - _configLookup.insert(config.get()); - _cachedHashCode = 0; - configs.push_back(config); // track order here - - return true; - } - - // a previous (s,i,pi,_), merge with it and save result - bool rootIsWildcard = !fullCtx; - Ref merged = PredictionContext::merge((*existing)->context, config->context, rootIsWildcard, mergeCache); - // no need to check for existing.context, config.context in cache - // since only way to create new graphs is "call rule" and here. We - // cache at both places. - (*existing)->reachesIntoOuterContext = std::max((*existing)->reachesIntoOuterContext, config->reachesIntoOuterContext); - - // make sure to preserve the precedence filter suppression during the merge - if (config->isPrecedenceFilterSuppressed()) { - (*existing)->setPrecedenceFilterSuppressed(true); - } - - (*existing)->context = std::move(merged); // replace context; no need to alt mapping - - return true; -} - -bool ATNConfigSet::addAll(const ATNConfigSet &other) { - for (const auto &c : other.configs) { - add(c); - } - return false; -} - -std::vector ATNConfigSet::getStates() const { - std::vector states; - states.reserve(configs.size()); - for (const auto &c : configs) { - states.push_back(c->state); - } - return states; -} - -/** - * Gets the complete set of represented alternatives for the configuration - * set. - * - * @return the set of represented alternatives in this configuration set - * - * @since 4.3 - */ - -BitSet ATNConfigSet::getAlts() const { - BitSet alts; - for (const auto &config : configs) { - alts.set(config->alt); - } - return alts; -} - -std::vector> ATNConfigSet::getPredicates() const { - std::vector> preds; - preds.reserve(configs.size()); - for (const auto &c : configs) { - if (c->semanticContext != SemanticContext::Empty::Instance) { - preds.push_back(c->semanticContext); - } - } - return preds; -} - -const Ref& ATNConfigSet::get(size_t i) const { - return configs[i]; -} - -void ATNConfigSet::optimizeConfigs(ATNSimulator *interpreter) { - assert(interpreter); - - if (_readonly) { - throw IllegalStateException("This set is readonly"); - } - if (_configLookup.empty()) - return; - - for (const auto &config : configs) { - config->context = interpreter->getCachedContext(config->context); - } -} - -bool ATNConfigSet::equals(const ATNConfigSet &other) const { - if (&other == this) { - return true; - } - - if (configs.size() != other.configs.size()) - return false; - - if (fullCtx != other.fullCtx || uniqueAlt != other.uniqueAlt || - conflictingAlts != other.conflictingAlts || hasSemanticContext != other.hasSemanticContext || - dipsIntoOuterContext != other.dipsIntoOuterContext) // includes stack context - return false; - - return Arrays::equals(configs, other.configs); -} - -size_t ATNConfigSet::hashCode() const { - size_t cachedHashCode = _cachedHashCode.load(std::memory_order_relaxed); - if (!isReadonly() || cachedHashCode == 0) { - cachedHashCode = 1; - for (const auto &i : configs) { - cachedHashCode = 31 * cachedHashCode + i->hashCode(); // Same as Java's list hashCode impl. - } - _cachedHashCode.store(cachedHashCode, std::memory_order_relaxed); - } - return cachedHashCode; -} - -size_t ATNConfigSet::size() const { - return configs.size(); -} - -bool ATNConfigSet::isEmpty() const { - return configs.empty(); -} - -void ATNConfigSet::clear() { - if (_readonly) { - throw IllegalStateException("This set is readonly"); - } - configs.clear(); - _cachedHashCode = 0; - _configLookup.clear(); -} - -bool ATNConfigSet::isReadonly() const { - return _readonly; -} - -void ATNConfigSet::setReadonly(bool readonly) { - _readonly = readonly; - LookupContainer(0, ATNConfigHasher{this}, ATNConfigComparer{this}).swap(_configLookup); -} - -std::string ATNConfigSet::toString() const { - std::stringstream ss; - ss << "["; - for (size_t i = 0; i < configs.size(); i++) { - if ( i>0 ) ss << ", "; - ss << configs[i]->toString(); - } - ss << "]"; - - if (hasSemanticContext) { - ss << ",hasSemanticContext=" << (hasSemanticContext?"true":"false"); - } - if (uniqueAlt != ATN::INVALID_ALT_NUMBER) { - ss << ",uniqueAlt=" << uniqueAlt; - } - - if (conflictingAlts.count() > 0) { - ss << ",conflictingAlts="; - ss << conflictingAlts.toString(); - } - - if (dipsIntoOuterContext) { - ss << ",dipsIntoOuterContext"; - } - return ss.str(); -} - -size_t ATNConfigSet::hashCode(const ATNConfig &other) const { - size_t hashCode = 7; - hashCode = 31 * hashCode + other.state->stateNumber; - hashCode = 31 * hashCode + other.alt; - hashCode = 31 * hashCode + other.semanticContext->hashCode(); - return hashCode; -} - -bool ATNConfigSet::equals(const ATNConfig &lhs, const ATNConfig &rhs) const { - return lhs.state->stateNumber == rhs.state->stateNumber && lhs.alt == rhs.alt && *lhs.semanticContext == *rhs.semanticContext; -} diff --git a/src/include/atn/ATNConfigSet.h b/src/include/atn/ATNConfigSet.h deleted file mode 100755 index d147f183..00000000 --- a/src/include/atn/ATNConfigSet.h +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include - -#include "support/BitSet.h" -#include "atn/PredictionContext.h" -#include "atn/ATNConfig.h" -#include "FlatHashSet.h" - -namespace antlr4 { -namespace atn { - - /// Specialized set that can track info about the set, with support for combining similar configurations using a - /// graph-structured stack. - class ANTLR4CPP_PUBLIC ATNConfigSet { - public: - /// Track the elements as they are added to the set; supports get(i) - std::vector> configs; - - // TODO: these fields make me pretty uncomfortable but nice to pack up info together, saves recomputation - // TODO: can we track conflicts as they are added to save scanning configs later? - size_t uniqueAlt = 0; - - /** Currently this is only used when we detect SLL conflict; this does - * not necessarily represent the ambiguous alternatives. In fact, - * I should also point out that this seems to include predicated alternatives - * that have predicates that evaluate to false. Computed in computeTargetState(). - */ - 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. - bool hasSemanticContext = false; - bool dipsIntoOuterContext = false; - - /// Indicates that this configuration set is part of a full context - /// LL prediction. It will be used to determine how to merge $. With SLL - /// it's a wildcard whereas it is not for LL context merge. - const bool fullCtx = true; - - ATNConfigSet(); - - ATNConfigSet(const ATNConfigSet &other); - - ATNConfigSet(ATNConfigSet&&) = delete; - - explicit ATNConfigSet(bool fullCtx); - - virtual ~ATNConfigSet() = default; - - bool add(const Ref &config); - - /// - /// Adding a new config means merging contexts with existing configs for - /// {@code (s, i, pi, _)}, where {@code s} is the - /// , {@code i} is the , and - /// {@code pi} is the . We use - /// {@code (s,i,pi)} as key. - ///

- /// This method updates and - /// when necessary. - ///

- bool add(const Ref &config, PredictionContextMergeCache *mergeCache); - - bool addAll(const ATNConfigSet &other); - - std::vector getStates() const; - - /** - * Gets the complete set of represented alternatives for the configuration - * set. - * - * @return the set of represented alternatives in this configuration set - * - * @since 4.3 - */ - antlrcpp::BitSet getAlts() const; - std::vector> getPredicates() const; - - const Ref& get(size_t i) const; - - void optimizeConfigs(ATNSimulator *interpreter); - - size_t size() const; - bool isEmpty() const; - void clear(); - bool isReadonly() const; - void setReadonly(bool readonly); - - virtual size_t hashCode() const; - - virtual bool equals(const ATNConfigSet &other) const; - - virtual std::string toString() const; - - private: - struct ATNConfigHasher final { - const ATNConfigSet* atnConfigSet; - - size_t operator()(const ATNConfig *other) const { - assert(other != nullptr); - return atnConfigSet->hashCode(*other); - } - }; - - struct ATNConfigComparer final { - const ATNConfigSet* atnConfigSet; - - bool operator()(const ATNConfig *lhs, const ATNConfig *rhs) const { - assert(lhs != nullptr); - assert(rhs != nullptr); - return atnConfigSet->equals(*lhs, *rhs); - } - }; - - mutable std::atomic _cachedHashCode = 0; - - /// Indicates that the set of configurations is read-only. Do not - /// allow any code to manipulate the set; DFA states will point at - /// the sets and they must not change. This does not protect the other - /// fields; in particular, conflictingAlts is set after - /// we've made this readonly. - bool _readonly = false; - - virtual size_t hashCode(const ATNConfig &atnConfig) const; - - virtual bool equals(const ATNConfig &lhs, const ATNConfig &rhs) const; - - using LookupContainer = FlatHashSet; - - /// All configs but hashed by (s, i, _, pi) not including context. Wiped out - /// when we go readonly as this set becomes a DFA state. - LookupContainer _configLookup; - }; - - inline bool operator==(const ATNConfigSet &lhs, const ATNConfigSet &rhs) { return lhs.equals(rhs); } - - inline bool operator!=(const ATNConfigSet &lhs, const ATNConfigSet &rhs) { return !operator==(lhs, rhs); } - -} // namespace atn -} // namespace antlr4 - -namespace std { - -template <> -struct hash<::antlr4::atn::ATNConfigSet> { - size_t operator()(const ::antlr4::atn::ATNConfigSet &atnConfigSet) const { - return atnConfigSet.hashCode(); - } -}; - -} // namespace std diff --git a/src/include/atn/ATNDeserializationOptions.cpp b/src/include/atn/ATNDeserializationOptions.cpp deleted file mode 100755 index 40fb855b..00000000 --- a/src/include/atn/ATNDeserializationOptions.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ATNDeserializationOptions.h" -#include "Exceptions.h" - -using namespace antlr4; -using namespace antlr4::atn; - -ATNDeserializationOptions::ATNDeserializationOptions(ATNDeserializationOptions *options) - : _readOnly(false), _verifyATN(options->_verifyATN), - _generateRuleBypassTransitions(options->_generateRuleBypassTransitions) {} - -const ATNDeserializationOptions& ATNDeserializationOptions::getDefaultOptions() { - static const std::unique_ptr defaultOptions = std::make_unique(); - return *defaultOptions; -} - -void ATNDeserializationOptions::makeReadOnly() { - _readOnly = true; -} - -void ATNDeserializationOptions::setVerifyATN(bool verify) { - throwIfReadOnly(); - _verifyATN = verify; -} - -void ATNDeserializationOptions::setGenerateRuleBypassTransitions(bool generate) { - throwIfReadOnly(); - _generateRuleBypassTransitions = generate; -} - -void ATNDeserializationOptions::throwIfReadOnly() const { - if (isReadOnly()) { - throw IllegalStateException("ATNDeserializationOptions is read only."); - } -} diff --git a/src/include/atn/ATNDeserializationOptions.h b/src/include/atn/ATNDeserializationOptions.h deleted file mode 100755 index 8b1f9850..00000000 --- a/src/include/atn/ATNDeserializationOptions.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - -class ANTLR4CPP_PUBLIC ATNDeserializationOptions final { -public: - ATNDeserializationOptions() - : _readOnly(false), _verifyATN(true), _generateRuleBypassTransitions(false) {} - - // TODO: Is this useful? If so we should mark it as explicit, otherwise remove it. - ATNDeserializationOptions(ATNDeserializationOptions *options); - - ATNDeserializationOptions(const ATNDeserializationOptions&) = default; - - ATNDeserializationOptions& operator=(const ATNDeserializationOptions&) = default; - - static const ATNDeserializationOptions& getDefaultOptions(); - - bool isReadOnly() const { return _readOnly; } - - void makeReadOnly(); - - bool isVerifyATN() const { return _verifyATN; } - - void setVerifyATN(bool verify); - - bool isGenerateRuleBypassTransitions() const { return _generateRuleBypassTransitions; } - - void setGenerateRuleBypassTransitions(bool generate); - -private: - void throwIfReadOnly() const; - - bool _readOnly; - bool _verifyATN; - bool _generateRuleBypassTransitions; -}; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ATNDeserializer.cpp b/src/include/atn/ATNDeserializer.cpp deleted file mode 100755 index 47ad15d6..00000000 --- a/src/include/atn/ATNDeserializer.cpp +++ /dev/null @@ -1,628 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ATNDeserializationOptions.h" - -#include "atn/ATNType.h" -#include "atn/ATNState.h" -#include "atn/ATN.h" - -#include "atn/LoopEndState.h" -#include "atn/DecisionState.h" -#include "atn/RuleStartState.h" -#include "atn/RuleStopState.h" -#include "atn/TokensStartState.h" -#include "atn/RuleTransition.h" -#include "atn/EpsilonTransition.h" -#include "atn/PlusLoopbackState.h" -#include "atn/PlusBlockStartState.h" -#include "atn/StarLoopbackState.h" -#include "atn/BasicBlockStartState.h" -#include "atn/BasicState.h" -#include "atn/BlockEndState.h" -#include "atn/StarLoopEntryState.h" - -#include "atn/AtomTransition.h" -#include "atn/StarBlockStartState.h" -#include "atn/RangeTransition.h" -#include "atn/PredicateTransition.h" -#include "atn/PrecedencePredicateTransition.h" -#include "atn/ActionTransition.h" -#include "atn/SetTransition.h" -#include "atn/NotSetTransition.h" -#include "atn/WildcardTransition.h" -#include "atn/TransitionType.h" -#include "Token.h" - -#include "misc/IntervalSet.h" -#include "Exceptions.h" -#include "support/CPPUtils.h" -#include "support/Casts.h" - -#include "atn/LexerCustomAction.h" -#include "atn/LexerChannelAction.h" -#include "atn/LexerModeAction.h" -#include "atn/LexerMoreAction.h" -#include "atn/LexerPopModeAction.h" -#include "atn/LexerPushModeAction.h" -#include "atn/LexerSkipAction.h" -#include "atn/LexerTypeAction.h" - -#include "atn/ATNDeserializer.h" - -#include -#include -#include - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlrcpp; - -namespace { - - void checkCondition(bool condition, std::string_view message) { - if (!condition) { - throw IllegalStateException(std::string(message)); - } - } - - void checkCondition(bool condition) { - checkCondition(condition, ""); - } - - /** - * Analyze the {@link StarLoopEntryState} states in the specified ATN to set - * the {@link StarLoopEntryState#isPrecedenceDecision} field to the - * correct value. - * - * @param atn The ATN. - */ - void markPrecedenceDecisions(const ATN &atn) { - for (ATNState *state : atn.states) { - if (!StarLoopEntryState::is(state)) { - continue; - } - - /* We analyze the ATN to determine if this ATN decision state is the - * decision for the closure block that determines whether a - * precedence rule should continue or complete. - */ - if (atn.ruleToStartState[state->ruleIndex]->isLeftRecursiveRule) { - ATNState *maybeLoopEndState = state->transitions[state->transitions.size() - 1]->target; - if (LoopEndState::is(maybeLoopEndState)) { - if (maybeLoopEndState->epsilonOnlyTransitions && RuleStopState::is(maybeLoopEndState->transitions[0]->target)) { - downCast(state)->isPrecedenceDecision = true; - } - } - } - } - } - - Ref lexerActionFactory(LexerActionType type, int data1, int data2) { - switch (type) { - case LexerActionType::CHANNEL: - return std::make_shared(data1); - - case LexerActionType::CUSTOM: - return std::make_shared(data1, data2); - - case LexerActionType::MODE: - return std::make_shared< LexerModeAction>(data1); - - case LexerActionType::MORE: - return LexerMoreAction::getInstance(); - - case LexerActionType::POP_MODE: - return LexerPopModeAction::getInstance(); - - case LexerActionType::PUSH_MODE: - return std::make_shared(data1); - - case LexerActionType::SKIP: - return LexerSkipAction::getInstance(); - - case LexerActionType::TYPE: - return std::make_shared(data1); - - default: - throw IllegalArgumentException("The specified lexer action type " + std::to_string(static_cast(type)) + - " is not valid."); - } - } - - ConstTransitionPtr edgeFactory(const ATN &atn, TransitionType type, size_t trg, size_t arg1, size_t arg2, - size_t arg3, const std::vector &sets) { - ATNState *target = atn.states[trg]; - switch (type) { - case TransitionType::EPSILON: - return std::make_unique(target); - case TransitionType::RANGE: - if (arg3 != 0) { - return std::make_unique(target, Token::EOF, arg2); - } else { - return std::make_unique(target, arg1, arg2); - } - case TransitionType::RULE: - return std::make_unique(downCast(atn.states[arg1]), arg2, (int)arg3, target); - case TransitionType::PREDICATE: - return std::make_unique(target, arg1, arg2, arg3 != 0); - case TransitionType::PRECEDENCE: - return std::make_unique(target, (int)arg1); - case TransitionType::ATOM: - if (arg3 != 0) { - return std::make_unique(target, Token::EOF); - } else { - return std::make_unique(target, arg1); - } - case TransitionType::ACTION: - return std::make_unique(target, arg1, arg2, arg3 != 0); - case TransitionType::SET: - return std::make_unique(target, sets[arg1]); - case TransitionType::NOT_SET: - return std::make_unique(target, sets[arg1]); - case TransitionType::WILDCARD: - return std::make_unique(target); - } - - throw IllegalArgumentException("The specified transition type is not valid."); - } - - /* mem check: all created instances are freed in the d-tor of the ATN. */ - ATNState* stateFactory(ATNStateType type, size_t ruleIndex) { - ATNState *s; - switch (type) { - case ATNStateType::INVALID: - return nullptr; - case ATNStateType::BASIC : - s = new BasicState(); - break; - case ATNStateType::RULE_START : - s = new RuleStartState(); - break; - case ATNStateType::BLOCK_START : - s = new BasicBlockStartState(); - break; - case ATNStateType::PLUS_BLOCK_START : - s = new PlusBlockStartState(); - break; - case ATNStateType::STAR_BLOCK_START : - s = new StarBlockStartState(); - break; - case ATNStateType::TOKEN_START : - s = new TokensStartState(); - break; - case ATNStateType::RULE_STOP : - s = new RuleStopState(); - break; - case ATNStateType::BLOCK_END : - s = new BlockEndState(); - break; - case ATNStateType::STAR_LOOP_BACK : - s = new StarLoopbackState(); - break; - case ATNStateType::STAR_LOOP_ENTRY : - s = new StarLoopEntryState(); - break; - case ATNStateType::PLUS_LOOP_BACK : - s = new PlusLoopbackState(); - break; - case ATNStateType::LOOP_END : - s = new LoopEndState(); - break; - default : - std::string message = "The specified state type " + std::to_string(static_cast(type)) + " is not valid."; - throw IllegalArgumentException(message); - } - assert(s->getStateType() == type); - s->ruleIndex = ruleIndex; - return s; - } - - ssize_t readUnicodeInt32(SerializedATNView data, int& p) { - return static_cast(data[p++]); - } - - void deserializeSets( - SerializedATNView data, - int& p, - std::vector& sets) { - size_t nsets = data[p++]; - sets.reserve(sets.size() + nsets); - for (size_t i = 0; i < nsets; i++) { - size_t nintervals = data[p++]; - misc::IntervalSet set; - - bool containsEof = data[p++] != 0; - if (containsEof) { - set.add(-1); - } - - for (size_t j = 0; j < nintervals; j++) { - auto a = readUnicodeInt32(data, p); - auto b = readUnicodeInt32(data, p); - set.add(a, b); - } - sets.push_back(set); - } - } - -} - -ATNDeserializer::ATNDeserializer() : ATNDeserializer(ATNDeserializationOptions::getDefaultOptions()) {} - -ATNDeserializer::ATNDeserializer(ATNDeserializationOptions deserializationOptions) : _deserializationOptions(std::move(deserializationOptions)) {} - -std::unique_ptr ATNDeserializer::deserialize(SerializedATNView data) const { - int p = 0; - int version = data[p++]; - if (version != SERIALIZED_VERSION) { - std::string reason = "Could not deserialize ATN with version" + std::to_string(version) + "(expected " + std::to_string(SERIALIZED_VERSION) + ")."; - - throw UnsupportedOperationException(reason); - } - - ATNType grammarType = (ATNType)data[p++]; - size_t maxTokenType = data[p++]; - auto atn = std::make_unique(grammarType, maxTokenType); - - // - // STATES - // - { - std::vector> loopBackStateNumbers; - std::vector> endStateNumbers; - size_t nstates = data[p++]; - atn->states.reserve(nstates); - loopBackStateNumbers.reserve(nstates); // Reserve worst case size, its short lived. - endStateNumbers.reserve(nstates); // Reserve worst case size, its short lived. - for (size_t i = 0; i < nstates; i++) { - ATNStateType stype = static_cast(data[p++]); - // ignore bad type of states - if (stype == ATNStateType::INVALID) { - atn->addState(nullptr); - continue; - } - - size_t ruleIndex = data[p++]; - ATNState *s = stateFactory(stype, ruleIndex); - if (stype == ATNStateType::LOOP_END) { // special case - int loopBackStateNumber = data[p++]; - loopBackStateNumbers.push_back({ downCast(s), loopBackStateNumber }); - } else if (BlockStartState::is(s)) { - int endStateNumber = data[p++]; - endStateNumbers.push_back({ downCast(s), endStateNumber }); - } - atn->addState(s); - } - - // delay the assignment of loop back and end states until we know all the state instances have been initialized - for (auto &pair : loopBackStateNumbers) { - pair.first->loopBackState = atn->states[pair.second]; - } - - for (auto &pair : endStateNumbers) { - pair.first->endState = downCast(atn->states[pair.second]); - } - } - - size_t numNonGreedyStates = data[p++]; - for (size_t i = 0; i < numNonGreedyStates; i++) { - size_t stateNumber = data[p++]; - // The serialized ATN must be specifying the right states, so that the - // cast below is correct. - downCast(atn->states[stateNumber])->nonGreedy = true; - } - - size_t numPrecedenceStates = data[p++]; - for (size_t i = 0; i < numPrecedenceStates; i++) { - size_t stateNumber = data[p++]; - downCast(atn->states[stateNumber])->isLeftRecursiveRule = true; - } - - // - // RULES - // - size_t nrules = data[p++]; - atn->ruleToStartState.reserve(nrules); - for (size_t i = 0; i < nrules; i++) { - size_t s = data[p++]; - // Also here, the serialized atn must ensure to point to the correct class type. - RuleStartState *startState = downCast(atn->states[s]); - atn->ruleToStartState.push_back(startState); - if (atn->grammarType == ATNType::LEXER) { - size_t tokenType = data[p++]; - atn->ruleToTokenType.push_back(tokenType); - } - } - - atn->ruleToStopState.resize(nrules); - for (ATNState *state : atn->states) { - if (!RuleStopState::is(state)) { - continue; - } - - RuleStopState *stopState = downCast(state); - atn->ruleToStopState[state->ruleIndex] = stopState; - atn->ruleToStartState[state->ruleIndex]->stopState = stopState; - } - - // - // MODES - // - size_t nmodes = data[p++]; - atn->modeToStartState.reserve(nmodes); - for (size_t i = 0; i < nmodes; i++) { - size_t s = data[p++]; - atn->modeToStartState.push_back(downCast(atn->states[s])); - } - - // - // SETS - // - { - std::vector sets; - - deserializeSets(data, p, sets); - sets.shrink_to_fit(); - - // - // EDGES - // - int nedges = data[p++]; - for (int i = 0; i < nedges; i++) { - size_t src = data[p]; - size_t trg = data[p + 1]; - TransitionType ttype = static_cast(data[p + 2]); - size_t arg1 = data[p + 3]; - size_t arg2 = data[p + 4]; - size_t arg3 = data[p + 5]; - ConstTransitionPtr trans = edgeFactory(*atn, ttype, trg, arg1, arg2, arg3, sets); - ATNState *srcState = atn->states[src]; - srcState->addTransition(std::move(trans)); - p += 6; - } - } - // edges for rule stop states can be derived, so they aren't serialized - for (ATNState *state : atn->states) { - for (size_t i = 0; i < state->transitions.size(); i++) { - const Transition *t = state->transitions[i].get(); - if (!RuleTransition::is(t)) { - continue; - } - - const RuleTransition *ruleTransition = downCast(t); - size_t outermostPrecedenceReturn = INVALID_INDEX; - if (atn->ruleToStartState[ruleTransition->target->ruleIndex]->isLeftRecursiveRule) { - if (ruleTransition->precedence == 0) { - outermostPrecedenceReturn = ruleTransition->target->ruleIndex; - } - } - - ConstTransitionPtr returnTransition = std::make_unique(ruleTransition->followState, outermostPrecedenceReturn); - atn->ruleToStopState[ruleTransition->target->ruleIndex]->addTransition(std::move(returnTransition)); - } - } - - for (ATNState *state : atn->states) { - if (BlockStartState::is(state)) { - BlockStartState *startState = downCast(state); - - // we need to know the end state to set its start state - if (startState->endState == nullptr) { - throw IllegalStateException(); - } - - // block end states can only be associated to a single block start state - if (startState->endState->startState != nullptr) { - throw IllegalStateException(); - } - - startState->endState->startState = downCast(state); - } - - if (PlusLoopbackState::is(state)) { - PlusLoopbackState *loopbackState = downCast(state); - for (size_t i = 0; i < loopbackState->transitions.size(); i++) { - ATNState *target = loopbackState->transitions[i]->target; - if (PlusBlockStartState::is(target)) { - (downCast(target))->loopBackState = loopbackState; - } - } - } else if (StarLoopbackState::is(state)) { - StarLoopbackState *loopbackState = downCast(state); - for (size_t i = 0; i < loopbackState->transitions.size(); i++) { - ATNState *target = loopbackState->transitions[i]->target; - if (StarLoopEntryState::is(target)) { - downCast(target)->loopBackState = loopbackState; - } - } - } - } - - // - // DECISIONS - // - size_t ndecisions = data[p++]; - atn->decisionToState.reserve(ndecisions); - for (size_t i = 0; i < ndecisions; i++) { - size_t s = data[p++]; - DecisionState *decState = downCast(atn->states[s]); - if (decState == nullptr) - throw IllegalStateException(); - - atn->decisionToState.push_back(decState); - decState->decision = static_cast(i); - } - - // - // LEXER ACTIONS - // - if (atn->grammarType == ATNType::LEXER) { - atn->lexerActions.resize(data[p++]); - for (size_t i = 0; i < atn->lexerActions.size(); i++) { - LexerActionType actionType = static_cast(data[p++]); - int data1 = data[p++]; - int data2 = data[p++]; - atn->lexerActions[i] = lexerActionFactory(actionType, data1, data2); - } - } - - markPrecedenceDecisions(*atn); - - if (_deserializationOptions.isVerifyATN()) { - verifyATN(*atn); - } - - if (_deserializationOptions.isGenerateRuleBypassTransitions() && atn->grammarType == ATNType::PARSER) { - atn->ruleToTokenType.resize(atn->ruleToStartState.size()); - for (size_t i = 0; i < atn->ruleToStartState.size(); i++) { - atn->ruleToTokenType[i] = static_cast(atn->maxTokenType + i + 1); - } - - for (std::vector::size_type i = 0; i < atn->ruleToStartState.size(); i++) { - BasicBlockStartState *bypassStart = new BasicBlockStartState(); /* mem check: freed in ATN d-tor */ - bypassStart->ruleIndex = static_cast(i); - atn->addState(bypassStart); - - BlockEndState *bypassStop = new BlockEndState(); /* mem check: freed in ATN d-tor */ - bypassStop->ruleIndex = static_cast(i); - atn->addState(bypassStop); - - bypassStart->endState = bypassStop; - atn->defineDecisionState(bypassStart); - - bypassStop->startState = bypassStart; - - ATNState *endState; - const Transition *excludeTransition = nullptr; - if (atn->ruleToStartState[i]->isLeftRecursiveRule) { - // wrap from the beginning of the rule to the StarLoopEntryState - endState = nullptr; - for (ATNState *state : atn->states) { - if (state->ruleIndex != i) { - continue; - } - - if (!StarLoopEntryState::is(state)) { - continue; - } - - ATNState *maybeLoopEndState = state->transitions[state->transitions.size() - 1]->target; - if (!LoopEndState::is(maybeLoopEndState)) { - continue; - } - - if (maybeLoopEndState->epsilonOnlyTransitions && RuleStopState::is(maybeLoopEndState->transitions[0]->target)) { - endState = state; - break; - } - } - - if (endState == nullptr) { - throw UnsupportedOperationException("Couldn't identify final state of the precedence rule prefix section."); - - } - - excludeTransition = (static_cast(endState))->loopBackState->transitions[0].get(); - } else { - endState = atn->ruleToStopState[i]; - } - - // all non-excluded transitions that currently target end state need to target blockEnd instead - for (ATNState *state : atn->states) { - for (auto &transition : state->transitions) { - if (transition.get() == excludeTransition) { - continue; - } - - if (transition->target == endState) { - const_cast(transition.get())->target = bypassStop; - } - } - } - - // all transitions leaving the rule start state need to leave blockStart instead - while (atn->ruleToStartState[i]->transitions.size() > 0) { - ConstTransitionPtr transition = atn->ruleToStartState[i]->removeTransition(atn->ruleToStartState[i]->transitions.size() - 1); - bypassStart->addTransition(std::move(transition)); - } - - // link the new states - atn->ruleToStartState[i]->addTransition(std::make_unique(bypassStart)); - bypassStop->addTransition(std::make_unique(endState)); - - ATNState *matchState = new BasicState(); /* mem check: freed in ATN d-tor */ - atn->addState(matchState); - matchState->addTransition(std::make_unique(bypassStop, atn->ruleToTokenType[i])); - bypassStart->addTransition(std::make_unique(matchState)); - } - - if (_deserializationOptions.isVerifyATN()) { - // reverify after modification - verifyATN(*atn); - } - } - - return atn; -} - -void ATNDeserializer::verifyATN(const ATN &atn) const { - // verify assumptions - for (ATNState *state : atn.states) { - if (state == nullptr) { - continue; - } - - checkCondition(state->epsilonOnlyTransitions || state->transitions.size() <= 1); - - if (PlusBlockStartState::is(state)) { - checkCondition((downCast(state))->loopBackState != nullptr); - } - - if (StarLoopEntryState::is(state)) { - StarLoopEntryState *starLoopEntryState = downCast(state); - checkCondition(starLoopEntryState->loopBackState != nullptr); - checkCondition(starLoopEntryState->transitions.size() == 2); - - if (StarBlockStartState::is(starLoopEntryState->transitions[0]->target)) { - checkCondition(downCast(starLoopEntryState->transitions[1]->target) != nullptr); - checkCondition(!starLoopEntryState->nonGreedy); - } else if (LoopEndState::is(starLoopEntryState->transitions[0]->target)) { - checkCondition(StarBlockStartState::is(starLoopEntryState->transitions[1]->target)); - checkCondition(starLoopEntryState->nonGreedy); - } else { - throw IllegalStateException(); - } - } - - if (StarLoopbackState::is(state)) { - checkCondition(state->transitions.size() == 1); - checkCondition(StarLoopEntryState::is(state->transitions[0]->target)); - } - - if (LoopEndState::is(state)) { - checkCondition((downCast(state))->loopBackState != nullptr); - } - - if (RuleStartState::is(state)) { - checkCondition((downCast(state))->stopState != nullptr); - } - - if (BlockStartState::is(state)) { - checkCondition((downCast(state))->endState != nullptr); - } - - if (BlockEndState::is(state)) { - checkCondition((downCast(state))->startState != nullptr); - } - - if (DecisionState::is(state)) { - DecisionState *decisionState = downCast(state); - checkCondition(decisionState->transitions.size() <= 1 || decisionState->decision >= 0); - } else { - checkCondition(state->transitions.size() <= 1 || RuleStopState::is(state)); - } - } -} diff --git a/src/include/atn/ATNDeserializer.h b/src/include/atn/ATNDeserializer.h deleted file mode 100755 index 9be49159..00000000 --- a/src/include/atn/ATNDeserializer.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNDeserializationOptions.h" -#include "atn/SerializedATNView.h" -#include "atn/LexerAction.h" -#include "atn/Transition.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC ATNDeserializer final { - public: - static constexpr size_t SERIALIZED_VERSION = 4; - - ATNDeserializer(); - - explicit ATNDeserializer(ATNDeserializationOptions deserializationOptions); - - std::unique_ptr deserialize(SerializedATNView input) const; - void verifyATN(const ATN &atn) const; - - private: - const ATNDeserializationOptions _deserializationOptions; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ATNSimulator.cpp b/src/include/atn/ATNSimulator.cpp deleted file mode 100755 index 3abe6882..00000000 --- a/src/include/atn/ATNSimulator.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ATNSimulator.h" - -#include "atn/ATNConfigSet.h" -#include "atn/ATNDeserializer.h" -#include "atn/ATNType.h" -#include "dfa/DFAState.h" - -using namespace antlr4; -using namespace antlr4::dfa; -using namespace antlr4::atn; - -const Ref ATNSimulator::ERROR = std::make_shared(std::numeric_limits::max()); - -ATNSimulator::ATNSimulator(const ATN &atn, PredictionContextCache &sharedContextCache) - : atn(atn), _sharedContextCache(sharedContextCache) {} - -void ATNSimulator::clearDFA() { - throw UnsupportedOperationException("This ATN simulator does not support clearing the DFA."); -} - -PredictionContextCache& ATNSimulator::getSharedContextCache() const { - return _sharedContextCache; -} - -Ref ATNSimulator::getCachedContext(const Ref &context) { - // This function must only be called with an active state lock, as we are going to change a shared structure. - return PredictionContext::getCachedContext(context, getSharedContextCache()); -} diff --git a/src/include/atn/ATNSimulator.h b/src/include/atn/ATNSimulator.h deleted file mode 100755 index 1b0ebf6d..00000000 --- a/src/include/atn/ATNSimulator.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATN.h" -#include "atn/PredictionContext.h" -#include "atn/PredictionContextCache.h" -#include "misc/IntervalSet.h" -#include "support/CPPUtils.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC ATNSimulator { - public: - /// Must distinguish between missing edge and edge we know leads nowhere. - static const Ref ERROR; - const ATN &atn; - - ATNSimulator(const ATN &atn, PredictionContextCache &sharedContextCache); - - virtual ~ATNSimulator() = default; - - virtual void reset() = 0; - - /** - * Clear the DFA cache used by the current instance. Since the DFA cache may - * be shared by multiple ATN simulators, this method may affect the - * performance (but not accuracy) of other parsers which are being used - * concurrently. - * - * @throws UnsupportedOperationException if the current instance does not - * support clearing the DFA. - * - * @since 4.3 - */ - virtual void clearDFA(); - - PredictionContextCache& getSharedContextCache() const; - Ref getCachedContext(const Ref &context); - - protected: - /// - /// The context cache maps all PredictionContext objects that are equals() - /// to a single cached copy. This cache is shared across all contexts - /// in all ATNConfigs in all DFA states. We rebuild each ATNConfigSet - /// to use only cached nodes/graphs in addDFAState(). We don't want to - /// fill this during closure() since there are lots of contexts that - /// pop up but are not used ever again. It also greatly slows down closure(). - ///

- /// This cache makes a huge difference in memory and a little bit in speed. - /// For the Java grammar on java.*, it dropped the memory requirements - /// at the end from 25M to 16M. We don't store any of the full context - /// graphs in the DFA because they are limited to local context only, - /// but apparently there's a lot of repetition there as well. We optimize - /// the config contexts before storing the config set in the DFA states - /// by literally rebuilding them with cached subgraphs only. - ///

- /// I tried a cache for use during closure operations, that was - /// whacked after each adaptivePredict(). It cost a little bit - /// more time I think and doesn't save on the overall footprint - /// so it's not worth the complexity. - ///

- PredictionContextCache &_sharedContextCache; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ATNState.cpp b/src/include/atn/ATNState.cpp deleted file mode 100755 index 43deb258..00000000 --- a/src/include/atn/ATNState.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ATN.h" -#include "atn/Transition.h" -#include "misc/IntervalSet.h" -#include "support/CPPUtils.h" - -#include "atn/ATNState.h" - -using namespace antlr4::atn; -using namespace antlrcpp; - -size_t ATNState::hashCode() const { - return stateNumber; -} - -bool ATNState::equals(const ATNState &other) const { - return stateNumber == other.stateNumber; -} - -bool ATNState::isNonGreedyExitState() const { - return false; -} - -std::string ATNState::toString() const { - return std::to_string(stateNumber); -} - -void ATNState::addTransition(ConstTransitionPtr e) { - addTransition(transitions.size(), std::move(e)); -} - -void ATNState::addTransition(size_t index, ConstTransitionPtr e) { - for (const auto &transition : transitions) - if (transition->target->stateNumber == e->target->stateNumber) { - return; - } - - if (transitions.empty()) { - epsilonOnlyTransitions = e->isEpsilon(); - } else if (epsilonOnlyTransitions != e->isEpsilon()) { - std::cerr << "ATN state %d has both epsilon and non-epsilon transitions.\n" << stateNumber; - epsilonOnlyTransitions = false; - } - - transitions.insert(transitions.begin() + index, std::move(e)); -} - -ConstTransitionPtr ATNState::removeTransition(size_t index) { - ConstTransitionPtr result = std::move(transitions[index]); - transitions.erase(transitions.begin() + index); - return result; -} diff --git a/src/include/atn/ATNState.h b/src/include/atn/ATNState.h deleted file mode 100755 index 8b3f118e..00000000 --- a/src/include/atn/ATNState.h +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "misc/IntervalSet.h" -#include "atn/Transition.h" -#include "atn/ATNStateType.h" - -namespace antlr4 { -namespace atn { - - /// - /// The following images show the relation of states and - /// for various grammar constructs. - /// - ///
    - /// - ///
  • Solid edges marked with an ε indicate a required - /// .
  • - /// - ///
  • Dashed edges indicate locations where any transition derived from - /// might appear.
  • - /// - ///
  • Dashed nodes are place holders for either a sequence of linked - /// states or the inclusion of a block representing a nested - /// construct in one of the forms below.
  • - /// - ///
  • Nodes showing multiple outgoing alternatives with a {@code ...} support - /// any number of alternatives (one or more). Nodes without the {@code ...} only - /// support the exact number of alternatives shown in the diagram.
  • - /// - ///
- /// - ///

Basic Blocks

- /// - ///

Rule

- /// - /// - /// - ///

Block of 1 or more alternatives

- /// - /// - /// - ///

Greedy Loops

- /// - ///

Greedy Closure: {@code (...)*}

- /// - /// - /// - ///

Greedy Positive Closure: {@code (...)+}

- /// - /// - /// - ///

Greedy Optional: {@code (...)?}

- /// - /// - /// - ///

Non-Greedy Loops

- /// - ///

Non-Greedy Closure: {@code (...)*?}

- /// - /// - /// - ///

Non-Greedy Positive Closure: {@code (...)+?}

- /// - /// - /// - ///

Non-Greedy Optional: {@code (...)??}

- /// - /// - ///
- -// GCC generates a warning here if ATN has already been declared due to the -// attributes added by ANTLR4CPP_PUBLIC. -// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39159 -// Only forward-declare if it hasn't already been declared. -#ifndef ANTLR4CPP_ATN_DECLARED - class ANTLR4CPP_PUBLIC ATN; -#endif - - class ANTLR4CPP_PUBLIC ATNState { - public: - static constexpr size_t INITIAL_NUM_TRANSITIONS = 4; - static constexpr size_t INVALID_STATE_NUMBER = std::numeric_limits::max(); - - size_t stateNumber = INVALID_STATE_NUMBER; - size_t ruleIndex = 0; // at runtime, we don't have Rule objects - bool epsilonOnlyTransitions = false; - - /// Track the transitions emanating from this ATN state. - std::vector transitions; - - ATNState() = delete; - - ATNState(ATNState const&) = delete; - - ATNState(ATNState&&) = delete; - - virtual ~ATNState() = default; - - ATNState& operator=(ATNState const&) = delete; - - ATNState& operator=(ATNState&&) = delete; - - void addTransition(ConstTransitionPtr e); - void addTransition(size_t index, ConstTransitionPtr e); - ConstTransitionPtr removeTransition(size_t index); - - virtual size_t hashCode() const; - virtual bool equals(const ATNState &other) const; - - virtual bool isNonGreedyExitState() const; - virtual std::string toString() const; - - ATNStateType getStateType() const { return _stateType; } - - protected: - explicit ATNState(ATNStateType stateType) : _stateType(stateType) {} - - private: - /// Used to cache lookahead during parsing, not used during construction. - - misc::IntervalSet _nextTokenWithinRule; - std::atomic _nextTokenUpdated { false }; - - const ATNStateType _stateType; - - friend class ATN; - }; - - inline bool operator==(const ATNState &lhs, const ATNState &rhs) { return lhs.equals(rhs); } - - inline bool operator!=(const ATNState &lhs, const ATNState &rhs) { return !operator==(lhs, rhs); } - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ATNStateType.cpp b/src/include/atn/ATNStateType.cpp deleted file mode 100644 index 577e2af8..00000000 --- a/src/include/atn/ATNStateType.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "atn/ATNStateType.h" - -std::string antlr4::atn::atnStateTypeName(ATNStateType atnStateType) { - switch (atnStateType) { - case ATNStateType::INVALID: - return "INVALID"; - case ATNStateType::BASIC: - return "BASIC"; - case ATNStateType::RULE_START: - return "RULE_START"; - case ATNStateType::BLOCK_START: - return "BLOCK_START"; - case ATNStateType::PLUS_BLOCK_START: - return "PLUS_BLOCK_START"; - case ATNStateType::STAR_BLOCK_START: - return "STAR_BLOCK_START"; - case ATNStateType::TOKEN_START: - return "TOKEN_START"; - case ATNStateType::RULE_STOP: - return "RULE_STOP"; - case ATNStateType::BLOCK_END: - return "BLOCK_END"; - case ATNStateType::STAR_LOOP_BACK: - return "STAR_LOOP_BACK"; - case ATNStateType::STAR_LOOP_ENTRY: - return "STAR_LOOP_ENTRY"; - case ATNStateType::PLUS_LOOP_BACK: - return "PLUS_LOOP_BACK"; - case ATNStateType::LOOP_END: - return "LOOP_END"; - } - return "UNKNOWN"; -} diff --git a/src/include/atn/ATNStateType.h b/src/include/atn/ATNStateType.h deleted file mode 100644 index e19b2cce..00000000 --- a/src/include/atn/ATNStateType.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include -#include - -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - - // Constants for ATNState serialization. - enum class ATNStateType : size_t { - INVALID = 0, - BASIC = 1, - RULE_START = 2, - BLOCK_START = 3, - PLUS_BLOCK_START = 4, - STAR_BLOCK_START = 5, - TOKEN_START = 6, - RULE_STOP = 7, - BLOCK_END = 8, - STAR_LOOP_BACK = 9, - STAR_LOOP_ENTRY = 10, - PLUS_LOOP_BACK = 11, - LOOP_END = 12, - }; - - ANTLR4CPP_PUBLIC std::string atnStateTypeName(ATNStateType atnStateType); - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ATNType.h b/src/include/atn/ATNType.h deleted file mode 100755 index 19ed7a66..00000000 --- a/src/include/atn/ATNType.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - - /// Represents the type of recognizer an ATN applies to. - enum class ATNType { - LEXER = 0, - PARSER = 1, - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ActionTransition.cpp b/src/include/atn/ActionTransition.cpp deleted file mode 100755 index 45930c42..00000000 --- a/src/include/atn/ActionTransition.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ActionTransition.h" - -using namespace antlr4::atn; - -ActionTransition::ActionTransition(ATNState *target, size_t ruleIndex) - : Transition(TransitionType::ACTION, target), ruleIndex(ruleIndex), actionIndex(INVALID_INDEX), isCtxDependent(false) { -} - -ActionTransition::ActionTransition(ATNState *target, size_t ruleIndex, size_t actionIndex, bool isCtxDependent) - : Transition(TransitionType::ACTION, target), ruleIndex(ruleIndex), actionIndex(actionIndex), isCtxDependent(isCtxDependent) { -} - -bool ActionTransition::isEpsilon() const { - return true; // we are to be ignored by analysis 'cept for predicates -} - -bool ActionTransition::matches(size_t /*symbol*/, size_t /*minVocabSymbol*/, size_t /*maxVocabSymbol*/) const { - return false; -} - -std::string ActionTransition::toString() const { - return " ACTION " + Transition::toString() + " { ruleIndex: " + std::to_string(ruleIndex) + ", actionIndex: " + - std::to_string(actionIndex) + ", isCtxDependent: " + std::to_string(isCtxDependent) + " }"; -} diff --git a/src/include/atn/ActionTransition.h b/src/include/atn/ActionTransition.h deleted file mode 100755 index 0c6b9afc..00000000 --- a/src/include/atn/ActionTransition.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/Transition.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC ActionTransition final : public Transition { - public: - static bool is(const Transition &transition) { return transition.getTransitionType() == TransitionType::ACTION; } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - const size_t ruleIndex; - const size_t actionIndex; - const bool isCtxDependent; // e.g., $i ref in action - - ActionTransition(ATNState *target, size_t ruleIndex); - - ActionTransition(ATNState *target, size_t ruleIndex, size_t actionIndex, bool isCtxDependent); - - virtual bool isEpsilon() const override; - - virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - - virtual std::string toString() const override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/AmbiguityInfo.cpp b/src/include/atn/AmbiguityInfo.cpp deleted file mode 100755 index 72ce9226..00000000 --- a/src/include/atn/AmbiguityInfo.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/AmbiguityInfo.h" - -using namespace antlr4; -using namespace antlr4::atn; - -AmbiguityInfo::AmbiguityInfo(size_t decision, ATNConfigSet *configs, const antlrcpp::BitSet &ambigAlts, - TokenStream *input, size_t startIndex, size_t stopIndex, bool fullCtx) - : DecisionEventInfo(decision, configs, input, startIndex, stopIndex, fullCtx) { - - this->ambigAlts = ambigAlts; -} diff --git a/src/include/atn/AmbiguityInfo.h b/src/include/atn/AmbiguityInfo.h deleted file mode 100755 index db594a1f..00000000 --- a/src/include/atn/AmbiguityInfo.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionEventInfo.h" -#include "support/BitSet.h" - -namespace antlr4 { -namespace atn { - - /// - /// This class represents profiling event information for an ambiguity. - /// Ambiguities are decisions where a particular input resulted in an SLL - /// conflict, followed by LL prediction also reaching a conflict state - /// (indicating a true ambiguity in the grammar). - /// - /// - /// This event may be reported during SLL prediction in cases where the - /// conflicting SLL configuration set provides sufficient information to - /// determine that the SLL conflict is truly an ambiguity. For example, if none - /// of the ATN configurations in the conflicting SLL configuration set have - /// traversed a global follow transition (i.e. - /// is 0 for all configurations), then - /// the result of SLL prediction for that input is known to be equivalent to the - /// result of LL prediction for that input. - /// - /// - /// In some cases, the minimum represented alternative in the conflicting LL - /// configuration set is not equal to the minimum represented alternative in the - /// conflicting SLL configuration set. Grammars and inputs which result in this - /// scenario are unable to use , which in turn means - /// they cannot use the two-stage parsing strategy to improve parsing performance - /// for that input. - /// - /// - /// - class ANTLR4CPP_PUBLIC AmbiguityInfo : public DecisionEventInfo { - public: - /// The set of alternative numbers for this decision event that lead to a valid parse. - antlrcpp::BitSet ambigAlts; - - /// - /// Constructs a new instance of the class with the - /// specified detailed ambiguity information. - /// - /// The decision number - /// The final configuration set identifying the ambiguous - /// alternatives for the current input - /// The set of alternatives in the decision that lead to a valid parse. - /// The predicted alt is the min(ambigAlts) - /// The input token stream - /// The start index for the current prediction - /// The index at which the ambiguity was identified during - /// prediction - /// {@code true} if the ambiguity was identified during LL - /// prediction; otherwise, {@code false} if the ambiguity was identified - /// during SLL prediction - AmbiguityInfo(size_t decision, ATNConfigSet *configs, const antlrcpp::BitSet &ambigAlts, TokenStream *input, - size_t startIndex, size_t stopIndex, bool fullCtx); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ArrayPredictionContext.cpp b/src/include/atn/ArrayPredictionContext.cpp deleted file mode 100755 index 70dfa15a..00000000 --- a/src/include/atn/ArrayPredictionContext.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ArrayPredictionContext.h" - -#include - -#include "atn/SingletonPredictionContext.h" -#include "atn/HashUtils.h" -#include "misc/MurmurHash.h" -#include "support/Casts.h" - -using namespace antlr4::atn; -using namespace antlr4::misc; -using namespace antlrcpp; - -namespace { - - bool predictionContextEqual(const Ref &lhs, const Ref &rhs) { - // parent PredictionContext pointers can be null during full context mode and - // the ctxs are in an ArrayPredictionContext. If both are null, return true - // if just one is null, return false. If both are non-null, do comparison. - if ( lhs == nullptr ) return rhs == nullptr; - if ( rhs == nullptr ) return false; // lhs!=null and rhs==null - return *lhs == *rhs; // both nonnull - } - -} - -ArrayPredictionContext::ArrayPredictionContext(const SingletonPredictionContext &predictionContext) - : ArrayPredictionContext({ predictionContext.parent }, { predictionContext.returnState }) {} - -ArrayPredictionContext::ArrayPredictionContext(std::vector> parents, - std::vector returnStates) - : PredictionContext(PredictionContextType::ARRAY), parents(std::move(parents)), returnStates(std::move(returnStates)) { - assert(this->parents.size() > 0); - assert(this->returnStates.size() > 0); - assert(this->parents.size() == this->returnStates.size()); -} - -bool ArrayPredictionContext::isEmpty() const { - // Since EMPTY_RETURN_STATE can only appear in the last position, we don't need to verify that size == 1. - return returnStates[0] == EMPTY_RETURN_STATE; -} - -size_t ArrayPredictionContext::size() const { - return returnStates.size(); -} - -const Ref& ArrayPredictionContext::getParent(size_t index) const { - return parents[index]; -} - -size_t ArrayPredictionContext::getReturnState(size_t index) const { - return returnStates[index]; -} - -size_t ArrayPredictionContext::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getContextType())); - for (const auto &parent : parents) { - hash = MurmurHash::update(hash, parent); - } - for (const auto &returnState : returnStates) { - hash = MurmurHash::update(hash, returnState); - } - return MurmurHash::finish(hash, 1 + parents.size() + returnStates.size()); -} - -bool ArrayPredictionContext::equals(const PredictionContext &other) const { - if (this == std::addressof(other)) { - return true; - } - if (getContextType() != other.getContextType()) { - return false; - } - const auto &array = downCast(other); - const bool sameSize = returnStates.size() == array.returnStates.size() && - parents.size() == array.parents.size(); - if ( !sameSize ) { - return false; - } - - const bool sameHash = cachedHashCodeEqual(cachedHashCode(), array.cachedHashCode()); - if ( !sameHash ) { - return false; - } - - const size_t stateSizeBytes = sizeof(decltype(returnStates)::value_type); - const bool returnStateArraysEqual = - std::memcmp(returnStates.data(), array.returnStates.data(), - returnStates.size() * stateSizeBytes) == 0; - if ( !returnStateArraysEqual ) { - return false; - } - - // stack of contexts is the same - const bool parentCtxEqual = - std::equal(parents.begin(), parents.end(), array.parents.begin(), predictionContextEqual); - return parentCtxEqual; -} - -std::string ArrayPredictionContext::toString() const { - if (isEmpty()) { - return "[]"; - } - - std::stringstream ss; - ss << "["; - for (size_t i = 0; i < returnStates.size(); i++) { - if (i > 0) { - ss << ", "; - } - if (returnStates[i] == EMPTY_RETURN_STATE) { - ss << "$"; - continue; - } - ss << returnStates[i]; - if (parents[i] != nullptr) { - ss << " " << parents[i]->toString(); - } else { - ss << "nul"; - } - } - ss << "]"; - return ss.str(); -} diff --git a/src/include/atn/ArrayPredictionContext.h b/src/include/atn/ArrayPredictionContext.h deleted file mode 100755 index adc2ca4c..00000000 --- a/src/include/atn/ArrayPredictionContext.h +++ /dev/null @@ -1,51 +0,0 @@ - -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/PredictionContext.h" - -namespace antlr4 { -namespace atn { - - class SingletonPredictionContext; - - class ANTLR4CPP_PUBLIC ArrayPredictionContext final : public PredictionContext { - public: - static bool is(const PredictionContext &predictionContext) { return predictionContext.getContextType() == PredictionContextType::ARRAY; } - - static bool is(const PredictionContext *predictionContext) { return predictionContext != nullptr && is(*predictionContext); } - - /// Parent can be empty only if full ctx mode and we make an array - /// from EMPTY and non-empty. We merge EMPTY by using null parent and - /// returnState == EMPTY_RETURN_STATE. - // Also here: we use a strong reference to our parents to avoid having them freed prematurely. - // See also SinglePredictionContext. - std::vector> parents; - - /// Sorted for merge, no duplicates; if present, EMPTY_RETURN_STATE is always last. - std::vector returnStates; - - explicit ArrayPredictionContext(const SingletonPredictionContext &predictionContext); - - ArrayPredictionContext(std::vector> parents, std::vector returnStates); - - ArrayPredictionContext(ArrayPredictionContext&&) = default; - - bool isEmpty() const override; - size_t size() const override; - const Ref& getParent(size_t index) const override; - size_t getReturnState(size_t index) const override; - bool equals(const PredictionContext &other) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - }; - -} // namespace atn -} // namespace antlr4 - diff --git a/src/include/atn/AtomTransition.cpp b/src/include/atn/AtomTransition.cpp deleted file mode 100755 index 4424980c..00000000 --- a/src/include/atn/AtomTransition.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/IntervalSet.h" -#include "atn/Transition.h" - -#include "atn/AtomTransition.h" - -using namespace antlr4::misc; -using namespace antlr4::atn; - -AtomTransition::AtomTransition(ATNState *target, size_t label) : Transition(TransitionType::ATOM, target), _label(label) { -} - -IntervalSet AtomTransition::label() const { - return IntervalSet::of((int)_label); -} - -bool AtomTransition::matches(size_t symbol, size_t /*minVocabSymbol*/, size_t /*maxVocabSymbol*/) const { - return _label == symbol; -} - -std::string AtomTransition::toString() const { - return "ATOM " + Transition::toString() + " { label: " + std::to_string(_label) + " }"; -} diff --git a/src/include/atn/AtomTransition.h b/src/include/atn/AtomTransition.h deleted file mode 100755 index db62a7fe..00000000 --- a/src/include/atn/AtomTransition.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/Transition.h" - -namespace antlr4 { -namespace atn { - - /// TODO: make all transitions sets? no, should remove set edges. - class ANTLR4CPP_PUBLIC AtomTransition final : public Transition { - public: - static bool is(const Transition &transition) { return transition.getTransitionType() == TransitionType::ATOM; } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - /// The token type or character value; or, signifies special label. - /// TODO: rename this to label - const size_t _label; - - AtomTransition(ATNState *target, size_t label); - - virtual misc::IntervalSet label() const override; - virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - - virtual std::string toString() const override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/BasicBlockStartState.h b/src/include/atn/BasicBlockStartState.h deleted file mode 100755 index c5a588fb..00000000 --- a/src/include/atn/BasicBlockStartState.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" -#include "atn/BlockStartState.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC BasicBlockStartState final : public BlockStartState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::BLOCK_START; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - BasicBlockStartState() : BlockStartState(ATNStateType::BLOCK_START) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/BasicState.h b/src/include/atn/BasicState.h deleted file mode 100755 index 311a966e..00000000 --- a/src/include/atn/BasicState.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNState.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC BasicState final : public ATNState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::BASIC; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - BasicState() : ATNState(ATNStateType::BASIC) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/BlockEndState.h b/src/include/atn/BlockEndState.h deleted file mode 100755 index a3e06710..00000000 --- a/src/include/atn/BlockEndState.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNState.h" - -namespace antlr4 { -namespace atn { - - /// Terminal node of a simple {@code (a|b|c)} block. - class ANTLR4CPP_PUBLIC BlockEndState final : public ATNState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::BLOCK_END; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - BlockStartState *startState = nullptr; - - BlockEndState() : ATNState(ATNStateType::BLOCK_END) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/BlockStartState.h b/src/include/atn/BlockStartState.h deleted file mode 100755 index 1e4006ae..00000000 --- a/src/include/atn/BlockStartState.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionState.h" - -namespace antlr4 { -namespace atn { - - /// The start of a regular {@code (...)} block. - class ANTLR4CPP_PUBLIC BlockStartState : public DecisionState { - public: - static bool is(const ATNState &atnState) { - const auto stateType = atnState.getStateType(); - return stateType >= ATNStateType::BLOCK_START && stateType <= ATNStateType::STAR_BLOCK_START; - } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - BlockEndState *endState = nullptr; - - protected: - using DecisionState::DecisionState; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ContextSensitivityInfo.cpp b/src/include/atn/ContextSensitivityInfo.cpp deleted file mode 100755 index 12442a9b..00000000 --- a/src/include/atn/ContextSensitivityInfo.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ContextSensitivityInfo.h" - -using namespace antlr4; -using namespace antlr4::atn; - -ContextSensitivityInfo::ContextSensitivityInfo(size_t decision, ATNConfigSet *configs, TokenStream *input, - size_t startIndex, size_t stopIndex) - : DecisionEventInfo(decision, configs, input, startIndex, stopIndex, true) { -} diff --git a/src/include/atn/ContextSensitivityInfo.h b/src/include/atn/ContextSensitivityInfo.h deleted file mode 100755 index 430ce3b6..00000000 --- a/src/include/atn/ContextSensitivityInfo.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionEventInfo.h" - -namespace antlr4 { -namespace atn { - - /// - /// This class represents profiling event information for a context sensitivity. - /// Context sensitivities are decisions where a particular input resulted in an - /// SLL conflict, but LL prediction produced a single unique alternative. - /// - /// - /// In some cases, the unique alternative identified by LL prediction is not - /// equal to the minimum represented alternative in the conflicting SLL - /// configuration set. Grammars and inputs which result in this scenario are - /// unable to use , which in turn means they cannot use - /// the two-stage parsing strategy to improve parsing performance for that - /// input. - /// - /// - /// - class ANTLR4CPP_PUBLIC ContextSensitivityInfo : public DecisionEventInfo { - public: - /// - /// Constructs a new instance of the class - /// with the specified detailed context sensitivity information. - /// - /// The decision number - /// The final configuration set containing the unique - /// alternative identified by full-context prediction - /// The input token stream - /// The start index for the current prediction - /// The index at which the context sensitivity was - /// identified during full-context prediction - ContextSensitivityInfo(size_t decision, ATNConfigSet *configs, TokenStream *input, size_t startIndex, size_t stopIndex); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/DecisionEventInfo.cpp b/src/include/atn/DecisionEventInfo.cpp deleted file mode 100755 index bca6c778..00000000 --- a/src/include/atn/DecisionEventInfo.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/DecisionEventInfo.h" - -using namespace antlr4; -using namespace antlr4::atn; - -DecisionEventInfo::DecisionEventInfo(size_t decision, ATNConfigSet *configs, TokenStream *input, size_t startIndex, - size_t stopIndex, bool fullCtx) - : decision(decision), configs(configs), input(input), startIndex(startIndex), stopIndex(stopIndex), fullCtx(fullCtx) { -} diff --git a/src/include/atn/DecisionEventInfo.h b/src/include/atn/DecisionEventInfo.h deleted file mode 100755 index af7f5f4b..00000000 --- a/src/include/atn/DecisionEventInfo.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - - /// - /// This is the base class for gathering detailed information about prediction - /// events which occur during parsing. - /// - /// Note that we could record the parser call stack at the time this event - /// occurred but in the presence of left recursive rules, the stack is kind of - /// meaningless. It's better to look at the individual configurations for their - /// individual stacks. Of course that is a object - /// not a parse tree node and so it does not have information about the extent - /// (start...stop) of the various subtrees. Examining the stack tops of all - /// configurations provide the return states for the rule invocations. - /// From there you can get the enclosing rule. - /// - /// @since 4.3 - /// - class ANTLR4CPP_PUBLIC DecisionEventInfo { - public: - /// - /// The invoked decision number which this event is related to. - /// - /// - const size_t decision; - - /// - /// The configuration set containing additional information relevant to the - /// prediction state when the current event occurred, or {@code null} if no - /// additional information is relevant or available. - /// - const ATNConfigSet *configs; - - /// - /// The input token stream which is being parsed. - /// - const TokenStream *input; - - /// - /// The token index in the input stream at which the current prediction was - /// originally invoked. - /// - const size_t startIndex; - - /// - /// The token index in the input stream at which the current event occurred. - /// - const size_t stopIndex; - - /// - /// {@code true} if the current event occurred during LL prediction; - /// otherwise, {@code false} if the input occurred during SLL prediction. - /// - const bool fullCtx; - - DecisionEventInfo(size_t decision, ATNConfigSet *configs, TokenStream *input, size_t startIndex, - size_t stopIndex, bool fullCtx); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/DecisionInfo.cpp b/src/include/atn/DecisionInfo.cpp deleted file mode 100755 index ee9b1aac..00000000 --- a/src/include/atn/DecisionInfo.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ErrorInfo.h" -#include "atn/LookaheadEventInfo.h" - -#include "atn/DecisionInfo.h" - -using namespace antlr4::atn; - -DecisionInfo::DecisionInfo(size_t decision) : decision(decision) { -} - -std::string DecisionInfo::toString() const { - std::stringstream ss; - - ss << "{decision=" << decision << ", contextSensitivities=" << contextSensitivities.size() << ", errors="; - ss << errors.size() << ", ambiguities=" << ambiguities.size() << ", SLL_lookahead=" << SLL_TotalLook; - ss << ", SLL_ATNTransitions=" << SLL_ATNTransitions << ", SLL_DFATransitions=" << SLL_DFATransitions; - ss << ", LL_Fallback=" << LL_Fallback << ", LL_lookahead=" << LL_TotalLook << ", LL_ATNTransitions=" << LL_ATNTransitions << '}'; - - return ss.str(); -} diff --git a/src/include/atn/DecisionInfo.h b/src/include/atn/DecisionInfo.h deleted file mode 100755 index 2b43ad8b..00000000 --- a/src/include/atn/DecisionInfo.h +++ /dev/null @@ -1,227 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ContextSensitivityInfo.h" -#include "atn/AmbiguityInfo.h" -#include "atn/PredicateEvalInfo.h" -#include "atn/ErrorInfo.h" - -namespace antlr4 { -namespace atn { - - class LookaheadEventInfo; - - /// - /// This class contains profiling gathered for a particular decision. - /// - /// - /// Parsing performance in ANTLR 4 is heavily influenced by both static factors - /// (e.g. the form of the rules in the grammar) and dynamic factors (e.g. the - /// choice of input and the state of the DFA cache at the time profiling - /// operations are started). For best results, gather and use aggregate - /// statistics from a large sample of inputs representing the inputs expected in - /// production before using the results to make changes in the grammar. - /// - /// @since 4.3 - /// - class ANTLR4CPP_PUBLIC DecisionInfo { - public: - /// - /// The decision number, which is an index into . - /// - const size_t decision; - - /// - /// The total number of times was - /// invoked for this decision. - /// - long long invocations = 0; - - /// - /// The total time spent in for - /// this decision, in nanoseconds. - /// - /// - /// The value of this field contains the sum of differential results obtained - /// by , and is not adjusted to compensate for JIT - /// and/or garbage collection overhead. For best accuracy, use a modern JVM - /// implementation that provides precise results from - /// , and perform profiling in a separate process - /// which is warmed up by parsing the input prior to profiling. If desired, - /// call to reset the DFA cache to its initial - /// state before starting the profiling measurement pass. - /// - long long timeInPrediction = 0; - - /// - /// The sum of the lookahead required for SLL prediction for this decision. - /// Note that SLL prediction is used before LL prediction for performance - /// reasons even when or - /// is used. - /// - long long SLL_TotalLook = 0; - - /// - /// Gets the minimum lookahead required for any single SLL prediction to - /// complete for this decision, by reaching a unique prediction, reaching an - /// SLL conflict state, or encountering a syntax error. - /// - long long SLL_MinLook = 0; - - /// - /// Gets the maximum lookahead required for any single SLL prediction to - /// complete for this decision, by reaching a unique prediction, reaching an - /// SLL conflict state, or encountering a syntax error. - /// - long long SLL_MaxLook = 0; - - /// Gets the associated with the event where the - /// value was set. - Ref SLL_MaxLookEvent; - - /// - /// The sum of the lookahead required for LL prediction for this decision. - /// Note that LL prediction is only used when SLL prediction reaches a - /// conflict state. - /// - long long LL_TotalLook = 0; - - /// - /// Gets the minimum lookahead required for any single LL prediction to - /// complete for this decision. An LL prediction completes when the algorithm - /// reaches a unique prediction, a conflict state (for - /// , an ambiguity state (for - /// , or a syntax error. - /// - long long LL_MinLook = 0; - - /// - /// Gets the maximum lookahead required for any single LL prediction to - /// complete for this decision. An LL prediction completes when the algorithm - /// reaches a unique prediction, a conflict state (for - /// , an ambiguity state (for - /// , or a syntax error. - /// - long long LL_MaxLook = 0; - - /// - /// Gets the associated with the event where the - /// value was set. - /// - Ref LL_MaxLookEvent; - - /// - /// A collection of instances describing the - /// context sensitivities encountered during LL prediction for this decision. - /// - /// - std::vector contextSensitivities; - - /// - /// A collection of instances describing the parse errors - /// identified during calls to for - /// this decision. - /// - /// - std::vector errors; - - /// - /// A collection of instances describing the - /// ambiguities encountered during LL prediction for this decision. - /// - /// - std::vector ambiguities; - - /// - /// A collection of instances describing the - /// results of evaluating individual predicates during prediction for this - /// decision. - /// - /// - std::vector predicateEvals; - - /// - /// The total number of ATN transitions required during SLL prediction for - /// this decision. An ATN transition is determined by the number of times the - /// DFA does not contain an edge that is required for prediction, resulting - /// in on-the-fly computation of that edge. - /// - /// - /// If DFA caching of SLL transitions is employed by the implementation, ATN - /// computation may cache the computed edge for efficient lookup during - /// future parsing of this decision. Otherwise, the SLL parsing algorithm - /// will use ATN transitions exclusively. - /// - /// - /// - /// - long long SLL_ATNTransitions = 0; - - /// - /// The total number of DFA transitions required during SLL prediction for - /// this decision. - /// - /// If the ATN simulator implementation does not use DFA caching for SLL - /// transitions, this value will be 0. - /// - /// - /// - long long SLL_DFATransitions = 0; - - /// - /// Gets the total number of times SLL prediction completed in a conflict - /// state, resulting in fallback to LL prediction. - /// - /// Note that this value is not related to whether or not - /// may be used successfully with a particular - /// grammar. If the ambiguity resolution algorithm applied to the SLL - /// conflicts for this decision produce the same result as LL prediction for - /// this decision, would produce the same overall - /// parsing result as . - /// - long long LL_Fallback = 0; - - /// - /// The total number of ATN transitions required during LL prediction for - /// this decision. An ATN transition is determined by the number of times the - /// DFA does not contain an edge that is required for prediction, resulting - /// in on-the-fly computation of that edge. - /// - /// - /// If DFA caching of LL transitions is employed by the implementation, ATN - /// computation may cache the computed edge for efficient lookup during - /// future parsing of this decision. Otherwise, the LL parsing algorithm will - /// use ATN transitions exclusively. - /// - /// - /// - /// - long long LL_ATNTransitions = 0; - - /// - /// The total number of DFA transitions required during LL prediction for - /// this decision. - /// - /// If the ATN simulator implementation does not use DFA caching for LL - /// transitions, this value will be 0. - /// - /// - /// - long long LL_DFATransitions = 0; - - /// - /// Constructs a new instance of the class to contain - /// statistics for a particular decision. - /// - /// The decision number - explicit DecisionInfo(size_t decision); - - std::string toString() const; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/DecisionState.cpp b/src/include/atn/DecisionState.cpp deleted file mode 100755 index 7ec3a9b3..00000000 --- a/src/include/atn/DecisionState.cpp +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/DecisionState.h" - -using namespace antlr4::atn; - -std::string DecisionState::toString() const { - return ATNState::toString(); -} diff --git a/src/include/atn/DecisionState.h b/src/include/atn/DecisionState.h deleted file mode 100755 index f26ad07c..00000000 --- a/src/include/atn/DecisionState.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNState.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC DecisionState : public ATNState { - public: - static bool is(const ATNState &atnState) { - const auto stateType = atnState.getStateType(); - return (stateType >= ATNStateType::BLOCK_START && stateType <= ATNStateType::TOKEN_START) || - stateType == ATNStateType::PLUS_LOOP_BACK || - stateType == ATNStateType::STAR_LOOP_ENTRY; - } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - int decision = -1; - bool nonGreedy = false; - - virtual std::string toString() const override; - - protected: - using ATNState::ATNState; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/EpsilonTransition.cpp b/src/include/atn/EpsilonTransition.cpp deleted file mode 100755 index 1dba8017..00000000 --- a/src/include/atn/EpsilonTransition.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/EpsilonTransition.h" - -using namespace antlr4::atn; - -EpsilonTransition::EpsilonTransition(ATNState *target) : EpsilonTransition(target, INVALID_INDEX) { -} - -EpsilonTransition::EpsilonTransition(ATNState *target, size_t outermostPrecedenceReturn) - : Transition(TransitionType::EPSILON, target), _outermostPrecedenceReturn(outermostPrecedenceReturn) { -} - -size_t EpsilonTransition::outermostPrecedenceReturn() const { - return _outermostPrecedenceReturn; -} - -bool EpsilonTransition::isEpsilon() const { - return true; -} - -bool EpsilonTransition::matches(size_t /*symbol*/, size_t /*minVocabSymbol*/, size_t /*maxVocabSymbol*/) const { - return false; -} - -std::string EpsilonTransition::toString() const { - return "EPSILON " + Transition::toString() + " {}"; -} diff --git a/src/include/atn/EpsilonTransition.h b/src/include/atn/EpsilonTransition.h deleted file mode 100755 index 2cc9cf0b..00000000 --- a/src/include/atn/EpsilonTransition.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/Transition.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC EpsilonTransition final : public Transition { - public: - static bool is(const Transition &transition) { return transition.getTransitionType() == TransitionType::EPSILON; } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - explicit EpsilonTransition(ATNState *target); - EpsilonTransition(ATNState *target, size_t outermostPrecedenceReturn); - - /** - * @return the rule index of a precedence rule for which this transition is - * returning from, where the precedence value is 0; otherwise, INVALID_INDEX. - * - * @see ATNConfig#isPrecedenceFilterSuppressed() - * @see ParserATNSimulator#applyPrecedenceFilter(ATNConfigSet) - * @since 4.4.1 - */ - size_t outermostPrecedenceReturn() const; - - virtual bool isEpsilon() const override; - virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - - virtual std::string toString() const override; - - private: - const size_t _outermostPrecedenceReturn; // A rule index. - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ErrorInfo.cpp b/src/include/atn/ErrorInfo.cpp deleted file mode 100755 index efe85071..00000000 --- a/src/include/atn/ErrorInfo.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ATNConfigSet.h" - -#include "atn/ErrorInfo.h" - -using namespace antlr4; -using namespace antlr4::atn; - -ErrorInfo::ErrorInfo(size_t decision, ATNConfigSet *configs, TokenStream *input, size_t startIndex, size_t stopIndex, bool fullCtx) - : DecisionEventInfo(decision, configs, input, startIndex, stopIndex, fullCtx) { -} diff --git a/src/include/atn/ErrorInfo.h b/src/include/atn/ErrorInfo.h deleted file mode 100755 index d34642a1..00000000 --- a/src/include/atn/ErrorInfo.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionEventInfo.h" - -namespace antlr4 { -namespace atn { - - /// - /// This class represents profiling event information for a syntax error - /// identified during prediction. Syntax errors occur when the prediction - /// algorithm is unable to identify an alternative which would lead to a - /// successful parse. - /// - /// - /// - class ANTLR4CPP_PUBLIC ErrorInfo : public DecisionEventInfo { - public: - /// - /// Constructs a new instance of the class with the - /// specified detailed syntax error information. - /// - /// The decision number - /// The final configuration set reached during prediction - /// prior to reaching the state - /// The input token stream - /// The start index for the current prediction - /// The index at which the syntax error was identified - /// {@code true} if the syntax error was identified during LL - /// prediction; otherwise, {@code false} if the syntax error was identified - /// during SLL prediction - ErrorInfo(size_t decision, ATNConfigSet *configs, TokenStream *input, size_t startIndex, size_t stopIndex, - bool fullCtx); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/HashUtils.h b/src/include/atn/HashUtils.h deleted file mode 100644 index 690d2048..00000000 --- a/src/include/atn/HashUtils.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (c) 2022 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include - -namespace antlr4 { -namespace atn { - - inline bool cachedHashCodeEqual(size_t lhs, size_t rhs) { - return lhs == rhs || lhs == 0 || rhs == 0; - } - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LL1Analyzer.cpp b/src/include/atn/LL1Analyzer.cpp deleted file mode 100755 index 1e6da892..00000000 --- a/src/include/atn/LL1Analyzer.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/RuleStopState.h" -#include "atn/Transition.h" -#include "atn/RuleTransition.h" -#include "atn/SingletonPredictionContext.h" -#include "atn/WildcardTransition.h" -#include "atn/NotSetTransition.h" -#include "misc/IntervalSet.h" -#include "atn/ATNConfig.h" - -#include "support/CPPUtils.h" - -#include "atn/LL1Analyzer.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlrcpp; - -namespace { - - struct ATNConfigHasher final { - size_t operator()(const ATNConfig& atn_config) const { - return atn_config.hashCode(); - } - }; - - struct ATNConfigComparer final { - bool operator()(const ATNConfig& lhs, const ATNConfig& rhs) const { - return lhs == rhs; - } - }; - - class LL1AnalyzerImpl final { - public: - LL1AnalyzerImpl(const ATN& atn, misc::IntervalSet& look, bool seeThruPreds, bool addEOF) : _atn(atn), _look(look), _seeThruPreds(seeThruPreds), _addEOF(addEOF) {} - - /// - /// Compute set of tokens that can follow {@code s} in the ATN in the - /// specified {@code ctx}. - ///

- /// If {@code ctx} is {@code null} and {@code stopState} or the end of the - /// rule containing {@code s} is reached, is added to - /// the result set. If {@code ctx} is not {@code null} and {@code addEOF} is - /// {@code true} and {@code stopState} or the end of the outermost rule is - /// reached, is added to the result set. - ///

- /// the ATN state. - /// the ATN state to stop at. This can be a - /// to detect epsilon paths through a closure. - /// The outer context, or {@code null} if the outer context should - /// not be used. - /// The result lookahead set. - /// A set used for preventing epsilon closures in the ATN - /// from causing a stack overflow. Outside code should pass - /// {@code new HashSet} for this argument. - /// A set used for preventing left recursion in the - /// ATN from causing a stack overflow. Outside code should pass - /// {@code new BitSet()} for this argument. - /// {@code true} to true semantic predicates as - /// implicitly {@code true} and "see through them", otherwise {@code false} - /// to treat semantic predicates as opaque and add to the - /// result if one is encountered. - /// Add to the result if the end of the - /// outermost context is reached. This parameter has no effect if {@code ctx} - /// is {@code null}. - void LOOK(ATNState *s, ATNState *stopState, Ref const& ctx) { - if (!_lookBusy.insert(ATNConfig(s, 0, ctx)).second) { - return; - } - - // ml: s can never be null, hence no need to check if stopState is != null. - if (s == stopState) { - if (ctx == nullptr) { - _look.add(Token::EPSILON); - return; - } else if (ctx->isEmpty() && _addEOF) { - _look.add(Token::EOF); - return; - } - } - - if (s->getStateType() == ATNStateType::RULE_STOP) { - if (ctx == nullptr) { - _look.add(Token::EPSILON); - return; - } else if (ctx->isEmpty() && _addEOF) { - _look.add(Token::EOF); - return; - } - - if (ctx != PredictionContext::EMPTY) { - bool removed = _calledRuleStack.test(s->ruleIndex); - _calledRuleStack[s->ruleIndex] = false; - // run thru all possible stack tops in ctx - for (size_t i = 0; i < ctx->size(); i++) { - ATNState *returnState = _atn.states[ctx->getReturnState(i)]; - LOOK(returnState, stopState, ctx->getParent(i)); - } - if (removed) { - _calledRuleStack.set(s->ruleIndex); - } - return; - } - } - - size_t n = s->transitions.size(); - for (size_t i = 0; i < n; i++) { - const Transition *t = s->transitions[i].get(); - const auto tType = t->getTransitionType(); - - if (tType == TransitionType::RULE) { - if (_calledRuleStack[(static_cast(t))->target->ruleIndex]) { - continue; - } - - Ref newContext = SingletonPredictionContext::create(ctx, (static_cast(t))->followState->stateNumber); - - _calledRuleStack.set((static_cast(t))->target->ruleIndex); - LOOK(t->target, stopState, newContext); - _calledRuleStack[(static_cast(t))->target->ruleIndex] = false; - - } else if (tType == TransitionType::PREDICATE || tType == TransitionType::PRECEDENCE) { - if (_seeThruPreds) { - LOOK(t->target, stopState, ctx); - } else { - _look.add(LL1Analyzer::HIT_PRED); - } - } else if (t->isEpsilon()) { - LOOK(t->target, stopState, ctx); - } else if (tType == TransitionType::WILDCARD) { - _look.addAll(misc::IntervalSet::of(Token::MIN_USER_TOKEN_TYPE, static_cast(_atn.maxTokenType))); - } else { - misc::IntervalSet set = t->label(); - if (!set.isEmpty()) { - if (tType == TransitionType::NOT_SET) { - set = set.complement(misc::IntervalSet::of(Token::MIN_USER_TOKEN_TYPE, static_cast(_atn.maxTokenType))); - } - _look.addAll(set); - } - } - } - } - - private: - const ATN& _atn; - misc::IntervalSet& _look; - antlrcpp::BitSet _calledRuleStack; - std::unordered_set _lookBusy; - bool _seeThruPreds; - bool _addEOF; - }; - -} - -std::vector LL1Analyzer::getDecisionLookahead(ATNState *s) const { - std::vector look; - - if (s == nullptr) { - return look; - } - - look.resize(s->transitions.size()); // Fills all interval sets with defaults. - for (size_t alt = 0; alt < s->transitions.size(); alt++) { - LL1AnalyzerImpl impl(_atn, look[alt], false, false); - impl.LOOK(s->transitions[alt]->target, nullptr, PredictionContext::EMPTY); - // Wipe out lookahead for this alternative if we found nothing - // or we had a predicate when we !seeThruPreds - if (look[alt].size() == 0 || look[alt].contains(LL1Analyzer::HIT_PRED)) { - look[alt].clear(); - } - } - return look; -} - -misc::IntervalSet LL1Analyzer::LOOK(ATNState *s, RuleContext *ctx) const { - return LOOK(s, nullptr, ctx); -} - -misc::IntervalSet LL1Analyzer::LOOK(ATNState *s, ATNState *stopState, RuleContext *ctx) const { - Ref lookContext = ctx != nullptr ? PredictionContext::fromRuleContext(_atn, ctx) : nullptr; - misc::IntervalSet r; - LL1AnalyzerImpl impl(_atn, r, true, true); - impl.LOOK(s, stopState, lookContext); - return r; -} diff --git a/src/include/atn/LL1Analyzer.h b/src/include/atn/LL1Analyzer.h deleted file mode 100755 index cf17501d..00000000 --- a/src/include/atn/LL1Analyzer.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "Token.h" -#include "atn/ATNConfig.h" -#include "atn/PredictionContext.h" -#include "support/BitSet.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC LL1Analyzer final { - public: - /// Special value added to the lookahead sets to indicate that we hit - /// a predicate during analysis if {@code seeThruPreds==false}. - static constexpr size_t HIT_PRED = Token::INVALID_TYPE; - - explicit LL1Analyzer(const atn::ATN &atn) : _atn(atn) {} - - /// - /// Calculates the SLL(1) expected lookahead set for each outgoing transition - /// of an . The returned array has one element for each - /// outgoing transition in {@code s}. If the closure from transition - /// i leads to a semantic predicate before matching a symbol, the - /// element at index i of the result will be {@code null}. - /// - /// the ATN state - /// the expected symbols for each outgoing transition of {@code s}. - std::vector getDecisionLookahead(ATNState *s) const; - - /// - /// Compute set of tokens that can follow {@code s} in the ATN in the - /// specified {@code ctx}. - ///

- /// If {@code ctx} is {@code null} and the end of the rule containing - /// {@code s} is reached, is added to the result set. - /// If {@code ctx} is not {@code null} and the end of the outermost rule is - /// reached, is added to the result set. - ///

- /// the ATN state - /// the complete parser context, or {@code null} if the context - /// should be ignored - /// - /// The set of tokens that can follow {@code s} in the ATN in the - /// specified {@code ctx}. - misc::IntervalSet LOOK(ATNState *s, RuleContext *ctx) const; - - /// - /// Compute set of tokens that can follow {@code s} in the ATN in the - /// specified {@code ctx}. - ///

- /// If {@code ctx} is {@code null} and the end of the rule containing - /// {@code s} is reached, is added to the result set. - /// If {@code ctx} is not {@code null} and the end of the outermost rule is - /// reached, is added to the result set. - ///

- /// the ATN state - /// the ATN state to stop at. This can be a - /// to detect epsilon paths through a closure. - /// the complete parser context, or {@code null} if the context - /// should be ignored - /// - /// The set of tokens that can follow {@code s} in the ATN in the - /// specified {@code ctx}. - misc::IntervalSet LOOK(ATNState *s, ATNState *stopState, RuleContext *ctx) const; - - private: - const atn::ATN &_atn; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerATNConfig.cpp b/src/include/atn/LexerATNConfig.cpp deleted file mode 100755 index 055f8bbd..00000000 --- a/src/include/atn/LexerATNConfig.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "atn/DecisionState.h" -#include "atn/PredictionContext.h" -#include "SemanticContext.h" -#include "atn/LexerActionExecutor.h" - -#include "support/CPPUtils.h" -#include "support/Casts.h" - -#include "atn/LexerATNConfig.h" - -using namespace antlr4::atn; -using namespace antlrcpp; - -LexerATNConfig::LexerATNConfig(ATNState *state, int alt, Ref context) - : ATNConfig(state, alt, std::move(context)) {} - -LexerATNConfig::LexerATNConfig(ATNState *state, int alt, Ref context, Ref lexerActionExecutor) - : ATNConfig(state, alt, std::move(context)), _lexerActionExecutor(std::move(lexerActionExecutor)) {} - -LexerATNConfig::LexerATNConfig(LexerATNConfig const& other, ATNState *state) - : ATNConfig(other, state), _lexerActionExecutor(other._lexerActionExecutor), _passedThroughNonGreedyDecision(checkNonGreedyDecision(other, state)) {} - -LexerATNConfig::LexerATNConfig(LexerATNConfig const& other, ATNState *state, Ref lexerActionExecutor) - : ATNConfig(other, state), _lexerActionExecutor(std::move(lexerActionExecutor)), _passedThroughNonGreedyDecision(checkNonGreedyDecision(other, state)) {} - -LexerATNConfig::LexerATNConfig(LexerATNConfig const& other, ATNState *state, Ref context) - : ATNConfig(other, state, std::move(context)), _lexerActionExecutor(other._lexerActionExecutor), _passedThroughNonGreedyDecision(checkNonGreedyDecision(other, state)) {} - -size_t LexerATNConfig::hashCode() const { - size_t hashCode = misc::MurmurHash::initialize(7); - hashCode = misc::MurmurHash::update(hashCode, state->stateNumber); - hashCode = misc::MurmurHash::update(hashCode, alt); - hashCode = misc::MurmurHash::update(hashCode, context); - hashCode = misc::MurmurHash::update(hashCode, semanticContext); - hashCode = misc::MurmurHash::update(hashCode, _passedThroughNonGreedyDecision ? 1 : 0); - hashCode = misc::MurmurHash::update(hashCode, _lexerActionExecutor); - hashCode = misc::MurmurHash::finish(hashCode, 6); - return hashCode; -} - -bool LexerATNConfig::operator==(const LexerATNConfig& other) const -{ - if (this == &other) - return true; - - if (_passedThroughNonGreedyDecision != other._passedThroughNonGreedyDecision) - return false; - - if (_lexerActionExecutor == nullptr) - return other._lexerActionExecutor == nullptr; - if (*_lexerActionExecutor != *(other._lexerActionExecutor)) { - return false; - } - - return ATNConfig::operator==(other); -} - -bool LexerATNConfig::checkNonGreedyDecision(LexerATNConfig const& source, ATNState *target) { - return source._passedThroughNonGreedyDecision || - (DecisionState::is(target) && downCast(target)->nonGreedy); -} diff --git a/src/include/atn/LexerATNConfig.h b/src/include/atn/LexerATNConfig.h deleted file mode 100755 index 05d804f6..00000000 --- a/src/include/atn/LexerATNConfig.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNConfig.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC LexerATNConfig final : public ATNConfig { - public: - LexerATNConfig(ATNState *state, int alt, Ref context); - LexerATNConfig(ATNState *state, int alt, Ref context, Ref lexerActionExecutor); - - LexerATNConfig(LexerATNConfig const& other, ATNState *state); - LexerATNConfig(LexerATNConfig const& other, ATNState *state, Ref lexerActionExecutor); - LexerATNConfig(LexerATNConfig const& other, ATNState *state, Ref context); - - /** - * Gets the {@link LexerActionExecutor} capable of executing the embedded - * action(s) for the current configuration. - */ - const Ref& getLexerActionExecutor() const { return _lexerActionExecutor; } - bool hasPassedThroughNonGreedyDecision() const { return _passedThroughNonGreedyDecision; } - - virtual size_t hashCode() const override; - - bool operator==(const LexerATNConfig& other) const; - - private: - /** - * This is the backing field for {@link #getLexerActionExecutor}. - */ - const Ref _lexerActionExecutor; - const bool _passedThroughNonGreedyDecision = false; - - static bool checkNonGreedyDecision(LexerATNConfig const& source, ATNState *target); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerATNSimulator.cpp b/src/include/atn/LexerATNSimulator.cpp deleted file mode 100755 index cc42a238..00000000 --- a/src/include/atn/LexerATNSimulator.cpp +++ /dev/null @@ -1,621 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "IntStream.h" -#include "atn/OrderedATNConfigSet.h" -#include "Token.h" -#include "LexerNoViableAltException.h" -#include "atn/RuleStopState.h" -#include "atn/RuleTransition.h" -#include "atn/SingletonPredictionContext.h" -#include "atn/PredicateTransition.h" -#include "atn/ActionTransition.h" -#include "atn/TokensStartState.h" -#include "misc/Interval.h" -#include "dfa/DFA.h" -#include "Lexer.h" -#include "internal/Synchronization.h" - -#include "dfa/DFAState.h" -#include "atn/LexerATNConfig.h" -#include "atn/LexerActionExecutor.h" - -#include "atn/LexerATNSimulator.h" - -#ifndef LEXER_DEBUG_ATN -#define LEXER_DEBUG_ATN 0 -#endif -#ifndef LEXER_DEBUG_DFA -#define LEXER_DEBUG_DFA 0 -#endif - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::internal; -using namespace antlrcpp; - -void LexerATNSimulator::SimState::reset() { - *this = SimState(); -} - -LexerATNSimulator::LexerATNSimulator(const ATN &atn, std::vector &decisionToDFA, - PredictionContextCache &sharedContextCache) - : LexerATNSimulator(nullptr, atn, decisionToDFA, sharedContextCache) { -} - -LexerATNSimulator::LexerATNSimulator(Lexer *recog, const ATN &atn, std::vector &decisionToDFA, - PredictionContextCache &sharedContextCache) - : ATNSimulator(atn, sharedContextCache), _recog(recog), _decisionToDFA(decisionToDFA) { - InitializeInstanceFields(); -} - -void LexerATNSimulator::copyState(LexerATNSimulator *simulator) { - _charPositionInLine = simulator->_charPositionInLine; - _line = simulator->_line; - _mode = simulator->_mode; - _startIndex = simulator->_startIndex; -} - -size_t LexerATNSimulator::match(CharStream *input, size_t mode) { - _mode = mode; - ssize_t mark = input->mark(); - - auto onExit = finally([input, mark] { - input->release(mark); - }); - - _startIndex = input->index(); - _prevAccept.reset(); - const dfa::DFA &dfa = _decisionToDFA[mode]; - dfa::DFAState* s0; - { - SharedLock stateLock(atn._stateMutex); - s0 = dfa.s0; - } - if (s0 == nullptr) { - return matchATN(input); - } else { - return execATN(input, s0); - } -} - -void LexerATNSimulator::reset() { - _prevAccept.reset(); - _startIndex = 0; - _line = 1; - _charPositionInLine = 0; - _mode = Lexer::DEFAULT_MODE; -} - -void LexerATNSimulator::clearDFA() { - size_t size = _decisionToDFA.size(); - _decisionToDFA.clear(); - for (size_t d = 0; d < size; ++d) { - _decisionToDFA.emplace_back(atn.getDecisionState(d), d); - } -} - -size_t LexerATNSimulator::matchATN(CharStream *input) { - ATNState *startState = atn.modeToStartState[_mode]; - - std::unique_ptr s0_closure = computeStartState(input, startState); - - bool suppressEdge = s0_closure->hasSemanticContext; - s0_closure->hasSemanticContext = false; - - dfa::DFAState *next = addDFAState(s0_closure.release(), suppressEdge); - - size_t predict = execATN(input, next); - - return predict; -} - -size_t LexerATNSimulator::execATN(CharStream *input, dfa::DFAState *ds0) { - if (ds0->isAcceptState) { - // allow zero-length tokens - // ml: in Java code this method uses 3 params. The first is a member var of the class anyway (_prevAccept), so why pass it here? - captureSimState(input, ds0); - } - - size_t t = input->LA(1); - dfa::DFAState *s = ds0; // s is current/from DFA state - - while (true) { // while more work - // As we move src->trg, src->trg, we keep track of the previous trg to - // avoid looking up the DFA state again, which is expensive. - // If the previous target was already part of the DFA, we might - // be able to avoid doing a reach operation upon t. If s!=null, - // it means that semantic predicates didn't prevent us from - // creating a DFA state. Once we know s!=null, we check to see if - // the DFA state has an edge already for t. If so, we can just reuse - // it's configuration set; there's no point in re-computing it. - // This is kind of like doing DFA simulation within the ATN - // simulation because DFA simulation is really just a way to avoid - // computing reach/closure sets. Technically, once we know that - // we have a previously added DFA state, we could jump over to - // the DFA simulator. But, that would mean popping back and forth - // a lot and making things more complicated algorithmically. - // This optimization makes a lot of sense for loops within DFA. - // A character will take us back to an existing DFA state - // that already has lots of edges out of it. e.g., .* in comments. - dfa::DFAState *target = getExistingTargetState(s, t); - if (target == nullptr) { - target = computeTargetState(input, s, t); - } - - if (target == ERROR.get()) { - break; - } - - // If this is a consumable input element, make sure to consume before - // capturing the accept state so the input index, line, and char - // position accurately reflect the state of the interpreter at the - // end of the token. - if (t != Token::EOF) { - consume(input); - } - - if (target->isAcceptState) { - captureSimState(input, target); - if (t == Token::EOF) { - break; - } - } - - t = input->LA(1); - s = target; // flip; current DFA target becomes new src/from state - } - - return failOrAccept(input, s->configs.get(), t); -} - -dfa::DFAState *LexerATNSimulator::getExistingTargetState(dfa::DFAState *s, size_t t) { - dfa::DFAState* retval = nullptr; - SharedLock edgeLock(atn._edgeMutex); - if (t <= MAX_DFA_EDGE) { - auto iterator = s->edges.find(t - MIN_DFA_EDGE); -#if LEXER_DEBUG_ATN == 1 - if (iterator != s->edges.end()) { - std::cout << std::string("reuse state ") << s->stateNumber << std::string(" edge to ") << iterator->second->stateNumber << std::endl; - } -#endif - - if (iterator != s->edges.end()) - retval = iterator->second; - } - return retval; -} - -dfa::DFAState *LexerATNSimulator::computeTargetState(CharStream *input, dfa::DFAState *s, size_t t) { - OrderedATNConfigSet *reach = new OrderedATNConfigSet(); /* mem-check: deleted on error or managed by new DFA state. */ - - // if we don't find an existing DFA state - // Fill reach starting from closure, following t transitions - getReachableConfigSet(input, s->configs.get(), reach, t); - - if (reach->isEmpty()) { // we got nowhere on t from s - if (!reach->hasSemanticContext) { - // we got nowhere on t, don't throw out this knowledge; it'd - // cause a failover from DFA later. - addDFAEdge(s, t, ERROR.get()); - } - delete reach; - - // stop when we can't match any more char - return ERROR.get(); - } - - // Add an edge from s to target DFA found/created for reach - return addDFAEdge(s, t, reach); -} - -size_t LexerATNSimulator::failOrAccept(CharStream *input, ATNConfigSet *reach, size_t t) { - if (_prevAccept.dfaState != nullptr) { - accept(input, _prevAccept.dfaState->lexerActionExecutor, _startIndex, _prevAccept.index, _prevAccept.line, _prevAccept.charPos); - return _prevAccept.dfaState->prediction; - } else { - // if no accept and EOF is first char, return EOF - if (t == Token::EOF && input->index() == _startIndex) { - return Token::EOF; - } - - throw LexerNoViableAltException(_recog, input, _startIndex, reach); - } -} - -void LexerATNSimulator::getReachableConfigSet(CharStream *input, ATNConfigSet *closure_, ATNConfigSet *reach, size_t t) { - // 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 - size_t skipAlt = ATN::INVALID_ALT_NUMBER; - - for (const auto &c : closure_->configs) { - bool currentAltReachedAcceptState = c->alt == skipAlt; - if (currentAltReachedAcceptState && (std::static_pointer_cast(c))->hasPassedThroughNonGreedyDecision()) { - continue; - } - -#if LEXER_DEBUG_ATN == 1 - std::cout << "testing " << getTokenName((int)t) << " at " << c->toString(true) << std::endl; -#endif - - size_t n = c->state->transitions.size(); - for (size_t ti = 0; ti < n; ti++) { // for each transition - const Transition *trans = c->state->transitions[ti].get(); - ATNState *target = getReachableTarget(trans, (int)t); - if (target != nullptr) { - auto lexerActionExecutor = downCast(*c).getLexerActionExecutor(); - if (lexerActionExecutor != nullptr) { - lexerActionExecutor = lexerActionExecutor->fixOffsetBeforeMatch((int)input->index() - (int)_startIndex); - } - - bool treatEofAsEpsilon = t == Token::EOF; - Ref config = std::make_shared(downCast(*c), - target, std::move(lexerActionExecutor)); - - if (closure(input, config, reach, currentAltReachedAcceptState, true, treatEofAsEpsilon)) { - // any remaining configs for this alt have a lower priority than - // the one that just reached an accept state. - skipAlt = c->alt; - break; - } - } - } - } -} - -void LexerATNSimulator::accept(CharStream *input, const Ref &lexerActionExecutor, size_t /*startIndex*/, - size_t index, size_t line, size_t charPos) { -#if LEXER_DEBUG_ATN == 1 - std::cout << "ACTION "; - std::cout << toString(lexerActionExecutor) << std::endl; -#endif - - // seek to after last char in token - input->seek(index); - _line = line; - _charPositionInLine = (int)charPos; - - if (lexerActionExecutor != nullptr && _recog != nullptr) { - lexerActionExecutor->execute(_recog, input, _startIndex); - } -} - -atn::ATNState *LexerATNSimulator::getReachableTarget(const Transition *trans, size_t t) { - if (trans->matches(t, Lexer::MIN_CHAR_VALUE, Lexer::MAX_CHAR_VALUE)) { - return trans->target; - } - - return nullptr; -} - -std::unique_ptr LexerATNSimulator::computeStartState(CharStream *input, ATNState *p) { - Ref initialContext = PredictionContext::EMPTY; // ml: the purpose of this assignment is unclear - std::unique_ptr configs(new OrderedATNConfigSet()); - for (size_t i = 0; i < p->transitions.size(); i++) { - ATNState *target = p->transitions[i]->target; - Ref c = std::make_shared(target, (int)(i + 1), initialContext); - closure(input, c, configs.get(), false, false, false); - } - - return configs; -} - -bool LexerATNSimulator::closure(CharStream *input, const Ref &config, ATNConfigSet *configs, - bool currentAltReachedAcceptState, bool speculative, bool treatEofAsEpsilon) { -#if LEXER_DEBUG_ATN == 1 - std::cout << "closure(" << config->toString(true) << ")" << std::endl; -#endif - - if (config->state != nullptr && config->state->getStateType() == ATNStateType::RULE_STOP) { -#if LEXER_DEBUG_ATN == 1 - if (_recog != nullptr) { - std::cout << "closure at " << _recog->getRuleNames()[config->state->ruleIndex] << " rule stop " << config << std::endl; - } else { - std::cout << "closure at rule stop " << config << std::endl; - } -#endif - - if (config->context == nullptr || config->context->hasEmptyPath()) { - if (config->context == nullptr || config->context->isEmpty()) { - configs->add(config); - return true; - } else { - configs->add(std::make_shared(*config, config->state, PredictionContext::EMPTY)); - currentAltReachedAcceptState = true; - } - } - - if (config->context != nullptr && !config->context->isEmpty()) { - for (size_t i = 0; i < config->context->size(); i++) { - if (config->context->getReturnState(i) != PredictionContext::EMPTY_RETURN_STATE) { - Ref newContext = config->context->getParent(i); // "pop" return state - ATNState *returnState = atn.states[config->context->getReturnState(i)]; - Ref c = std::make_shared(*config, returnState, newContext); - currentAltReachedAcceptState = closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon); - } - } - } - - return currentAltReachedAcceptState; - } - - // optimization - if (!config->state->epsilonOnlyTransitions) { - if (!currentAltReachedAcceptState || !config->hasPassedThroughNonGreedyDecision()) { - configs->add(config); - } - } - - ATNState *p = config->state; - for (size_t i = 0; i < p->transitions.size(); i++) { - const Transition *t = p->transitions[i].get(); - Ref c = getEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon); - if (c != nullptr) { - currentAltReachedAcceptState = closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon); - } - } - - return currentAltReachedAcceptState; -} - -Ref LexerATNSimulator::getEpsilonTarget(CharStream *input, const Ref &config, const Transition *t, - ATNConfigSet *configs, bool speculative, bool treatEofAsEpsilon) { - - Ref c = nullptr; - switch (t->getTransitionType()) { - case TransitionType::RULE: { - const RuleTransition *ruleTransition = static_cast(t); - Ref newContext = SingletonPredictionContext::create(config->context, ruleTransition->followState->stateNumber); - c = std::make_shared(*config, t->target, newContext); - break; - } - - case TransitionType::PRECEDENCE: - throw UnsupportedOperationException("Precedence predicates are not supported in lexers."); - - case TransitionType::PREDICATE: { - /* Track traversing semantic predicates. If we traverse, - we cannot add a DFA state for this "reach" computation - because the DFA would not test the predicate again in the - future. Rather than creating collections of semantic predicates - like v3 and testing them on prediction, v4 will test them on the - fly all the time using the ATN not the DFA. This is slower but - semantically it's not used that often. One of the key elements to - this predicate mechanism is not adding DFA states that see - predicates immediately afterwards in the ATN. For example, - - a : ID {p1}? | ID {p2}? ; - - should create the start state for rule 'a' (to save start state - competition), but should not create target of ID state. The - collection of ATN states the following ID references includes - states reached by traversing predicates. Since this is when we - test them, we cannot cash the DFA state target of ID. - */ - const PredicateTransition *pt = static_cast(t); - -#if LEXER_DEBUG_ATN == 1 - std::cout << "EVAL rule " << pt->getRuleIndex() << ":" << pt->getPredIndex() << std::endl; -#endif - - configs->hasSemanticContext = true; - if (evaluatePredicate(input, pt->getRuleIndex(), pt->getPredIndex(), speculative)) { - c = std::make_shared(*config, t->target); - } - break; - } - - case TransitionType::ACTION: - if (config->context == nullptr|| config->context->hasEmptyPath()) { - // execute actions anywhere in the start rule for a token. - // - // TODO: if the entry rule is invoked recursively, some - // actions may be executed during the recursive call. The - // problem can appear when hasEmptyPath() is true but - // isEmpty() is false. In this case, the config needs to be - // split into two contexts - one with just the empty path - // and another with everything but the empty path. - // Unfortunately, the current algorithm does not allow - // getEpsilonTarget to return two configurations, so - // additional modifications are needed before we can support - // the split operation. - auto lexerActionExecutor = LexerActionExecutor::append(config->getLexerActionExecutor(), - atn.lexerActions[static_cast(t)->actionIndex]); - c = std::make_shared(*config, t->target, std::move(lexerActionExecutor)); - break; - } - else { - // ignore actions in referenced rules - c = std::make_shared(*config, t->target); - break; - } - - case TransitionType::EPSILON: - c = std::make_shared(*config, t->target); - break; - - case TransitionType::ATOM: - case TransitionType::RANGE: - case TransitionType::SET: - if (treatEofAsEpsilon) { - if (t->matches(Token::EOF, Lexer::MIN_CHAR_VALUE, Lexer::MAX_CHAR_VALUE)) { - c = std::make_shared(*config, t->target); - break; - } - } - - break; - - default: // To silence the compiler. Other transition types are not used here. - break; - } - - return c; -} - -bool LexerATNSimulator::evaluatePredicate(CharStream *input, size_t ruleIndex, size_t predIndex, bool speculative) { - // assume true if no recognizer was provided - if (_recog == nullptr) { - return true; - } - - if (!speculative) { - return _recog->sempred(nullptr, ruleIndex, predIndex); - } - - size_t savedCharPositionInLine = _charPositionInLine; - size_t savedLine = _line; - size_t index = input->index(); - ssize_t marker = input->mark(); - - auto onExit = finally([this, input, savedCharPositionInLine, savedLine, index, marker] { - _charPositionInLine = savedCharPositionInLine; - _line = savedLine; - input->seek(index); - input->release(marker); - }); - - consume(input); - return _recog->sempred(nullptr, ruleIndex, predIndex); -} - -void LexerATNSimulator::captureSimState(CharStream *input, dfa::DFAState *dfaState) { - _prevAccept.index = input->index(); - _prevAccept.line = _line; - _prevAccept.charPos = _charPositionInLine; - _prevAccept.dfaState = dfaState; -} - -dfa::DFAState *LexerATNSimulator::addDFAEdge(dfa::DFAState *from, size_t t, ATNConfigSet *q) { - /* leading to this call, ATNConfigSet.hasSemanticContext is used as a - * marker indicating dynamic predicate evaluation makes this edge - * dependent on the specific input sequence, so the static edge in the - * DFA should be omitted. The target DFAState is still created since - * execATN has the ability to resynchronize with the DFA state cache - * following the predicate evaluation step. - * - * TJP notes: next time through the DFA, we see a pred again and eval. - * If that gets us to a previously created (but dangling) DFA - * state, we can continue in pure DFA mode from there. - */ - bool suppressEdge = q->hasSemanticContext; - q->hasSemanticContext = false; - - dfa::DFAState *to = addDFAState(q); - - if (suppressEdge) { - return to; - } - - addDFAEdge(from, t, to); - return to; -} - -void LexerATNSimulator::addDFAEdge(dfa::DFAState *p, size_t t, dfa::DFAState *q) { - if (/*t < MIN_DFA_EDGE ||*/ t > MAX_DFA_EDGE) { // MIN_DFA_EDGE is 0 - // Only track edges within the DFA bounds - return; - } - - UniqueLock edgeLock(atn._edgeMutex); - p->edges[t - MIN_DFA_EDGE] = q; // connect -} - -dfa::DFAState *LexerATNSimulator::addDFAState(ATNConfigSet *configs) { - return addDFAState(configs, true); -} - -dfa::DFAState *LexerATNSimulator::addDFAState(ATNConfigSet *configs, bool suppressEdge) { - /* the lexer evaluates predicates on-the-fly; by this point configs - * should not contain any configurations with unevaluated predicates. - */ - assert(!configs->hasSemanticContext); - - dfa::DFAState *proposed = new dfa::DFAState(std::unique_ptr(configs)); /* mem-check: managed by the DFA or deleted below */ - Ref firstConfigWithRuleStopState = nullptr; - for (const auto &c : configs->configs) { - if (RuleStopState::is(c->state)) { - firstConfigWithRuleStopState = c; - break; - } - } - - if (firstConfigWithRuleStopState != nullptr) { - proposed->isAcceptState = true; - proposed->lexerActionExecutor = downCast(*firstConfigWithRuleStopState).getLexerActionExecutor(); - proposed->prediction = atn.ruleToTokenType[firstConfigWithRuleStopState->state->ruleIndex]; - } - - dfa::DFA &dfa = _decisionToDFA[_mode]; - - { - UniqueLock stateLock(atn._stateMutex); - auto [existing, inserted] = dfa.states.insert(proposed); - if (!inserted) { - delete proposed; - proposed = *existing; - } else { - // Previously we did a lookup, then set fields, then inserted. It was `dfa.states.size()`, - // since we already inserted we need to subtract one. - proposed->stateNumber = static_cast(dfa.states.size() - 1); - proposed->configs->setReadonly(true); - } - if (!suppressEdge) { - dfa.s0 = proposed; - } - } - - return proposed; -} - -dfa::DFA& LexerATNSimulator::getDFA(size_t mode) { - return _decisionToDFA[mode]; -} - -std::string LexerATNSimulator::getText(CharStream *input) { - // index is first lookahead char, don't include. - return input->getText(misc::Interval(_startIndex, input->index() - 1)); -} - -size_t LexerATNSimulator::getLine() const { - return _line; -} - -void LexerATNSimulator::setLine(size_t line) { - _line = line; -} - -size_t LexerATNSimulator::getCharPositionInLine() { - return _charPositionInLine; -} - -void LexerATNSimulator::setCharPositionInLine(size_t charPositionInLine) { - _charPositionInLine = charPositionInLine; -} - -void LexerATNSimulator::consume(CharStream *input) { - size_t curChar = input->LA(1); - if (curChar == '\n') { - _line++; - _charPositionInLine = 0; - } else { - _charPositionInLine++; - } - input->consume(); -} - -std::string LexerATNSimulator::getTokenName(size_t t) { - if (t == Token::EOF) { - return "EOF"; - } - return std::string("'") + static_cast(t) + std::string("'"); -} - -void LexerATNSimulator::InitializeInstanceFields() { - _startIndex = 0; - _line = 1; - _charPositionInLine = 0; - _mode = antlr4::Lexer::DEFAULT_MODE; -} diff --git a/src/include/atn/LexerATNSimulator.h b/src/include/atn/LexerATNSimulator.h deleted file mode 100755 index 46bc2261..00000000 --- a/src/include/atn/LexerATNSimulator.h +++ /dev/null @@ -1,199 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include - -#include "atn/ATNSimulator.h" -#include "atn/LexerATNConfig.h" -#include "atn/ATNConfigSet.h" - -namespace antlr4 { -namespace atn { - - /// "dup" of ParserInterpreter - class ANTLR4CPP_PUBLIC LexerATNSimulator : public ATNSimulator { - protected: - struct ANTLR4CPP_PUBLIC SimState final { - size_t index = INVALID_INDEX; - size_t line = 0; - size_t charPos = INVALID_INDEX; - dfa::DFAState *dfaState = nullptr; - - void reset(); - }; - - public: - static constexpr size_t MIN_DFA_EDGE = 0; - static constexpr size_t MAX_DFA_EDGE = 127; // forces unicode to stay in ATN - - protected: - /// - /// When we hit an accept state in either the DFA or the ATN, we - /// have to notify the character stream to start buffering characters - /// via and record the current state. The current sim state - /// includes the current index into the input, the current line, - /// and current character position in that line. Note that the Lexer is - /// tracking the starting line and characterization of the token. These - /// variables track the "state" of the simulator when it hits an accept state. - ///

- /// We track these variables separately for the DFA and ATN simulation - /// because the DFA simulation often has to fail over to the ATN - /// simulation. If the ATN simulation fails, we need the DFA to fall - /// back to its previously accepted state, if any. If the ATN succeeds, - /// then the ATN does the accept and the DFA simulator that invoked it - /// can simply return the predicted token type. - ///

- Lexer *const _recog; - - /// The current token's starting index into the character stream. - /// Shared across DFA to ATN simulation in case the ATN fails and the - /// DFA did not have a previous accept state. In this case, we use the - /// ATN-generated exception object. - size_t _startIndex; - - /// line number 1..n within the input. - size_t _line; - - /// The index of the character relative to the beginning of the line 0..n-1. - size_t _charPositionInLine; - - public: - std::vector &_decisionToDFA; - - protected: - size_t _mode; - - /// Used during DFA/ATN exec to record the most recent accept configuration info. - SimState _prevAccept; - - public: - LexerATNSimulator(const ATN &atn, std::vector &decisionToDFA, PredictionContextCache &sharedContextCache); - LexerATNSimulator(Lexer *recog, const ATN &atn, std::vector &decisionToDFA, PredictionContextCache &sharedContextCache); - virtual ~LexerATNSimulator() = default; - - virtual void copyState(LexerATNSimulator *simulator); - virtual size_t match(CharStream *input, size_t mode); - virtual void reset() override; - - virtual void clearDFA() override; - - protected: - virtual size_t matchATN(CharStream *input); - virtual size_t execATN(CharStream *input, dfa::DFAState *ds0); - - /// - /// Get an existing target state for an edge in the DFA. If the target state - /// for the edge has not yet been computed or is otherwise not available, - /// this method returns {@code null}. - /// - /// The current DFA state - /// The next input symbol - /// The existing target DFA state for the given input symbol - /// {@code t}, or {@code null} if the target state for this edge is not - /// already cached - virtual dfa::DFAState *getExistingTargetState(dfa::DFAState *s, size_t t); - - /// - /// Compute a target state for an edge in the DFA, and attempt to add the - /// computed state and corresponding edge to the DFA. - /// - /// The input stream - /// The current DFA state - /// The next input symbol - /// - /// The computed target DFA state for the given input symbol - /// {@code t}. If {@code t} does not lead to a valid DFA state, this method - /// returns . - virtual dfa::DFAState *computeTargetState(CharStream *input, dfa::DFAState *s, size_t t); - - virtual size_t failOrAccept(CharStream *input, ATNConfigSet *reach, size_t t); - - /// - /// Given a starting configuration set, figure out all ATN configurations - /// we can reach upon input {@code t}. Parameter {@code reach} is a return - /// parameter. - /// - void getReachableConfigSet(CharStream *input, ATNConfigSet *closure_, // closure_ as we have a closure() already - ATNConfigSet *reach, size_t t); - - virtual void accept(CharStream *input, const Ref &lexerActionExecutor, size_t startIndex, size_t index, - size_t line, size_t charPos); - - virtual ATNState *getReachableTarget(const Transition *trans, size_t t); - - virtual std::unique_ptr computeStartState(CharStream *input, ATNState *p); - - /// - /// Since the alternatives within any lexer decision are ordered by - /// preference, this method stops pursuing the closure as soon as an accept - /// state is reached. After the first accept state is reached by depth-first - /// search from {@code config}, all other (potentially reachable) states for - /// this rule would have a lower priority. - /// - /// {@code true} if an accept state is reached, otherwise - /// {@code false}. - virtual bool closure(CharStream *input, const Ref &config, ATNConfigSet *configs, - bool currentAltReachedAcceptState, bool speculative, bool treatEofAsEpsilon); - - // side-effect: can alter configs.hasSemanticContext - virtual Ref getEpsilonTarget(CharStream *input, const Ref &config, const Transition *t, - ATNConfigSet *configs, bool speculative, bool treatEofAsEpsilon); - - /// - /// Evaluate a predicate specified in the lexer. - ///

- /// If {@code speculative} is {@code true}, this method was called before - /// for the matched character. This method should call - /// before evaluating the predicate to ensure position - /// sensitive values, including , , - /// and , properly reflect the current - /// lexer state. This method should restore {@code input} and the simulator - /// to the original state before returning (i.e. undo the actions made by the - /// call to . - ///

- /// The input stream. - /// The rule containing the predicate. - /// The index of the predicate within the rule. - /// {@code true} if the current index in {@code input} is - /// one character before the predicate's location. - /// - /// {@code true} if the specified predicate evaluates to - /// {@code true}. - virtual bool evaluatePredicate(CharStream *input, size_t ruleIndex, size_t predIndex, bool speculative); - - virtual void captureSimState(CharStream *input, dfa::DFAState *dfaState); - virtual dfa::DFAState* addDFAEdge(dfa::DFAState *from, size_t t, ATNConfigSet *q); - virtual void addDFAEdge(dfa::DFAState *p, size_t t, dfa::DFAState *q); - - /// - /// Add a new DFA state if there isn't one with this set of - /// configurations already. This method also detects the first - /// configuration containing an ATN rule stop state. Later, when - /// traversing the DFA, we will know which rule to accept. - /// - virtual dfa::DFAState *addDFAState(ATNConfigSet *configs); - - virtual dfa::DFAState *addDFAState(ATNConfigSet *configs, bool suppressEdge); - - public: - dfa::DFA& getDFA(size_t mode); - - /// Get the text matched so far for the current token. - virtual std::string getText(CharStream *input); - virtual size_t getLine() const; - virtual void setLine(size_t line); - virtual size_t getCharPositionInLine(); - virtual void setCharPositionInLine(size_t charPositionInLine); - virtual void consume(CharStream *input); - virtual std::string getTokenName(size_t t); - - private: - void InitializeInstanceFields(); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerAction.cpp b/src/include/atn/LexerAction.cpp deleted file mode 100644 index a9d9a677..00000000 --- a/src/include/atn/LexerAction.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "LexerAction.h" - -using namespace antlr4::atn; - -size_t LexerAction::hashCode() const { - auto hash = cachedHashCode(); - if (hash == 0) { - hash = hashCodeImpl(); - if (hash == 0) { - hash = std::numeric_limits::max(); - } - _hashCode.store(hash, std::memory_order_relaxed); - } - return hash; -} diff --git a/src/include/atn/LexerAction.h b/src/include/atn/LexerAction.h deleted file mode 100755 index 5c30a896..00000000 --- a/src/include/atn/LexerAction.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/LexerActionType.h" -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - - /// - /// Represents a single action which can be executed following the successful - /// match of a lexer rule. Lexer actions are used for both embedded action syntax - /// and ANTLR 4's new lexer command syntax. - /// - /// @author Sam Harwell - /// @since 4.2 - /// - class ANTLR4CPP_PUBLIC LexerAction { - public: - virtual ~LexerAction() = default; - - /// - /// Gets the serialization type of the lexer action. - /// - /// The serialization type of the lexer action. - /// - /// IMPORTANT: Unlike Java, this returns LexerActionType::INDEXED_CUSTOM for instances of - /// LexerIndexedCustomAction. If you need the wrapped action type, use - /// LexerIndexedCustomAction::getAction()->getActionType(). - LexerActionType getActionType() const { return _actionType; } - - /// - /// Gets whether the lexer action is position-dependent. Position-dependent - /// actions may have different semantics depending on the - /// index at the time the action is executed. - /// - /// Many lexer commands, including {@code type}, {@code skip}, and - /// {@code more}, do not check the input index during their execution. - /// Actions like this are position-independent, and may be stored more - /// efficiently as part of the . - /// - /// {@code true} if the lexer action semantics can be affected by the - /// position of the input at the time it is executed; - /// otherwise, {@code false}. - bool isPositionDependent() const { return _positionDependent; } - - /// - /// Execute the lexer action in the context of the specified . - /// - /// For position-dependent actions, the input stream must already be - /// positioned correctly prior to calling this method. - /// - /// The lexer instance. - virtual void execute(Lexer *lexer) const = 0; - - size_t hashCode() const; - - virtual bool equals(const LexerAction &other) const = 0; - - virtual std::string toString() const = 0; - - protected: - LexerAction(LexerActionType actionType, bool positionDependent) - : _actionType(actionType), _hashCode(0), _positionDependent(positionDependent) {} - - virtual size_t hashCodeImpl() const = 0; - - size_t cachedHashCode() const { return _hashCode.load(std::memory_order_relaxed); } - - private: - const LexerActionType _actionType; - mutable std::atomic _hashCode; - const bool _positionDependent; - }; - - inline bool operator==(const LexerAction &lhs, const LexerAction &rhs) { - return lhs.equals(rhs); - } - - inline bool operator!=(const LexerAction &lhs, const LexerAction &rhs) { - return !operator==(lhs, rhs); - } - -} // namespace atn -} // namespace antlr4 - -namespace std { - - template <> - struct hash<::antlr4::atn::LexerAction> { - size_t operator()(const ::antlr4::atn::LexerAction &lexerAction) const { - return lexerAction.hashCode(); - } - }; - -} // namespace std diff --git a/src/include/atn/LexerActionExecutor.cpp b/src/include/atn/LexerActionExecutor.cpp deleted file mode 100755 index f6bb9e2c..00000000 --- a/src/include/atn/LexerActionExecutor.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "atn/LexerIndexedCustomAction.h" -#include "atn/HashUtils.h" -#include "support/CPPUtils.h" -#include "support/Arrays.h" -#include "support/Casts.h" - -#include "atn/LexerActionExecutor.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::misc; -using namespace antlrcpp; - -namespace { - - bool lexerActionEqual(const Ref &lhs, const Ref &rhs) { - return *lhs == *rhs; - } - -} - -LexerActionExecutor::LexerActionExecutor(std::vector> lexerActions) - : _lexerActions(std::move(lexerActions)), _hashCode(0) {} - -Ref LexerActionExecutor::append(const Ref &lexerActionExecutor, - Ref lexerAction) { - if (lexerActionExecutor == nullptr) { - return std::make_shared(std::vector>{ std::move(lexerAction) }); - } - std::vector> lexerActions; - lexerActions.reserve(lexerActionExecutor->_lexerActions.size() + 1); - lexerActions.insert(lexerActions.begin(), lexerActionExecutor->_lexerActions.begin(), lexerActionExecutor->_lexerActions.end()); - lexerActions.push_back(std::move(lexerAction)); - return std::make_shared(std::move(lexerActions)); -} - -Ref LexerActionExecutor::fixOffsetBeforeMatch(int offset) const { - std::vector> updatedLexerActions; - for (size_t i = 0; i < _lexerActions.size(); i++) { - if (_lexerActions[i]->isPositionDependent() && !LexerIndexedCustomAction::is(*_lexerActions[i])) { - if (updatedLexerActions.empty()) { - updatedLexerActions = _lexerActions; // Make a copy. - } - updatedLexerActions[i] = std::make_shared(offset, _lexerActions[i]); - } - } - if (updatedLexerActions.empty()) { - return shared_from_this(); - } - return std::make_shared(std::move(updatedLexerActions)); -} - -const std::vector>& LexerActionExecutor::getLexerActions() const { - return _lexerActions; -} - -void LexerActionExecutor::execute(Lexer *lexer, CharStream *input, size_t startIndex) const { - bool requiresSeek = false; - size_t stopIndex = input->index(); - - auto onExit = finally([requiresSeek, input, stopIndex]() { - if (requiresSeek) { - input->seek(stopIndex); - } - }); - for (const auto &lexerAction : _lexerActions) { - if (LexerIndexedCustomAction::is(*lexerAction)) { - int offset = downCast(*lexerAction).getOffset(); - input->seek(startIndex + offset); - requiresSeek = (startIndex + offset) != stopIndex; - } else if (lexerAction->isPositionDependent()) { - input->seek(stopIndex); - requiresSeek = false; - } - lexerAction->execute(lexer); - } -} - -size_t LexerActionExecutor::hashCode() const { - auto hash = _hashCode.load(std::memory_order_relaxed); - if (hash == 0) { - hash = MurmurHash::initialize(); - for (const auto &lexerAction : _lexerActions) { - hash = MurmurHash::update(hash, lexerAction); - } - hash = MurmurHash::finish(hash, _lexerActions.size()); - if (hash == 0) { - hash = std::numeric_limits::max(); - } - _hashCode.store(hash, std::memory_order_relaxed); - } - return hash; -} - -bool LexerActionExecutor::equals(const LexerActionExecutor &other) const { - if (this == std::addressof(other)) { - return true; - } - return cachedHashCodeEqual(_hashCode.load(std::memory_order_relaxed), other._hashCode.load(std::memory_order_relaxed)) && - _lexerActions.size() == other._lexerActions.size() && - std::equal(_lexerActions.begin(), _lexerActions.end(), other._lexerActions.begin(), lexerActionEqual); -} diff --git a/src/include/atn/LexerActionExecutor.h b/src/include/atn/LexerActionExecutor.h deleted file mode 100755 index 28bb1e28..00000000 --- a/src/include/atn/LexerActionExecutor.h +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "CharStream.h" -#include "atn/LexerAction.h" - -namespace antlr4 { -namespace atn { - - /// Represents an executor for a sequence of lexer actions which traversed during - /// the matching operation of a lexer rule (token). - /// - /// The executor tracks position information for position-dependent lexer actions - /// efficiently, ensuring that actions appearing only at the end of the rule do - /// not cause bloating of the created for the lexer. - class ANTLR4CPP_PUBLIC LexerActionExecutor final : public std::enable_shared_from_this { - public: - /// - /// Constructs an executor for a sequence of actions. - /// The lexer actions to execute. - explicit LexerActionExecutor(std::vector> lexerActions); - - /// - /// Creates a which executes the actions for - /// the input {@code lexerActionExecutor} followed by a specified - /// {@code lexerAction}. - /// - /// The executor for actions already traversed by - /// the lexer while matching a token within a particular - /// . If this is {@code null}, the method behaves as - /// though it were an empty executor. - /// The lexer action to execute after the actions - /// specified in {@code lexerActionExecutor}. - /// - /// A for executing the combine actions - /// of {@code lexerActionExecutor} and {@code lexerAction}. - static Ref append(const Ref &lexerActionExecutor, - Ref lexerAction); - - /// - /// Creates a which encodes the current offset - /// for position-dependent lexer actions. - /// - /// Normally, when the executor encounters lexer actions where - /// returns {@code true}, it calls - /// on the input to set the input - /// position to the end of the current token. This behavior provides - /// for efficient DFA representation of lexer actions which appear at the end - /// of a lexer rule, even when the lexer rule matches a variable number of - /// characters. - /// - /// Prior to traversing a match transition in the ATN, the current offset - /// from the token start index is assigned to all position-dependent lexer - /// actions which have not already been assigned a fixed offset. By storing - /// the offsets relative to the token start index, the DFA representation of - /// lexer actions which appear in the middle of tokens remains efficient due - /// to sharing among tokens of the same length, regardless of their absolute - /// position in the input stream. - /// - /// If the current executor already has offsets assigned to all - /// position-dependent lexer actions, the method returns {@code this}. - /// - /// The current offset to assign to all position-dependent - /// lexer actions which do not already have offsets assigned. - /// - /// A which stores input stream offsets - /// for all position-dependent lexer actions. - Ref fixOffsetBeforeMatch(int offset) const; - - /// - /// Gets the lexer actions to be executed by this executor. - /// The lexer actions to be executed by this executor. - const std::vector>& getLexerActions() const; - - /// - /// Execute the actions encapsulated by this executor within the context of a - /// particular . - /// - /// This method calls to set the position of the - /// {@code input} prior to calling - /// on a position-dependent action. Before the - /// method returns, the input position will be restored to the same position - /// it was in when the method was invoked. - /// - /// The lexer instance. - /// The input stream which is the source for the current token. - /// When this method is called, the current for - /// {@code input} should be the start of the following token, i.e. 1 - /// character past the end of the current token. - /// The token start index. This value may be passed to - /// to set the {@code input} position to the beginning - /// of the token. - void execute(Lexer *lexer, CharStream *input, size_t startIndex) const; - - size_t hashCode() const; - - bool equals(const LexerActionExecutor &other) const; - - private: - const std::vector> _lexerActions; - mutable std::atomic _hashCode; - }; - - inline bool operator==(const LexerActionExecutor &lhs, const LexerActionExecutor &rhs) { - return lhs.equals(rhs); - } - - inline bool operator!=(const LexerActionExecutor &lhs, const LexerActionExecutor &rhs) { - return !operator==(lhs, rhs); - } - -} // namespace atn -} // namespace antlr4 - -namespace std { - - template <> - struct hash<::antlr4::atn::LexerActionExecutor> { - size_t operator()(const ::antlr4::atn::LexerActionExecutor &lexerActionExecutor) const { - return lexerActionExecutor.hashCode(); - } - }; - -} // namespace std diff --git a/src/include/atn/LexerActionType.h b/src/include/atn/LexerActionType.h deleted file mode 100755 index aab40334..00000000 --- a/src/include/atn/LexerActionType.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - - /// - /// Represents the serialization type of a . - /// - /// @author Sam Harwell - /// @since 4.2 - /// - enum class LexerActionType : size_t { - /// - /// The type of a action. - /// - CHANNEL = 0, - /// - /// The type of a action. - /// - CUSTOM, - /// - /// The type of a action. - /// - MODE, - /// - /// The type of a action. - /// - MORE, - /// - /// The type of a action. - /// - POP_MODE, - /// - /// The type of a action. - /// - PUSH_MODE, - /// - /// The type of a action. - /// - SKIP, - /// - /// The type of a action. - /// - TYPE, - - INDEXED_CUSTOM, - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerChannelAction.cpp b/src/include/atn/LexerChannelAction.cpp deleted file mode 100755 index b6cda6cf..00000000 --- a/src/include/atn/LexerChannelAction.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "Lexer.h" -#include "support/Casts.h" - -#include "atn/LexerChannelAction.h" - -using namespace antlr4::atn; -using namespace antlr4::misc; -using namespace antlrcpp; - -LexerChannelAction::LexerChannelAction(int channel) - : LexerAction(LexerActionType::CHANNEL, false), _channel(channel) {} - -void LexerChannelAction::execute(Lexer *lexer) const { - lexer->setChannel(getChannel()); -} - -size_t LexerChannelAction::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getActionType())); - hash = MurmurHash::update(hash, getChannel()); - return MurmurHash::finish(hash, 2); -} - -bool LexerChannelAction::equals(const LexerAction &other) const { - if (this == std::addressof(other)) { - return true; - } - if (getActionType() != other.getActionType()) { - return false; - } - const auto &lexerAction = downCast(other); - return getChannel() == lexerAction.getChannel(); -} - -std::string LexerChannelAction::toString() const { - return "channel(" + std::to_string(getChannel()) + ")"; -} diff --git a/src/include/atn/LexerChannelAction.h b/src/include/atn/LexerChannelAction.h deleted file mode 100755 index 1a5c53ef..00000000 --- a/src/include/atn/LexerChannelAction.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/LexerAction.h" -#include "atn/LexerActionType.h" - -namespace antlr4 { -namespace atn { - - using antlr4::Lexer; - - /// - /// Implements the {@code channel} lexer action by calling - /// with the assigned channel. - /// - /// @author Sam Harwell - /// @since 4.2 - /// - class ANTLR4CPP_PUBLIC LexerChannelAction final : public LexerAction { - public: - static bool is(const LexerAction &lexerAction) { return lexerAction.getActionType() == LexerActionType::CHANNEL; } - - static bool is(const LexerAction *lexerAction) { return lexerAction != nullptr && is(*lexerAction); } - - /// - /// Constructs a new {@code channel} action with the specified channel value. - /// The channel value to pass to . - explicit LexerChannelAction(int channel); - - /// - /// Gets the channel to use for the created by the lexer. - /// - /// The channel to use for the created by the lexer. - int getChannel() const { return _channel; } - - /// - /// {@inheritDoc} - /// - /// This action is implemented by calling with the - /// value provided by . - /// - void execute(Lexer *lexer) const override; - - bool equals(const LexerAction &other) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - - private: - const int _channel; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerCustomAction.cpp b/src/include/atn/LexerCustomAction.cpp deleted file mode 100755 index b6edd89e..00000000 --- a/src/include/atn/LexerCustomAction.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "Lexer.h" -#include "support/Casts.h" - -#include "atn/LexerCustomAction.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::misc; -using namespace antlrcpp; - -LexerCustomAction::LexerCustomAction(size_t ruleIndex, size_t actionIndex) - : LexerAction(LexerActionType::CUSTOM, true), _ruleIndex(ruleIndex), _actionIndex(actionIndex) {} - -void LexerCustomAction::execute(Lexer *lexer) const { - lexer->action(nullptr, getRuleIndex(), getActionIndex()); -} - -size_t LexerCustomAction::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getActionType())); - hash = MurmurHash::update(hash, getRuleIndex()); - hash = MurmurHash::update(hash, getActionIndex()); - return MurmurHash::finish(hash, 3); -} - -bool LexerCustomAction::equals(const LexerAction &other) const { - if (this == std::addressof(other)) { - return true; - } - if (getActionType() != other.getActionType()) { - return false; - } - const auto &lexerAction = downCast(other); - return getRuleIndex() == lexerAction.getRuleIndex() && getActionIndex() == lexerAction.getActionIndex(); -} - -std::string LexerCustomAction::toString() const { - return "custom(" + std::to_string(getRuleIndex()) + ", " + std::to_string(getActionIndex()) + ")"; -} diff --git a/src/include/atn/LexerCustomAction.h b/src/include/atn/LexerCustomAction.h deleted file mode 100755 index 7973271c..00000000 --- a/src/include/atn/LexerCustomAction.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/LexerAction.h" -#include "atn/LexerActionType.h" - -namespace antlr4 { -namespace atn { - - /// - /// Executes a custom lexer action by calling with the - /// rule and action indexes assigned to the custom action. The implementation of - /// a custom action is added to the generated code for the lexer in an override - /// of when the grammar is compiled. - /// - /// This class may represent embedded actions created with the {...} - /// syntax in ANTLR 4, as well as actions created for lexer commands where the - /// command argument could not be evaluated when the grammar was compiled. - /// - /// @author Sam Harwell - /// @since 4.2 - /// - class ANTLR4CPP_PUBLIC LexerCustomAction final : public LexerAction { - public: - static bool is(const LexerAction &lexerAction) { return lexerAction.getActionType() == LexerActionType::CUSTOM; } - - static bool is(const LexerAction *lexerAction) { return lexerAction != nullptr && is(*lexerAction); } - - /// - /// Constructs a custom lexer action with the specified rule and action - /// indexes. - /// - /// The rule index to use for calls to - /// . - /// The action index to use for calls to - /// . - LexerCustomAction(size_t ruleIndex, size_t actionIndex); - - /// - /// Gets the rule index to use for calls to . - /// - /// The rule index for the custom action. - size_t getRuleIndex() const { return _ruleIndex; } - - /// - /// Gets the action index to use for calls to . - /// - /// The action index for the custom action. - size_t getActionIndex() const { return _actionIndex; } - - /// - /// {@inheritDoc} - /// - /// Custom actions are implemented by calling with the - /// appropriate rule and action indexes. - /// - void execute(Lexer *lexer) const override; - - bool equals(const LexerAction &other) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - - private: - const size_t _ruleIndex; - const size_t _actionIndex; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerIndexedCustomAction.cpp b/src/include/atn/LexerIndexedCustomAction.cpp deleted file mode 100755 index d4137af4..00000000 --- a/src/include/atn/LexerIndexedCustomAction.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/HashUtils.h" -#include "misc/MurmurHash.h" -#include "Lexer.h" -#include "support/CPPUtils.h" -#include "support/Casts.h" - -#include "atn/LexerIndexedCustomAction.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::misc; -using namespace antlrcpp; - -LexerIndexedCustomAction::LexerIndexedCustomAction(int offset, Ref action) - : LexerAction(LexerActionType::INDEXED_CUSTOM, true), _action(std::move(action)), _offset(offset) {} - -void LexerIndexedCustomAction::execute(Lexer *lexer) const { - // assume the input stream position was properly set by the calling code - getAction()->execute(lexer); -} - -size_t LexerIndexedCustomAction::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getActionType())); - hash = MurmurHash::update(hash, getOffset()); - hash = MurmurHash::update(hash, getAction()); - return MurmurHash::finish(hash, 3); -} - -bool LexerIndexedCustomAction::equals(const LexerAction &other) const { - if (this == std::addressof(other)) { - return true; - } - if (getActionType() != other.getActionType()) { - return false; - } - const auto &lexerAction = downCast(other); - return getOffset() == lexerAction.getOffset() && - cachedHashCodeEqual(cachedHashCode(), lexerAction.cachedHashCode()) && - *getAction() == *lexerAction.getAction(); -} - -std::string LexerIndexedCustomAction::toString() const { - return "indexedCustom(" + std::to_string(getOffset()) + ", " + getAction()->toString() + ")"; -} diff --git a/src/include/atn/LexerIndexedCustomAction.h b/src/include/atn/LexerIndexedCustomAction.h deleted file mode 100755 index 5693bac6..00000000 --- a/src/include/atn/LexerIndexedCustomAction.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "RuleContext.h" -#include "atn/LexerAction.h" - -namespace antlr4 { -namespace atn { - - /// - /// This implementation of is used for tracking input offsets - /// for position-dependent actions within a . - /// - /// This action is not serialized as part of the ATN, and is only required for - /// position-dependent lexer actions which appear at a location other than the - /// end of a rule. For more information about DFA optimizations employed for - /// lexer actions, see and - /// . - /// - /// @author Sam Harwell - /// @since 4.2 - /// - class ANTLR4CPP_PUBLIC LexerIndexedCustomAction final : public LexerAction { - public: - static bool is(const LexerAction &lexerAction) { return lexerAction.getActionType() == LexerActionType::INDEXED_CUSTOM; } - - static bool is(const LexerAction *lexerAction) { return lexerAction != nullptr && is(*lexerAction); } - - /// - /// Constructs a new indexed custom action by associating a character offset - /// with a . - /// - /// Note: This class is only required for lexer actions for which - /// returns {@code true}. - /// - /// The offset into the input , relative to - /// the token start index, at which the specified lexer action should be - /// executed. - /// The lexer action to execute at a particular offset in the - /// input . - LexerIndexedCustomAction(int offset, Ref action); - - /// - /// Gets the location in the input at which the lexer - /// action should be executed. The value is interpreted as an offset relative - /// to the token start index. - /// - /// The location in the input at which the lexer - /// action should be executed. - int getOffset() const { return _offset; } - - /// - /// Gets the lexer action to execute. - /// - /// A object which executes the lexer action. - const Ref& getAction() const { return _action; } - - void execute(Lexer *lexer) const override; - bool equals(const LexerAction &other) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - - private: - const Ref _action; - const int _offset; - }; - -} // namespace atn -} // namespace antlr4 - diff --git a/src/include/atn/LexerModeAction.cpp b/src/include/atn/LexerModeAction.cpp deleted file mode 100755 index a4ca3b3d..00000000 --- a/src/include/atn/LexerModeAction.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "Lexer.h" -#include "support/Casts.h" - -#include "atn/LexerModeAction.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::misc; -using namespace antlrcpp; - -LexerModeAction::LexerModeAction(int mode) : LexerAction(LexerActionType::MODE, false), _mode(mode) {} - -void LexerModeAction::execute(Lexer *lexer) const { - lexer->setMode(getMode()); -} - -size_t LexerModeAction::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getActionType())); - hash = MurmurHash::update(hash, getMode()); - return MurmurHash::finish(hash, 2); -} - -bool LexerModeAction::equals(const LexerAction &other) const { - if (this == std::addressof(other)) { - return true; - } - if (getActionType() != other.getActionType()) { - return false; - } - const auto &lexerAction = downCast(other); - return getMode() == lexerAction.getMode(); -} - -std::string LexerModeAction::toString() const { - return "mode(" + std::to_string(getMode()) + ")"; -} diff --git a/src/include/atn/LexerModeAction.h b/src/include/atn/LexerModeAction.h deleted file mode 100755 index 6fa61a2e..00000000 --- a/src/include/atn/LexerModeAction.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/LexerAction.h" -#include "atn/LexerActionType.h" - -namespace antlr4 { -namespace atn { - - /// - /// Implements the {@code mode} lexer action by calling with - /// the assigned mode. - /// - /// @author Sam Harwell - /// @since 4.2 - /// - class ANTLR4CPP_PUBLIC LexerModeAction final : public LexerAction { - public: - static bool is(const LexerAction &lexerAction) { return lexerAction.getActionType() == LexerActionType::MODE; } - - static bool is(const LexerAction *lexerAction) { return lexerAction != nullptr && is(*lexerAction); } - - /// - /// Constructs a new {@code mode} action with the specified mode value. - /// The mode value to pass to . - explicit LexerModeAction(int mode); - - /// - /// Get the lexer mode this action should transition the lexer to. - /// - /// The lexer mode for this {@code mode} command. - int getMode() const { return _mode; } - - /// - /// {@inheritDoc} - /// - /// This action is implemented by calling with the - /// value provided by . - /// - void execute(Lexer *lexer) const override; - - bool equals(const LexerAction &obj) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - - private: - const int _mode; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerMoreAction.cpp b/src/include/atn/LexerMoreAction.cpp deleted file mode 100755 index 30df87b7..00000000 --- a/src/include/atn/LexerMoreAction.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "Lexer.h" - -#include "atn/LexerMoreAction.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::misc; - -const Ref& LexerMoreAction::getInstance() { - static const Ref instance(new LexerMoreAction()); - return instance; -} - -void LexerMoreAction::execute(Lexer *lexer) const { - lexer->more(); -} - -size_t LexerMoreAction::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getActionType())); - return MurmurHash::finish(hash, 1); -} - -bool LexerMoreAction::equals(const LexerAction &other) const { - return this == std::addressof(other); -} - -std::string LexerMoreAction::toString() const { - return "more"; -} diff --git a/src/include/atn/LexerMoreAction.h b/src/include/atn/LexerMoreAction.h deleted file mode 100755 index fc4b8fcb..00000000 --- a/src/include/atn/LexerMoreAction.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/LexerAction.h" -#include "atn/LexerActionType.h" - -namespace antlr4 { -namespace atn { - - /// - /// Implements the {@code more} lexer action by calling . - /// - /// The {@code more} command does not have any parameters, so this action is - /// implemented as a singleton instance exposed by . - /// - /// @author Sam Harwell - /// @since 4.2 - /// - class ANTLR4CPP_PUBLIC LexerMoreAction final : public LexerAction { - public: - static bool is(const LexerAction &lexerAction) { return lexerAction.getActionType() == LexerActionType::MORE; } - - static bool is(const LexerAction *lexerAction) { return lexerAction != nullptr && is(*lexerAction); } - - /// - /// Provides a singleton instance of this parameterless lexer action. - /// - static const Ref& getInstance(); - - /// - /// {@inheritDoc} - /// - /// This action is implemented by calling . - /// - void execute(Lexer *lexer) const override; - - bool equals(const LexerAction &obj) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - - private: - /// Constructs the singleton instance of the lexer {@code more} command. - LexerMoreAction() : LexerAction(LexerActionType::MORE, false) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerPopModeAction.cpp b/src/include/atn/LexerPopModeAction.cpp deleted file mode 100755 index 51920493..00000000 --- a/src/include/atn/LexerPopModeAction.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "Lexer.h" - -#include "atn/LexerPopModeAction.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::misc; - -const Ref& LexerPopModeAction::getInstance() { - static const Ref instance(new LexerPopModeAction()); - return instance; -} - -void LexerPopModeAction::execute(Lexer *lexer) const { - lexer->popMode(); -} - -size_t LexerPopModeAction::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getActionType())); - return MurmurHash::finish(hash, 1); -} - -bool LexerPopModeAction::equals(const LexerAction &other) const { - return this == std::addressof(other); -} - -std::string LexerPopModeAction::toString() const { - return "popMode"; -} diff --git a/src/include/atn/LexerPopModeAction.h b/src/include/atn/LexerPopModeAction.h deleted file mode 100755 index 8d712cad..00000000 --- a/src/include/atn/LexerPopModeAction.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/LexerAction.h" -#include "atn/LexerActionType.h" - -namespace antlr4 { -namespace atn { - - /// - /// Implements the {@code popMode} lexer action by calling . - /// - /// The {@code popMode} command does not have any parameters, so this action is - /// implemented as a singleton instance exposed by . - /// - /// @author Sam Harwell - /// @since 4.2 - /// - class ANTLR4CPP_PUBLIC LexerPopModeAction final : public LexerAction { - public: - static bool is(const LexerAction &lexerAction) { return lexerAction.getActionType() == LexerActionType::POP_MODE; } - - static bool is(const LexerAction *lexerAction) { return lexerAction != nullptr && is(*lexerAction); } - - /// - /// Provides a singleton instance of this parameterless lexer action. - /// - static const Ref& getInstance(); - - /// - /// {@inheritDoc} - /// - /// This action is implemented by calling . - /// - void execute(Lexer *lexer) const override; - - bool equals(const LexerAction &other) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - - private: - /// Constructs the singleton instance of the lexer {@code popMode} command. - LexerPopModeAction() : LexerAction(LexerActionType::POP_MODE, false) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerPushModeAction.cpp b/src/include/atn/LexerPushModeAction.cpp deleted file mode 100755 index 3ebd21fa..00000000 --- a/src/include/atn/LexerPushModeAction.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "Lexer.h" -#include "support/Casts.h" - -#include "atn/LexerPushModeAction.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::misc; -using namespace antlrcpp; - -LexerPushModeAction::LexerPushModeAction(int mode) : LexerAction(LexerActionType::PUSH_MODE, false), _mode(mode) {} - -void LexerPushModeAction::execute(Lexer *lexer) const { - lexer->pushMode(getMode()); -} - -size_t LexerPushModeAction::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getActionType())); - hash = MurmurHash::update(hash, getMode()); - return MurmurHash::finish(hash, 2); -} - -bool LexerPushModeAction::equals(const LexerAction &other) const { - if (this == std::addressof(other)) { - return true; - } - if (getActionType() != other.getActionType()) { - return false; - } - const auto &lexerAction = downCast(other); - return getMode() == lexerAction.getMode(); -} - -std::string LexerPushModeAction::toString() const { - return "pushMode(" + std::to_string(getMode()) + ")"; -} diff --git a/src/include/atn/LexerPushModeAction.h b/src/include/atn/LexerPushModeAction.h deleted file mode 100755 index 32b706b5..00000000 --- a/src/include/atn/LexerPushModeAction.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/LexerAction.h" -#include "atn/LexerActionType.h" - -namespace antlr4 { -namespace atn { - - /// - /// Implements the {@code pushMode} lexer action by calling - /// with the assigned mode. - /// - /// @author Sam Harwell - /// @since 4.2 - /// - class ANTLR4CPP_PUBLIC LexerPushModeAction final : public LexerAction { - public: - static bool is(const LexerAction &lexerAction) { return lexerAction.getActionType() == LexerActionType::PUSH_MODE; } - - static bool is(const LexerAction *lexerAction) { return lexerAction != nullptr && is(*lexerAction); } - - /// - /// Constructs a new {@code pushMode} action with the specified mode value. - /// The mode value to pass to . - explicit LexerPushModeAction(int mode); - - /// - /// Get the lexer mode this action should transition the lexer to. - /// - /// The lexer mode for this {@code pushMode} command. - int getMode() const { return _mode; } - - /// - /// {@inheritDoc} - /// - /// This action is implemented by calling with the - /// value provided by . - /// - void execute(Lexer *lexer) const override; - - bool equals(const LexerAction &obj) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - - private: - const int _mode; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerSkipAction.cpp b/src/include/atn/LexerSkipAction.cpp deleted file mode 100755 index 72f9de3e..00000000 --- a/src/include/atn/LexerSkipAction.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "Lexer.h" - -#include "atn/LexerSkipAction.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::misc; - -const Ref& LexerSkipAction::getInstance() { - static const Ref instance(new LexerSkipAction()); - return instance; -} - -void LexerSkipAction::execute(Lexer *lexer) const { - lexer->skip(); -} - -size_t LexerSkipAction::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getActionType())); - return MurmurHash::finish(hash, 1); -} - -bool LexerSkipAction::equals(const LexerAction &other) const { - return this == std::addressof(other); -} - -std::string LexerSkipAction::toString() const { - return "skip"; -} diff --git a/src/include/atn/LexerSkipAction.h b/src/include/atn/LexerSkipAction.h deleted file mode 100755 index afdf4702..00000000 --- a/src/include/atn/LexerSkipAction.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/LexerAction.h" -#include "atn/LexerActionType.h" - -namespace antlr4 { -namespace atn { - - /// - /// Implements the {@code skip} lexer action by calling . - /// - /// The {@code skip} command does not have any parameters, so this action is - /// implemented as a singleton instance exposed by . - /// - /// @author Sam Harwell - /// @since 4.2 - /// - class ANTLR4CPP_PUBLIC LexerSkipAction final : public LexerAction { - public: - static bool is(const LexerAction &lexerAction) { return lexerAction.getActionType() == LexerActionType::SKIP; } - - static bool is(const LexerAction *lexerAction) { return lexerAction != nullptr && is(*lexerAction); } - - /// Provides a singleton instance of this parameterless lexer action. - static const Ref& getInstance(); - - /// - /// {@inheritDoc} - /// - /// This action is implemented by calling . - /// - void execute(Lexer *lexer) const override; - - bool equals(const LexerAction &obj) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - - private: - /// Constructs the singleton instance of the lexer {@code skip} command. - LexerSkipAction() : LexerAction(LexerActionType::SKIP, false) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LexerTypeAction.cpp b/src/include/atn/LexerTypeAction.cpp deleted file mode 100755 index 55ccf358..00000000 --- a/src/include/atn/LexerTypeAction.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "Lexer.h" -#include "support/Casts.h" - -#include "atn/LexerTypeAction.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::misc; -using namespace antlrcpp; - -LexerTypeAction::LexerTypeAction(int type) : LexerAction(LexerActionType::TYPE, false), _type(type) {} - -void LexerTypeAction::execute(Lexer *lexer) const { - lexer->setType(getType()); -} - -size_t LexerTypeAction::hashCodeImpl() const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, static_cast(getActionType())); - hash = MurmurHash::update(hash, getType()); - return MurmurHash::finish(hash, 2); -} - -bool LexerTypeAction::equals(const LexerAction &other) const { - if (this == std::addressof(other)) { - return true; - } - if (getActionType() != other.getActionType()) { - return false; - } - const auto &lexerAction = downCast(other); - return getType() == lexerAction.getType(); -} - -std::string LexerTypeAction::toString() const { - return "type(" + std::to_string(getType()) + ")"; -} diff --git a/src/include/atn/LexerTypeAction.h b/src/include/atn/LexerTypeAction.h deleted file mode 100755 index 1cd7d71f..00000000 --- a/src/include/atn/LexerTypeAction.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/LexerActionType.h" -#include "atn/LexerAction.h" - -namespace antlr4 { -namespace atn { - - /// Implements the {@code type} lexer action by calling - /// with the assigned type. - class ANTLR4CPP_PUBLIC LexerTypeAction final : public LexerAction { - public: - static bool is(const LexerAction &lexerAction) { return lexerAction.getActionType() == LexerActionType::TYPE; } - - static bool is(const LexerAction *lexerAction) { return lexerAction != nullptr && is(*lexerAction); } - - /// - /// Constructs a new {@code type} action with the specified token type value. - /// The type to assign to the token using . - explicit LexerTypeAction(int type); - - /// - /// Gets the type to assign to a token created by the lexer. - /// The type to assign to a token created by the lexer. - int getType() const { return _type; } - - /// - /// {@inheritDoc} - /// - /// This action is implemented by calling with the - /// value provided by . - /// - void execute(Lexer *lexer) const override; - - bool equals(const LexerAction &obj) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - - private: - const int _type; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LookaheadEventInfo.cpp b/src/include/atn/LookaheadEventInfo.cpp deleted file mode 100755 index aa3f9124..00000000 --- a/src/include/atn/LookaheadEventInfo.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/LookaheadEventInfo.h" - -using namespace antlr4; -using namespace antlr4::atn; - -LookaheadEventInfo::LookaheadEventInfo(size_t decision, ATNConfigSet *configs, size_t predictedAlt, - TokenStream *input, size_t startIndex, size_t stopIndex, bool fullCtx) - : DecisionEventInfo(decision, configs, input, startIndex, stopIndex, fullCtx) { - - this->predictedAlt = predictedAlt; -} diff --git a/src/include/atn/LookaheadEventInfo.h b/src/include/atn/LookaheadEventInfo.h deleted file mode 100755 index f5fc24fd..00000000 --- a/src/include/atn/LookaheadEventInfo.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionEventInfo.h" - -namespace antlr4 { -namespace atn { - - /// This class represents profiling event information for tracking the lookahead - /// depth required in order to make a prediction. - class ANTLR4CPP_PUBLIC LookaheadEventInfo : public DecisionEventInfo { - public: - /// The alternative chosen by adaptivePredict(), not necessarily - /// the outermost alt shown for a rule; left-recursive rules have - /// user-level alts that differ from the rewritten rule with a (...) block - /// and a (..)* loop. - size_t predictedAlt = 0; - - /// - /// Constructs a new instance of the class with - /// the specified detailed lookahead information. - /// - /// The decision number - /// The final configuration set containing the necessary - /// information to determine the result of a prediction, or {@code null} if - /// the final configuration set is not available - /// The input token stream - /// The start index for the current prediction - /// The index at which the prediction was finally made - /// {@code true} if the current lookahead is part of an LL - /// prediction; otherwise, {@code false} if the current lookahead is part of - /// an SLL prediction - LookaheadEventInfo(size_t decision, ATNConfigSet *configs, size_t predictedAlt, TokenStream *input, size_t startIndex, - size_t stopIndex, bool fullCtx); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/LoopEndState.h b/src/include/atn/LoopEndState.h deleted file mode 100755 index b680414e..00000000 --- a/src/include/atn/LoopEndState.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNState.h" - -namespace antlr4 { -namespace atn { - - /// Mark the end of a * or + loop. - class ANTLR4CPP_PUBLIC LoopEndState final : public ATNState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::LOOP_END; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - ATNState *loopBackState = nullptr; - - LoopEndState() : ATNState(ATNStateType::LOOP_END) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/NotSetTransition.cpp b/src/include/atn/NotSetTransition.cpp deleted file mode 100755 index b652290d..00000000 --- a/src/include/atn/NotSetTransition.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/NotSetTransition.h" -#include "atn/ATNState.h" -#include "misc/IntervalSet.h" - -using namespace antlr4; -using namespace antlr4::atn; - -NotSetTransition::NotSetTransition(ATNState *target, misc::IntervalSet set) : SetTransition(TransitionType::NOT_SET, target, std::move(set)) {} - -bool NotSetTransition::matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const { - return symbol >= minVocabSymbol && symbol <= maxVocabSymbol - && !SetTransition::matches(symbol, minVocabSymbol, maxVocabSymbol); -} - -std::string NotSetTransition::toString() const { - return "NOT_SET " + Transition::toString() + " { " + SetTransition::toString() + " }"; -} diff --git a/src/include/atn/NotSetTransition.h b/src/include/atn/NotSetTransition.h deleted file mode 100755 index 5c88ec10..00000000 --- a/src/include/atn/NotSetTransition.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/SetTransition.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC NotSetTransition final : public SetTransition { - public: - static bool is(const Transition &transition) { return transition.getTransitionType() == TransitionType::NOT_SET; } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - NotSetTransition(ATNState *target, misc::IntervalSet set); - - virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - - virtual std::string toString() const override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/OrderedATNConfigSet.cpp b/src/include/atn/OrderedATNConfigSet.cpp deleted file mode 100755 index a7e76cd1..00000000 --- a/src/include/atn/OrderedATNConfigSet.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/OrderedATNConfigSet.h" - -using namespace antlr4::atn; - -size_t OrderedATNConfigSet::hashCode(const ATNConfig &atnConfig) const { - return atnConfig.hashCode(); -} - -bool OrderedATNConfigSet::equals(const ATNConfig &lhs, const ATNConfig &rhs) const { - return lhs == rhs; -} diff --git a/src/include/atn/OrderedATNConfigSet.h b/src/include/atn/OrderedATNConfigSet.h deleted file mode 100755 index b6b344fd..00000000 --- a/src/include/atn/OrderedATNConfigSet.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNConfigSet.h" -#include "atn/ATNConfig.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC OrderedATNConfigSet final : public ATNConfigSet { - public: - OrderedATNConfigSet() = default; - - private: - size_t hashCode(const ATNConfig &atnConfig) const override; - - bool equals(const ATNConfig &lhs, const ATNConfig &rhs) const override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ParseInfo.cpp b/src/include/atn/ParseInfo.cpp deleted file mode 100755 index 95a89ac8..00000000 --- a/src/include/atn/ParseInfo.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ProfilingATNSimulator.h" -#include "dfa/DFA.h" - -#include "atn/ParseInfo.h" - -using namespace antlr4::atn; - -ParseInfo::ParseInfo(ProfilingATNSimulator *atnSimulator) : _atnSimulator(atnSimulator) { -} - -ParseInfo::~ParseInfo() { -} - -std::vector ParseInfo::getDecisionInfo() { - return _atnSimulator->getDecisionInfo(); -} - -std::vector ParseInfo::getLLDecisions() { - std::vector decisions = _atnSimulator->getDecisionInfo(); - std::vector LL; - for (size_t i = 0; i < decisions.size(); ++i) { - long long fallBack = decisions[i].LL_Fallback; - if (fallBack > 0) { - LL.push_back(i); - } - } - return LL; -} - -long long ParseInfo::getTotalTimeInPrediction() { - std::vector decisions = _atnSimulator->getDecisionInfo(); - long long t = 0; - for (size_t i = 0; i < decisions.size(); ++i) { - t += decisions[i].timeInPrediction; - } - return t; -} - -long long ParseInfo::getTotalSLLLookaheadOps() { - std::vector decisions = _atnSimulator->getDecisionInfo(); - long long k = 0; - for (size_t i = 0; i < decisions.size(); ++i) { - k += decisions[i].SLL_TotalLook; - } - return k; -} - -long long ParseInfo::getTotalLLLookaheadOps() { - std::vector decisions = _atnSimulator->getDecisionInfo(); - long long k = 0; - for (size_t i = 0; i < decisions.size(); i++) { - k += decisions[i].LL_TotalLook; - } - return k; -} - -long long ParseInfo::getTotalSLLATNLookaheadOps() { - std::vector decisions = _atnSimulator->getDecisionInfo(); - long long k = 0; - for (size_t i = 0; i < decisions.size(); ++i) { - k += decisions[i].SLL_ATNTransitions; - } - return k; -} - -long long ParseInfo::getTotalLLATNLookaheadOps() { - std::vector decisions = _atnSimulator->getDecisionInfo(); - long long k = 0; - for (size_t i = 0; i < decisions.size(); ++i) { - k += decisions[i].LL_ATNTransitions; - } - return k; -} - -long long ParseInfo::getTotalATNLookaheadOps() { - std::vector decisions = _atnSimulator->getDecisionInfo(); - long long k = 0; - for (size_t i = 0; i < decisions.size(); ++i) { - k += decisions[i].SLL_ATNTransitions; - k += decisions[i].LL_ATNTransitions; - } - return k; -} - -size_t ParseInfo::getDFASize() { - size_t n = 0; - std::vector &decisionToDFA = _atnSimulator->decisionToDFA; - for (size_t i = 0; i < decisionToDFA.size(); ++i) { - n += getDFASize(i); - } - return n; -} - -size_t ParseInfo::getDFASize(size_t decision) { - dfa::DFA &decisionToDFA = _atnSimulator->decisionToDFA[decision]; - return decisionToDFA.states.size(); -} diff --git a/src/include/atn/ParseInfo.h b/src/include/atn/ParseInfo.h deleted file mode 100755 index 7ced7de4..00000000 --- a/src/include/atn/ParseInfo.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionInfo.h" - -namespace antlr4 { -namespace atn { - - class ProfilingATNSimulator; - - /// This class provides access to specific and aggregate statistics gathered - /// during profiling of a parser. - class ANTLR4CPP_PUBLIC ParseInfo { - public: - ParseInfo(ProfilingATNSimulator *atnSimulator); - ParseInfo(ParseInfo const&) = default; - virtual ~ParseInfo(); - - ParseInfo& operator=(ParseInfo const&) = default; - - /// - /// Gets an array of instances containing the profiling - /// information gathered for each decision in the ATN. - /// - /// An array of instances, indexed by decision - /// number. - virtual std::vector getDecisionInfo(); - - /// - /// Gets the decision numbers for decisions that required one or more - /// full-context predictions during parsing. These are decisions for which - /// is non-zero. - /// - /// A list of decision numbers which required one or more - /// full-context predictions during parsing. - virtual std::vector getLLDecisions(); - - /// - /// Gets the total time spent during prediction across all decisions made - /// during parsing. This value is the sum of - /// for all decisions. - /// - virtual long long getTotalTimeInPrediction(); - - /// - /// Gets the total number of SLL lookahead operations across all decisions - /// made during parsing. This value is the sum of - /// for all decisions. - /// - virtual long long getTotalSLLLookaheadOps(); - - /// - /// Gets the total number of LL lookahead operations across all decisions - /// made during parsing. This value is the sum of - /// for all decisions. - /// - virtual long long getTotalLLLookaheadOps(); - - /// - /// Gets the total number of ATN lookahead operations for SLL prediction - /// across all decisions made during parsing. - /// - virtual long long getTotalSLLATNLookaheadOps(); - - /// - /// Gets the total number of ATN lookahead operations for LL prediction - /// across all decisions made during parsing. - /// - virtual long long getTotalLLATNLookaheadOps(); - - /// - /// Gets the total number of ATN lookahead operations for SLL and LL - /// prediction across all decisions made during parsing. - /// - /// - /// This value is the sum of and - /// . - /// - virtual long long getTotalATNLookaheadOps(); - - /// - /// Gets the total number of DFA states stored in the DFA cache for all - /// decisions in the ATN. - /// - virtual size_t getDFASize(); - - /// - /// Gets the total number of DFA states stored in the DFA cache for a - /// particular decision. - /// - virtual size_t getDFASize(size_t decision); - - protected: - const ProfilingATNSimulator *_atnSimulator; // non-owning, we are created by this simulator. - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ParserATNSimulator.cpp b/src/include/atn/ParserATNSimulator.cpp deleted file mode 100755 index 3a153758..00000000 --- a/src/include/atn/ParserATNSimulator.cpp +++ /dev/null @@ -1,1413 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "dfa/DFA.h" -#include "NoViableAltException.h" -#include "atn/DecisionState.h" -#include "ParserRuleContext.h" -#include "misc/IntervalSet.h" -#include "Parser.h" -#include "CommonTokenStream.h" -#include "atn/NotSetTransition.h" -#include "atn/AtomTransition.h" -#include "atn/RuleTransition.h" -#include "atn/PredicateTransition.h" -#include "atn/PrecedencePredicateTransition.h" -#include "atn/SingletonPredictionContext.h" -#include "atn/ActionTransition.h" -#include "atn/EpsilonTransition.h" -#include "atn/RuleStopState.h" -#include "atn/ATNConfigSet.h" -#include "atn/ATNConfig.h" -#include "internal/Synchronization.h" - -#include "atn/StarLoopEntryState.h" -#include "atn/BlockStartState.h" -#include "atn/BlockEndState.h" - -#include "misc/Interval.h" -#include "ANTLRErrorListener.h" - -#include "Vocabulary.h" -#include "support/Arrays.h" -#include "support/Casts.h" - -#include "atn/ParserATNSimulator.h" - -#ifndef DEBUG_ATN -#define DEBUG_ATN 0 -#endif -#ifndef TRACE_ATN_SIM -#define TRACE_ATN_SIM 0 -#endif -#ifndef DFA_DEBUG -#define DFA_DEBUG 0 -#endif -#ifndef RETRY_DEBUG -#define RETRY_DEBUG 0 -#endif - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::internal; -using namespace antlrcpp; - -const bool ParserATNSimulator::TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT = ParserATNSimulator::getLrLoopSetting(); - -ParserATNSimulator::ParserATNSimulator(const ATN &atn, std::vector &decisionToDFA, - PredictionContextCache &sharedContextCache) -: ParserATNSimulator(nullptr, atn, decisionToDFA, sharedContextCache) { -} - -ParserATNSimulator::ParserATNSimulator(Parser *parser, const ATN &atn, std::vector &decisionToDFA, - PredictionContextCache &sharedContextCache) -: ParserATNSimulator(parser, atn, decisionToDFA, sharedContextCache, ParserATNSimulatorOptions()) {} - -ParserATNSimulator::ParserATNSimulator(Parser *parser, const ATN &atn, std::vector &decisionToDFA, - PredictionContextCache &sharedContextCache, - const ParserATNSimulatorOptions &options) -: ATNSimulator(atn, sharedContextCache), decisionToDFA(decisionToDFA), parser(parser), - mergeCache(options.getPredictionContextMergeCacheOptions()) { - InitializeInstanceFields(); -} - -void ParserATNSimulator::reset() { -} - -void ParserATNSimulator::clearDFA() { - int size = (int)decisionToDFA.size(); - decisionToDFA.clear(); - for (int d = 0; d < size; ++d) { - decisionToDFA.push_back(dfa::DFA(atn.getDecisionState(d), d)); - } -} - -size_t ParserATNSimulator::adaptivePredict(TokenStream *input, size_t decision, ParserRuleContext *outerContext) { - -#if DEBUG_ATN == 1 || TRACE_ATN_SIM == 1 - std::cout << "adaptivePredict decision " << decision << " exec LA(1)==" << getLookaheadName(input) << " line " - << input->LT(1)->getLine() << ":" << input->LT(1)->getCharPositionInLine() << std::endl; -#endif - - _input = input; - _startIndex = input->index(); - _outerContext = outerContext; - dfa::DFA &dfa = decisionToDFA[decision]; - _dfa = &dfa; - - ssize_t m = input->mark(); - size_t index = _startIndex; - - // Now we are certain to have a specific decision's DFA - // But, do we still need an initial state? - auto onExit = finally([this, input, index, m] { - if (mergeCache.getOptions().getClearEveryN() != 0) { - if (++_mergeCacheCounter == mergeCache.getOptions().getClearEveryN()) { - mergeCache.clear(); - _mergeCacheCounter = 0; - } - } - _dfa = nullptr; - input->seek(index); - input->release(m); - }); - - dfa::DFAState *s0; - { - SharedLock stateLock(atn._stateMutex); - if (dfa.isPrecedenceDfa()) { - // the start state for a precedence DFA depends on the current - // parser precedence, and is provided by a DFA method. - SharedLock edgeLock(atn._edgeMutex); - s0 = dfa.getPrecedenceStartState(parser->getPrecedence()); - } else { - // the start state for a "regular" DFA is just s0 - s0 = dfa.s0; - } - } - - if (s0 == nullptr) { - auto s0_closure = computeStartState(dfa.atnStartState, &ParserRuleContext::EMPTY, false); - std::unique_ptr newState; - std::unique_ptr oldState; - UniqueLock stateLock(atn._stateMutex); - dfa::DFAState* ds0 = dfa.s0; - if (dfa.isPrecedenceDfa()) { - /* If this is a precedence DFA, we use applyPrecedenceFilter - * to convert the computed start state to a precedence start - * state. We then use DFA.setPrecedenceStartState to set the - * appropriate start state for the precedence level rather - * than simply setting DFA.s0. - */ - ds0->configs = std::move(s0_closure); // not used for prediction but useful to know start configs anyway - newState = std::make_unique(applyPrecedenceFilter(ds0->configs.get())); - s0 = addDFAState(dfa, newState.get()); - UniqueLock edgeLock(atn._edgeMutex); - dfa.setPrecedenceStartState(parser->getPrecedence(), s0); - } else { - newState = std::make_unique(std::move(s0_closure)); - s0 = addDFAState(dfa, newState.get()); - if (ds0 != s0) { - oldState.reset(ds0); - dfa.s0 = s0; - } - } - if (s0 == newState.get()) { - newState.release(); - } - } - - // We can start with an existing DFA. - size_t alt = execATN(dfa, s0, input, index, outerContext != nullptr ? outerContext : &ParserRuleContext::EMPTY); - - return alt; -} - -size_t ParserATNSimulator::execATN(dfa::DFA &dfa, dfa::DFAState *s0, TokenStream *input, size_t startIndex, - ParserRuleContext *outerContext) { - -#if DEBUG_ATN == 1 || TRACE_ATN_SIM == 1 - std::cout << "execATN decision " << dfa.decision << ", DFA state " << s0->toString() << - ", LA(1)==" << getLookaheadName(input) << - " line " << input->LT(1)->getLine() << ":" << input->LT(1)->getCharPositionInLine() << std::endl; -#endif - - dfa::DFAState *previousD = s0; - -#if DEBUG_ATN == 1 - std::cout << "s0 = " << s0->toString() << std::endl; -#endif - - size_t t = input->LA(1); - - while (true) { // while more work - dfa::DFAState *D = getExistingTargetState(previousD, t); - if (D == nullptr) { - D = computeTargetState(dfa, previousD, t); - } - - if (D == ERROR.get()) { - // if any configs in previous dipped into outer context, that - // means that input up to t actually finished entry rule - // at least for SLL decision. Full LL doesn't dip into outer - // so don't need special case. - // We will get an error no matter what so delay until after - // decision; better error message. Also, no reachable target - // ATN states in SLL implies LL will also get nowhere. - // If conflict in states that dip out, choose min since we - // will get error no matter what. - NoViableAltException e = noViableAlt(input, outerContext, previousD->configs.get(), startIndex, false); - input->seek(startIndex); - size_t alt = getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previousD->configs.get(), outerContext); - if (alt != ATN::INVALID_ALT_NUMBER) { - return alt; - } - - throw e; - } - - if (D->requiresFullContext && _mode != PredictionMode::SLL) { - // IF PREDS, MIGHT RESOLVE TO SINGLE ALT => SLL (or syntax error) - BitSet conflictingAlts; - if (D->predicates.size() != 0) { -#if DEBUG_ATN == 1 - std::cout << "DFA state has preds in DFA sim LL failover" << std::endl; -#endif - - size_t conflictIndex = input->index(); - if (conflictIndex != startIndex) { - input->seek(startIndex); - } - - conflictingAlts = evalSemanticContext(D->predicates, outerContext, true); - if (conflictingAlts.count() == 1) { -#if DEBUG_ATN == 1 - std::cout << "Full LL avoided" << std::endl; -#endif - - return conflictingAlts.nextSetBit(0); - } - - if (conflictIndex != startIndex) { - // restore the index so reporting the fallback to full - // context occurs with the index at the correct spot - input->seek(conflictIndex); - } - } - -#if DFA_DEBUG == 1 - std::cout << "ctx sensitive state " << outerContext << " in " << D << std::endl; -#endif - - bool fullCtx = true; - std::unique_ptr s0_closure = computeStartState(dfa.atnStartState, outerContext, fullCtx); - reportAttemptingFullContext(dfa, conflictingAlts, D->configs.get(), startIndex, input->index()); - size_t alt = execATNWithFullContext(dfa, D, s0_closure.get(), input, startIndex, outerContext); - return alt; - } - - if (D->isAcceptState) { - if (D->predicates.empty()) { - return D->prediction; - } - - size_t stopIndex = input->index(); - input->seek(startIndex); - BitSet alts = evalSemanticContext(D->predicates, outerContext, true); - switch (alts.count()) { - case 0: - throw noViableAlt(input, outerContext, D->configs.get(), startIndex, false); - - case 1: - 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.get()); - return alts.nextSetBit(0); - } - } - - previousD = D; - - if (t != Token::EOF) { - input->consume(); - t = input->LA(1); - } - } -} - -dfa::DFAState *ParserATNSimulator::getExistingTargetState(dfa::DFAState *previousD, size_t t) { - dfa::DFAState* retval; - SharedLock edgeLock(atn._edgeMutex); - auto iterator = previousD->edges.find(t); - retval = (iterator == previousD->edges.end()) ? nullptr : iterator->second; - return retval; -} - -dfa::DFAState *ParserATNSimulator::computeTargetState(dfa::DFA &dfa, dfa::DFAState *previousD, size_t t) { - std::unique_ptr reach = computeReachSet(previousD->configs.get(), t, false); - if (reach == nullptr) { - addDFAEdge(dfa, previousD, t, ERROR.get()); - return ERROR.get(); - } - - // create new target state; we'll add to DFA after it's complete - dfa::DFAState *D = new dfa::DFAState(std::move(reach)); /* mem-check: managed by the DFA or deleted below, "reach" is no longer valid now. */ - size_t predictedAlt = getUniqueAlt(D->configs.get()); - - if (predictedAlt != ATN::INVALID_ALT_NUMBER) { - // NO CONFLICT, UNIQUELY PREDICTED ALT - D->isAcceptState = true; - D->configs->uniqueAlt = predictedAlt; - D->prediction = predictedAlt; - } else if (PredictionModeClass::hasSLLConflictTerminatingPrediction(_mode, D->configs.get())) { - // MORE THAN ONE VIABLE ALTERNATIVE - D->configs->conflictingAlts = getConflictingAlts(D->configs.get()); - 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); - } - - if (D->isAcceptState && D->configs->hasSemanticContext) { - predicateDFAState(D, atn.getDecisionState(dfa.decision)); - if (D->predicates.size() != 0) { - D->prediction = ATN::INVALID_ALT_NUMBER; - } - } - - // all adds to dfa are done after we've created full D state - dfa::DFAState *state = addDFAEdge(dfa, previousD, t, D); - if (state != D) { - delete D; // If the new state exists already we don't need it and use the existing one instead. - } - return state; -} - -void ParserATNSimulator::predicateDFAState(dfa::DFAState *dfaState, DecisionState *decisionState) { - // We need to test all predicates, even in DFA states that - // uniquely predict alternative. - size_t nalts = decisionState->transitions.size(); - - // Update DFA so reach becomes accept state with (predicate,alt) - // pairs if preds found for conflicting alts - BitSet altsToCollectPredsFrom = getConflictingAltsOrUniqueAlt(dfaState->configs.get()); - std::vector> altToPred = getPredsForAmbigAlts(altsToCollectPredsFrom, dfaState->configs.get(), nalts); - if (!altToPred.empty()) { - dfaState->predicates = getPredicatePredictions(altsToCollectPredsFrom, altToPred); - dfaState->prediction = ATN::INVALID_ALT_NUMBER; // make sure we use preds - } else { - // 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); - } -} - -size_t ParserATNSimulator::execATNWithFullContext(dfa::DFA &dfa, dfa::DFAState *D, ATNConfigSet *s0, - TokenStream *input, size_t startIndex, ParserRuleContext *outerContext) { - -#if TRACE_ATN_SIM == 1 - std::cout << "execATNWithFullContext " << s0->toString() << std::endl; -#endif - - bool fullCtx = true; - bool foundExactAmbig = false; - - std::unique_ptr reach; - ATNConfigSet *previous = s0; - input->seek(startIndex); - size_t t = input->LA(1); - size_t predictedAlt; - - while (true) { - reach = computeReachSet(previous, t, fullCtx); - if (reach == nullptr) { - // if any configs in previous dipped into outer context, that - // means that input up to t actually finished entry rule - // at least for LL decision. Full LL doesn't dip into outer - // so don't need special case. - // We will get an error no matter what so delay until after - // decision; better error message. Also, no reachable target - // ATN states in SLL implies LL will also get nowhere. - // If conflict in states that dip out, choose min since we - // will get error no matter what. - NoViableAltException e = noViableAlt(input, outerContext, previous, startIndex, previous != s0); - input->seek(startIndex); - size_t alt = getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(previous, outerContext); - if (alt != ATN::INVALID_ALT_NUMBER) { - return alt; - } - throw e; - } - if (previous != s0) // Don't delete the start set. - delete previous; - previous = nullptr; - - std::vector altSubSets = PredictionModeClass::getConflictingAltSubsets(reach.get()); - reach->uniqueAlt = getUniqueAlt(reach.get()); - // unique prediction? - if (reach->uniqueAlt != ATN::INVALID_ALT_NUMBER) { - predictedAlt = reach->uniqueAlt; - break; - } - if (_mode != PredictionMode::LL_EXACT_AMBIG_DETECTION) { - predictedAlt = PredictionModeClass::resolvesToJustOneViableAlt(altSubSets); - if (predictedAlt != ATN::INVALID_ALT_NUMBER) { - break; - } - } else { - // In exact ambiguity mode, we never try to terminate early. - // Just keeps scarfing until we know what the conflict is - if (PredictionModeClass::allSubsetsConflict(altSubSets) && PredictionModeClass::allSubsetsEqual(altSubSets)) { - foundExactAmbig = true; - predictedAlt = PredictionModeClass::getSingleViableAlt(altSubSets); - break; - } - // else there are multiple non-conflicting subsets or - // we're not sure what the ambiguity is yet. - // So, keep going. - } - previous = reach.release(); - - if (t != Token::EOF) { - input->consume(); - t = input->LA(1); - } - } - - // If the configuration set uniquely predicts an alternative, - // without conflict, then we know that it's a full LL decision - // not SLL. - if (reach->uniqueAlt != ATN::INVALID_ALT_NUMBER) { - reportContextSensitivity(dfa, predictedAlt, reach.get(), startIndex, input->index()); - return predictedAlt; - } - - // We do not check predicates here because we have checked them - // on-the-fly when doing full context prediction. - - /* - In non-exact ambiguity detection mode, we might actually be able to - detect an exact ambiguity, but I'm not going to spend the cycles - needed to check. We only emit ambiguity warnings in exact ambiguity - mode. - - For example, we might know that we have conflicting configurations. - But, that does not mean that there is no way forward without a - conflict. It's possible to have nonconflicting alt subsets as in: - - LL altSubSets=[{1, 2}, {1, 2}, {1}, {1, 2}] - - from - - [(17,1,[5 $]), (13,1,[5 10 $]), (21,1,[5 10 $]), (11,1,[$]), - (13,2,[5 10 $]), (21,2,[5 10 $]), (11,2,[$])] - - In this case, (17,1,[5 $]) indicates there is some next sequence that - would resolve this without conflict to alternative 1. Any other viable - next sequence, however, is associated with a conflict. We stop - looking for input because no amount of further lookahead will alter - 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, startIndex, input->index(), foundExactAmbig, reach->getAlts(), reach.get()); - - return predictedAlt; -} - -std::unique_ptr ParserATNSimulator::computeReachSet(ATNConfigSet *closure_, size_t t, bool fullCtx) { - - std::unique_ptr intermediate(new 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 - * context). Once reached, these configurations are never updated by a - * closure operation, so they are handled separately for the performance - * advantage of having a smaller intermediate set when calling closure. - * - * For full-context reach operations, separate handling is required to - * ensure that the alternative matching the longest overall sequence is - * chosen when multiple such configurations can match the input. - */ - std::vector> skippedStopStates; - - // First figure out where we can reach on input t - for (const auto &c : closure_->configs) { - if (RuleStopState::is(c->state)) { - assert(c->context->isEmpty()); - - if (fullCtx || t == Token::EOF) { - skippedStopStates.push_back(c); - } - - continue; - } - - size_t n = c->state->transitions.size(); - for (size_t ti = 0; ti < n; ti++) { // for each transition - const Transition *trans = c->state->transitions[ti].get(); - ATNState *target = getReachableTarget(trans, (int)t); - if (target != nullptr) { - intermediate->add(std::make_shared(*c, target), &mergeCache); - } - } - } - - // Now figure out where the reach operation can take us... - std::unique_ptr reach; - - /* This block optimizes the reach operation for intermediate sets which - * trivially indicate a termination state for the overall - * adaptivePredict operation. - * - * The conditions assume that intermediate - * contains all configurations relevant to the reach set, but this - * condition is not true when one or more configurations have been - * withheld in skippedStopStates, or when the current symbol is EOF. - */ - if (skippedStopStates.empty() && t != Token::EOF) { - if (intermediate->size() == 1) { - // Don't pursue the closure if there is just one state. - // It can only have one alternative; just add to result - // Also don't pursue the closure if there is unique alternative - // among the configurations. - reach = std::move(intermediate); - } else if (getUniqueAlt(intermediate.get()) != ATN::INVALID_ALT_NUMBER) { - // Also don't pursue the closure if there is unique alternative - // among the configurations. - reach = std::move(intermediate); - } - } - - /* If the reach set could not be trivially determined, perform a closure - * operation on the intermediate set to compute its initial value. - */ - if (reach == nullptr) { - reach.reset(new ATNConfigSet(fullCtx)); - ATNConfig::Set closureBusy; - - bool treatEofAsEpsilon = t == Token::EOF; - for (const auto &c : intermediate->configs) { - closure(c, reach.get(), closureBusy, false, fullCtx, treatEofAsEpsilon); - } - } - - if (t == IntStream::EOF) { - /* After consuming EOF no additional input is possible, so we are - * only interested in configurations which reached the end of the - * decision rule (local context) or end of the start rule (full - * context). Update reach to contain only these configurations. This - * handles both explicit EOF transitions in the grammar and implicit - * EOF transitions following the end of the decision or start rule. - * - * When reach==intermediate, no closure operation was performed. In - * this case, removeAllConfigsNotInRuleStopState needs to check for - * reachable rule stop states as well as configurations already in - * a rule stop state. - * - * This is handled before the configurations in skippedStopStates, - * because any configurations potentially added from that list are - * already guaranteed to meet this condition whether or not it's - * required. - */ - ATNConfigSet *temp = removeAllConfigsNotInRuleStopState(reach.get(), *reach == *intermediate); - if (temp != reach.get()) - reach.reset(temp); // We got a new set, so use that. - } - - /* If skippedStopStates is not null, then it contains at least one - * configuration. For full-context reach operations, these - * configurations reached the end of the start rule, in which case we - * only add them back to reach if no configuration during the current - * closure operation reached such a state. This ensures adaptivePredict - * chooses an alternative matching the longest overall sequence when - * multiple alternatives are viable. - */ - if (skippedStopStates.size() > 0 && (!fullCtx || !PredictionModeClass::hasConfigInRuleStopState(reach.get()))) { - assert(!skippedStopStates.empty()); - - for (const auto &c : skippedStopStates) { - reach->add(c, &mergeCache); - } - } - -#if DEBUG_ATN == 1 || TRACE_ATN_SIM == 1 - std::cout << "computeReachSet " << closure_->toString() << " -> " << reach->toString() << std::endl; -#endif - - if (reach->isEmpty()) { - return nullptr; - } - return reach; -} - -ATNConfigSet* ParserATNSimulator::removeAllConfigsNotInRuleStopState(ATNConfigSet *configs, - bool lookToEndOfRule) { - if (PredictionModeClass::allConfigsInRuleStopStates(configs)) { - return configs; - } - - ATNConfigSet *result = new ATNConfigSet(configs->fullCtx); /* mem-check: released by caller */ - - for (const auto &config : configs->configs) { - if (config->state != nullptr && config->state->getStateType() == ATNStateType::RULE_STOP) { - result->add(config, &mergeCache); - continue; - } - - if (lookToEndOfRule && config->state->epsilonOnlyTransitions) { - misc::IntervalSet nextTokens = atn.nextTokens(config->state); - if (nextTokens.contains(Token::EPSILON)) { - ATNState *endOfRuleState = atn.ruleToStopState[config->state->ruleIndex]; - result->add(std::make_shared(*config, endOfRuleState), &mergeCache); - } - } - } - - return result; -} - -std::unique_ptr ParserATNSimulator::computeStartState(ATNState *p, RuleContext *ctx, bool fullCtx) { - // always at least the implicit call to start rule - Ref initialContext = PredictionContext::fromRuleContext(atn, ctx); - std::unique_ptr configs(new ATNConfigSet(fullCtx)); - -#if DEBUG_ATN == 1 || TRACE_ATN_SIM == 1 - std::cout << "computeStartState from ATN state " << p->toString() << " initialContext=" << initialContext->toString() << std::endl; -#endif - - for (size_t i = 0; i < p->transitions.size(); i++) { - ATNState *target = p->transitions[i]->target; - Ref c = std::make_shared(target, (int)i + 1, initialContext); - ATNConfig::Set closureBusy; - closure(c, configs.get(), closureBusy, true, fullCtx, false); - } - - return configs; -} - -std::unique_ptr ParserATNSimulator::applyPrecedenceFilter(ATNConfigSet *configs) { - std::map> statesFromAlt1; - std::unique_ptr configSet(new ATNConfigSet(configs->fullCtx)); - for (const auto &config : configs->configs) { - // handle alt 1 first - if (config->alt != 1) { - continue; - } - - Ref updatedContext = config->semanticContext->evalPrecedence(parser, _outerContext); - if (updatedContext == nullptr) { - // the configuration was eliminated - continue; - } - - statesFromAlt1[config->state->stateNumber] = config->context; - if (updatedContext != config->semanticContext) { - configSet->add(std::make_shared(*config, updatedContext), &mergeCache); - } - else { - configSet->add(config, &mergeCache); - } - } - - for (const auto &config : configs->configs) { - if (config->alt == 1) { - // already handled - continue; - } - - if (!config->isPrecedenceFilterSuppressed()) { - /* In the future, this elimination step could be updated to also - * filter the prediction context for alternatives predicting alt>1 - * (basically a graph subtraction algorithm). - */ - auto iterator = statesFromAlt1.find(config->state->stateNumber); - if (iterator != statesFromAlt1.end() && *iterator->second == *config->context) { - // eliminated - continue; - } - } - - configSet->add(config, &mergeCache); - } - - return configSet; -} - -atn::ATNState* ParserATNSimulator::getReachableTarget(const Transition *trans, size_t ttype) { - if (trans->matches(ttype, 0, atn.maxTokenType)) { - return trans->target; - } - - return nullptr; -} - -// Note that caller must memory manage the returned value from this function -std::vector> ParserATNSimulator::getPredsForAmbigAlts(const BitSet &ambigAlts, - 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 - * corresponds to alternative i. altToPred[i] may have one of three values: - * 1. null: no ATNConfig c is found such that c.alt==i - * 2. SemanticContext.NONE: At least one ATNConfig c exists such that - * c.alt==i and c.semanticContext==SemanticContext.NONE. In other words, - * alt i has at least one un-predicated config. - * 3. Non-NONE Semantic Context: There exists at least one, and for all - * ATNConfig c such that c.alt==i, c.semanticContext!=SemanticContext.NONE. - * - * From this, it is clear that NONE||anything==NONE. - */ - std::vector> altToPred(nalts + 1); - - for (const auto &c : configs->configs) { - if (ambigAlts.test(c->alt)) { - altToPred[c->alt] = SemanticContext::Or(altToPred[c->alt], c->semanticContext); - } - } - - size_t nPredAlts = 0; - for (size_t i = 1; i <= nalts; i++) { - if (altToPred[i] == nullptr) { - altToPred[i] = SemanticContext::Empty::Instance; - } else if (altToPred[i] != SemanticContext::Empty::Instance) { - nPredAlts++; - } - } - - // nonambig alts are null in altToPred - if (nPredAlts == 0) { - altToPred.clear(); - } -#if DEBUG_ATN == 1 - std::cout << "getPredsForAmbigAlts result " << Arrays::toString(altToPred) << std::endl; -#endif - - return altToPred; -} - -std::vector ParserATNSimulator::getPredicatePredictions(const antlrcpp::BitSet &ambigAlts, - const std::vector> &altToPred) { - bool containsPredicate = std::find_if(altToPred.begin(), altToPred.end(), [](const Ref &context) { - return context != SemanticContext::Empty::Instance; - }) != altToPred.end(); - std::vector pairs; - if (containsPredicate) { - for (size_t i = 1; i < altToPred.size(); i++) { - const auto &pred = altToPred[i]; - assert(pred != nullptr); // unpredicted is indicated by SemanticContext.NONE - if (ambigAlts.test(i)) { - pairs.emplace_back(pred, static_cast(i)); - } - } - } - return pairs; -} - -size_t ParserATNSimulator::getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(ATNConfigSet *configs, - ParserRuleContext *outerContext) -{ - std::pair sets = splitAccordingToSemanticValidity(configs, outerContext); - std::unique_ptr semValidConfigs(sets.first); - std::unique_ptr semInvalidConfigs(sets.second); - size_t alt = getAltThatFinishedDecisionEntryRule(semValidConfigs.get()); - if (alt != ATN::INVALID_ALT_NUMBER) { // semantically/syntactically viable path exists - return alt; - } - // Is there a syntactically valid path with a failed pred? - if (!semInvalidConfigs->configs.empty()) { - alt = getAltThatFinishedDecisionEntryRule(semInvalidConfigs.get()); - if (alt != ATN::INVALID_ALT_NUMBER) { // syntactically viable path exists - return alt; - } - } - return ATN::INVALID_ALT_NUMBER; -} - -size_t ParserATNSimulator::getAltThatFinishedDecisionEntryRule(ATNConfigSet *configs) { - misc::IntervalSet alts; - for (const auto &c : configs->configs) { - if (c->getOuterContextDepth() > 0 || (c->state != nullptr && c->state->getStateType() == ATNStateType::RULE_STOP && c->context->hasEmptyPath())) { - alts.add(c->alt); - } - } - if (alts.size() == 0) { - return ATN::INVALID_ALT_NUMBER; - } - return alts.getMinElement(); -} - -std::pair ParserATNSimulator::splitAccordingToSemanticValidity(ATNConfigSet *configs, - ParserRuleContext *outerContext) { - - // mem-check: both pointers must be freed by the caller. - ATNConfigSet *succeeded(new ATNConfigSet(configs->fullCtx)); - ATNConfigSet *failed(new ATNConfigSet(configs->fullCtx)); - for (const auto &c : configs->configs) { - if (c->semanticContext != SemanticContext::Empty::Instance) { - bool predicateEvaluationResult = evalSemanticContext(c->semanticContext, outerContext, c->alt, configs->fullCtx); - if (predicateEvaluationResult) { - succeeded->add(c); - } else { - failed->add(c); - } - } else { - succeeded->add(c); - } - } - return { succeeded, failed }; -} - -BitSet ParserATNSimulator::evalSemanticContext(const std::vector &predPredictions, - ParserRuleContext *outerContext, bool complete) { - BitSet predictions; - for (const auto &prediction : predPredictions) { - if (prediction.pred == SemanticContext::Empty::Instance) { - predictions.set(prediction.alt); - if (!complete) { - break; - } - continue; - } - - bool fullCtx = false; // in dfa - bool predicateEvaluationResult = evalSemanticContext(prediction.pred, outerContext, prediction.alt, fullCtx); -#if DEBUG_ATN == 1 || DFA_DEBUG == 1 - std::cout << "eval pred " << prediction.toString() << " = " << predicateEvaluationResult << std::endl; -#endif - - if (predicateEvaluationResult) { -#if DEBUG_ATN == 1 || DFA_DEBUG == 1 - std::cout << "PREDICT " << prediction.alt << std::endl; -#endif - - predictions.set(prediction.alt); - if (!complete) { - break; - } - } - } - - return predictions; -} - -bool ParserATNSimulator::evalSemanticContext(Ref const& pred, ParserRuleContext *parserCallStack, - size_t /*alt*/, bool /*fullCtx*/) { - return pred->eval(parser, parserCallStack); -} - -void ParserATNSimulator::closure(Ref const& config, ATNConfigSet *configs, ATNConfig::Set &closureBusy, - bool collectPredicates, bool fullCtx, bool treatEofAsEpsilon) { - const int initialDepth = 0; - closureCheckingStopState(config, configs, closureBusy, collectPredicates, fullCtx, initialDepth, treatEofAsEpsilon); - - assert(!fullCtx || !configs->dipsIntoOuterContext); -} - -void ParserATNSimulator::closureCheckingStopState(Ref const& config, ATNConfigSet *configs, - ATNConfig::Set &closureBusy, bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon) { - -#if TRACE_ATN_SIM == 1 - std::cout << "closure(" << config->toString(true) << ")" << std::endl; -#endif - - if (config->state != nullptr && config->state->getStateType() == ATNStateType::RULE_STOP) { - // We hit rule end. If we have context info, use it - // run thru all possible stack tops in ctx - if (!config->context->isEmpty()) { - for (size_t i = 0; i < config->context->size(); i++) { - if (config->context->getReturnState(i) == PredictionContext::EMPTY_RETURN_STATE) { - if (fullCtx) { - configs->add(std::make_shared(*config, config->state, PredictionContext::EMPTY), &mergeCache); - continue; - } else { - // we have no context info, just chase follow links (if greedy) -#if DEBUG_ATN == 1 - std::cout << "FALLING off rule " << getRuleName(config->state->ruleIndex) << std::endl; -#endif - closure_(config, configs, closureBusy, collectPredicates, fullCtx, depth, treatEofAsEpsilon); - } - continue; - } - ATNState *returnState = atn.states[config->context->getReturnState(i)]; - Ref newContext = config->context->getParent(i); // "pop" return state - Ref c = std::make_shared(returnState, config->alt, newContext, config->semanticContext); - // While we have context to pop back from, we may have - // gotten that context AFTER having falling off a rule. - // Make sure we track that we are now out of context. - // - // This assignment also propagates the - // isPrecedenceFilterSuppressed() value to the new - // configuration. - c->reachesIntoOuterContext = config->reachesIntoOuterContext; - assert(depth > INT_MIN); - - closureCheckingStopState(c, configs, closureBusy, collectPredicates, fullCtx, depth - 1, treatEofAsEpsilon); - } - return; - } else if (fullCtx) { - // reached end of start rule - configs->add(config, &mergeCache); - return; - } else { - // else if we have no context info, just chase follow links (if greedy) - } - } - - closure_(config, configs, closureBusy, collectPredicates, fullCtx, depth, treatEofAsEpsilon); -} - -void ParserATNSimulator::closure_(Ref const& config, ATNConfigSet *configs, ATNConfig::Set &closureBusy, - bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon) { - ATNState *p = config->state; - // optimization - if (!p->epsilonOnlyTransitions) { - // make sure to not return here, because EOF transitions can act as - // both epsilon transitions and non-epsilon transitions. - configs->add(config, &mergeCache); - } - - for (size_t i = 0; i < p->transitions.size(); i++) { - if (i == 0 && canDropLoopEntryEdgeInLeftRecursiveRule(config.get())) - continue; - - const Transition *t = p->transitions[i].get(); - bool continueCollecting = !(t != nullptr && t->getTransitionType() == TransitionType::ACTION) && collectPredicates; - Ref c = getEpsilonTarget(config, t, continueCollecting, depth == 0, fullCtx, treatEofAsEpsilon); - if (c != nullptr) { - int newDepth = depth; - if (config->state != nullptr && config->state->getStateType() == ATNStateType::RULE_STOP) { - assert(!fullCtx); - - // target fell off end of rule; mark resulting c as having dipped into outer context - // We can't get here if incoming config was rule stop and we had context - // track how far we dip into outer context. Might - // come in handy and we avoid evaluating context dependent - // preds if this is > 0. - - if (closureBusy.count(c) > 0) { - // avoid infinite recursion for right-recursive rules - continue; - } - closureBusy.insert(c); - - if (_dfa != nullptr && _dfa->isPrecedenceDfa()) { - size_t outermostPrecedenceReturn = downCast(t)->outermostPrecedenceReturn(); - if (outermostPrecedenceReturn == _dfa->atnStartState->ruleIndex) { - c->setPrecedenceFilterSuppressed(true); - } - } - - c->reachesIntoOuterContext++; - - if (!t->isEpsilon()) { - // avoid infinite recursion for EOF* and EOF+ - if (closureBusy.count(c) == 0) { - closureBusy.insert(c); - } else { - continue; - } - } - - configs->dipsIntoOuterContext = true; // TODO: can remove? only care when we add to set per middle of this method - assert(newDepth > INT_MIN); - - newDepth--; -#if DFA_DEBUG == 1 - std::cout << "dips into outer ctx: " << c << std::endl; -#endif - - } else if (!t->isEpsilon()) { - // avoid infinite recursion for EOF* and EOF+ - if (closureBusy.count(c) == 0) { - closureBusy.insert(c); - } else { - continue; - } - } - - if (t != nullptr && t->getTransitionType() == TransitionType::RULE) { - // latch when newDepth goes negative - once we step out of the entry context we can't return - if (newDepth >= 0) { - newDepth++; - } - } - - closureCheckingStopState(c, configs, closureBusy, continueCollecting, fullCtx, newDepth, treatEofAsEpsilon); - } - } -} - -bool ParserATNSimulator::canDropLoopEntryEdgeInLeftRecursiveRule(ATNConfig *config) const { - if (TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT) - return false; - - ATNState *p = config->state; - - // First check to see if we are in StarLoopEntryState generated during - // left-recursion elimination. For efficiency, also check if - // the context has an empty stack case. If so, it would mean - // global FOLLOW so we can't perform optimization - if (p->getStateType() != ATNStateType::STAR_LOOP_ENTRY || - !((StarLoopEntryState *)p)->isPrecedenceDecision || // Are we the special loop entry/exit state? - config->context->isEmpty() || // If SLL wildcard - config->context->hasEmptyPath()) - { - return false; - } - - // Require all return states to return back to the same rule - // that p is in. - size_t numCtxs = config->context->size(); - for (size_t i = 0; i < numCtxs; i++) { // for each stack context - ATNState *returnState = atn.states[config->context->getReturnState(i)]; - if (returnState->ruleIndex != p->ruleIndex) - return false; - } - - BlockStartState *decisionStartState = (BlockStartState *)p->transitions[0]->target; - size_t blockEndStateNum = decisionStartState->endState->stateNumber; - BlockEndState *blockEndState = (BlockEndState *)atn.states[blockEndStateNum]; - - // Verify that the top of each stack context leads to loop entry/exit - // state through epsilon edges and w/o leaving rule. - for (size_t i = 0; i < numCtxs; i++) { // for each stack context - size_t returnStateNumber = config->context->getReturnState(i); - ATNState *returnState = atn.states[returnStateNumber]; - // All states must have single outgoing epsilon edge. - if (returnState->transitions.size() != 1 || !returnState->transitions[0]->isEpsilon()) - { - return false; - } - - // Look for prefix op case like 'not expr', (' type ')' expr - ATNState *returnStateTarget = returnState->transitions[0]->target; - if (returnState->getStateType() == ATNStateType::BLOCK_END && returnStateTarget == p) { - continue; - } - - // Look for 'expr op expr' or case where expr's return state is block end - // of (...)* internal block; the block end points to loop back - // which points to p but we don't need to check that - if (returnState == blockEndState) { - continue; - } - - // Look for ternary expr ? expr : expr. The return state points at block end, - // which points at loop entry state - if (returnStateTarget == blockEndState) { - continue; - } - - // Look for complex prefix 'between expr and expr' case where 2nd expr's - // return state points at block end state of (...)* internal block - if (returnStateTarget->getStateType() == ATNStateType::BLOCK_END && - returnStateTarget->transitions.size() == 1 && - returnStateTarget->transitions[0]->isEpsilon() && - returnStateTarget->transitions[0]->target == p) - { - continue; - } - - // Anything else ain't conforming. - return false; - } - - return true; -} - -std::string ParserATNSimulator::getRuleName(size_t index) { - if (parser != nullptr) { - return parser->getRuleNames()[index]; - } - return ""; -} - -Ref ParserATNSimulator::getEpsilonTarget(Ref const& config, const Transition *t, bool collectPredicates, - bool inContext, bool fullCtx, bool treatEofAsEpsilon) { - switch (t->getTransitionType()) { - case TransitionType::RULE: - return ruleTransition(config, static_cast(t)); - - case TransitionType::PRECEDENCE: - return precedenceTransition(config, static_cast(t), collectPredicates, inContext, fullCtx); - - case TransitionType::PREDICATE: - return predTransition(config, static_cast(t), collectPredicates, inContext, fullCtx); - - case TransitionType::ACTION: - return actionTransition(config, static_cast(t)); - - case TransitionType::EPSILON: - return std::make_shared(*config, t->target); - - case TransitionType::ATOM: - case TransitionType::RANGE: - case TransitionType::SET: - // EOF transitions act like epsilon transitions after the first EOF - // transition is traversed - if (treatEofAsEpsilon) { - if (t->matches(Token::EOF, 0, 1)) { - return std::make_shared(*config, t->target); - } - } - - return nullptr; - - default: - return nullptr; - } -} - -Ref ParserATNSimulator::actionTransition(Ref const& config, const ActionTransition *t) { -#if DFA_DEBUG == 1 - std::cout << "ACTION edge " << t->ruleIndex << ":" << t->actionIndex << std::endl; -#endif - - return std::make_shared(*config, t->target); -} - -Ref ParserATNSimulator::precedenceTransition(Ref const& config, const PrecedencePredicateTransition *pt, - bool collectPredicates, bool inContext, bool fullCtx) { -#if DFA_DEBUG == 1 - std::cout << "PRED (collectPredicates=" << collectPredicates << ") " << pt->getPrecedence() << ">=_p" << ", ctx dependent=true" << std::endl; - if (parser != nullptr) { - std::cout << "context surrounding pred is " << Arrays::listToString(parser->getRuleInvocationStack(), ", ") << std::endl; - } -#endif - - Ref c; - if (collectPredicates && inContext) { - const auto &predicate = pt->getPredicate(); - - if (fullCtx) { - // In full context mode, we can evaluate predicates on-the-fly - // during closure, which dramatically reduces the size of - // the config sets. It also obviates the need to test predicates - // later during conflict resolution. - size_t currentPosition = _input->index(); - _input->seek(_startIndex); - bool predSucceeds = evalSemanticContext(predicate, _outerContext, config->alt, fullCtx); - _input->seek(currentPosition); - if (predSucceeds) { - c = std::make_shared(*config, pt->target); // no pred context - } - } else { - Ref newSemCtx = SemanticContext::And(config->semanticContext, predicate); - c = std::make_shared(*config, pt->target, std::move(newSemCtx)); - } - } else { - c = std::make_shared(*config, pt->target); - } - -#if DFA_DEBUG == 1 - std::cout << "config from pred transition=" << c << std::endl; -#endif - - return c; -} - -Ref ParserATNSimulator::predTransition(Ref const& config, const PredicateTransition *pt, - bool collectPredicates, bool inContext, bool fullCtx) { -#if DFA_DEBUG == 1 - std::cout << "PRED (collectPredicates=" << collectPredicates << ") " << pt->getRuleIndex() << ":" << pt->getPredIndex() << ", ctx dependent=" << pt->isCtxDependent() << std::endl; - if (parser != nullptr) { - std::cout << "context surrounding pred is " << Arrays::listToString(parser->getRuleInvocationStack(), ", ") << std::endl; - } -#endif - - Ref c = nullptr; - if (collectPredicates && (!pt->isCtxDependent() || (pt->isCtxDependent() && inContext))) { - const auto &predicate = pt->getPredicate(); - if (fullCtx) { - // In full context mode, we can evaluate predicates on-the-fly - // during closure, which dramatically reduces the size of - // the config sets. It also obviates the need to test predicates - // later during conflict resolution. - size_t currentPosition = _input->index(); - _input->seek(_startIndex); - bool predSucceeds = evalSemanticContext(predicate, _outerContext, config->alt, fullCtx); - _input->seek(currentPosition); - if (predSucceeds) { - c = std::make_shared(*config, pt->target); // no pred context - } - } else { - Ref newSemCtx = SemanticContext::And(config->semanticContext, predicate); - c = std::make_shared(*config, pt->target, std::move(newSemCtx)); - } - } else { - c = std::make_shared(*config, pt->target); - } - -#if DFA_DEBUG == 1 - std::cout << "config from pred transition=" << c << std::endl; -#endif - - return c; -} - -Ref ParserATNSimulator::ruleTransition(Ref const& config, const RuleTransition *t) { -#if DFA_DEBUG == 1 - std::cout << "CALL rule " << getRuleName(t->target->ruleIndex) << ", ctx=" << config->context << std::endl; -#endif - - atn::ATNState *returnState = t->followState; - Ref newContext = SingletonPredictionContext::create(config->context, returnState->stateNumber); - return std::make_shared(*config, t->target, newContext); -} - -BitSet ParserATNSimulator::getConflictingAlts(ATNConfigSet *configs) { - std::vector altsets = PredictionModeClass::getConflictingAltSubsets(configs); - return PredictionModeClass::getAlts(altsets); -} - -BitSet ParserATNSimulator::getConflictingAltsOrUniqueAlt(ATNConfigSet *configs) { - BitSet conflictingAlts; - if (configs->uniqueAlt != ATN::INVALID_ALT_NUMBER) { - conflictingAlts.set(configs->uniqueAlt); - } else { - conflictingAlts = configs->conflictingAlts; - } - return conflictingAlts; -} - -std::string ParserATNSimulator::getTokenName(size_t t) { - if (t == Token::EOF) { - return "EOF"; - } - - const dfa::Vocabulary &vocabulary = parser != nullptr ? parser->getVocabulary() : dfa::Vocabulary(); - std::string displayName = vocabulary.getDisplayName(t); - if (displayName == std::to_string(t)) { - return displayName; - } - - return displayName + "<" + std::to_string(t) + ">"; -} - -std::string ParserATNSimulator::getLookaheadName(TokenStream *input) { - return getTokenName(input->LA(1)); -} - -void ParserATNSimulator::dumpDeadEndConfigs(NoViableAltException &nvae) { - std::cerr << "dead end configs: "; - for (const auto &c : nvae.getDeadEndConfigs()->configs) { - std::string trans = "no edges"; - if (c->state->transitions.size() > 0) { - const Transition *t = c->state->transitions[0].get(); - if (t != nullptr && t->getTransitionType() == TransitionType::ATOM) { - const AtomTransition *at = static_cast(t); - trans = "Atom " + getTokenName(at->_label); - } else if (t != nullptr && t->getTransitionType() == TransitionType::SET) { - const SetTransition *st = static_cast(t); - trans = "Set "; - trans += st->set.toString(); - } else if (t != nullptr && t->getTransitionType() == TransitionType::NOT_SET) { - const SetTransition *st = static_cast(t); - trans = "~Set "; - trans += st->set.toString(); - } - } - std::cerr << c->toString(true) + ":" + trans; - } -} - -NoViableAltException ParserATNSimulator::noViableAlt(TokenStream *input, ParserRuleContext *outerContext, - ATNConfigSet *configs, size_t startIndex, bool deleteConfigs) { - return NoViableAltException(parser, input, input->get(startIndex), input->LT(1), configs, outerContext, deleteConfigs); -} - -size_t ParserATNSimulator::getUniqueAlt(ATNConfigSet *configs) { - size_t alt = ATN::INVALID_ALT_NUMBER; - for (const auto &c : configs->configs) { - if (alt == ATN::INVALID_ALT_NUMBER) { - alt = c->alt; // found first alt - } else if (c->alt != alt) { - return ATN::INVALID_ALT_NUMBER; - } - } - return alt; -} - -dfa::DFAState *ParserATNSimulator::addDFAEdge(dfa::DFA &dfa, dfa::DFAState *from, ssize_t t, dfa::DFAState *to) { -#if DFA_DEBUG == 1 - std::cout << "EDGE " << from << " -> " << to << " upon " << getTokenName(t) << std::endl; -#endif - - if (to == nullptr) { - return nullptr; - } - - { - UniqueLock stateLock(atn._stateMutex); - to = addDFAState(dfa, to); // used existing if possible not incoming - } - if (from == nullptr || t > (int)atn.maxTokenType) { - return to; - } - - { - UniqueLock edgeLock(atn._edgeMutex); - from->edges[t] = to; // connect - } - -#if DFA_DEBUG == 1 - std::string dfaText; - if (parser != nullptr) { - dfaText = dfa.toString(parser->getVocabulary()); - } else { - dfaText = dfa.toString(dfa::Vocabulary()); - } - std::cout << "DFA=\n" << dfaText << std::endl; -#endif - - return to; -} - -dfa::DFAState *ParserATNSimulator::addDFAState(dfa::DFA &dfa, dfa::DFAState *D) { - if (D == ERROR.get()) { - return D; - } - - // Optimizing the configs below should not alter the hash code. Thus we can just do an insert - // which will only succeed if an equivalent DFAState does not already exist. - auto [existing, inserted] = dfa.states.insert(D); - if (!inserted) { -#if TRACE_ATN_SIM == 1 - std::cout << "addDFAState " << D->toString() << " exists" << std::endl; -#endif - return *existing; - } - - // Previously we did a lookup, then set fields, then inserted. It was `dfa.states.size()`, since - // we already inserted we need to subtract one. - D->stateNumber = static_cast(dfa.states.size() - 1); - -#if TRACE_ATN_SIM == 1 - std::cout << "addDFAState new " << D->toString() << std::endl; -#endif - - if (!D->configs->isReadonly()) { - D->configs->optimizeConfigs(this); - D->configs->setReadonly(true); - } - -#if DFA_DEBUG == 1 - std::cout << "adding new DFA state: " << D << std::endl; -#endif - - return D; -} - -void ParserATNSimulator::reportAttemptingFullContext(dfa::DFA &dfa, const antlrcpp::BitSet &conflictingAlts, - ATNConfigSet *configs, size_t startIndex, size_t stopIndex) { -#if DFA_DEBUG == 1 || RETRY_DEBUG == 1 - misc::Interval interval = misc::Interval((int)startIndex, (int)stopIndex); - std::cout << "reportAttemptingFullContext decision=" << dfa.decision << ":" << configs << ", input=" << parser->getTokenStream()->getText(interval) << std::endl; -#endif - - if (parser != nullptr) { - parser->getErrorListenerDispatch().reportAttemptingFullContext(parser, dfa, startIndex, stopIndex, conflictingAlts, configs); - } -} - -void ParserATNSimulator::reportContextSensitivity(dfa::DFA &dfa, size_t prediction, ATNConfigSet *configs, - size_t startIndex, size_t stopIndex) { -#if DFA_DEBUG == 1 || RETRY_DEBUG == 1 - misc::Interval interval = misc::Interval(startIndex, stopIndex); - std::cout << "reportContextSensitivity decision=" << dfa.decision << ":" << configs << ", input=" << parser->getTokenStream()->getText(interval) << std::endl; -#endif - - if (parser != nullptr) { - parser->getErrorListenerDispatch().reportContextSensitivity(parser, dfa, startIndex, stopIndex, prediction, configs); - } -} - -void ParserATNSimulator::reportAmbiguity(dfa::DFA &dfa, dfa::DFAState * /*D*/, size_t startIndex, size_t stopIndex, - bool exact, const antlrcpp::BitSet &ambigAlts, ATNConfigSet *configs) { -#if DFA_DEBUG == 1 || RETRY_DEBUG == 1 - misc::Interval interval = misc::Interval((int)startIndex, (int)stopIndex); - std::cout << "reportAmbiguity " << ambigAlts << ":" << configs << ", input=" << parser->getTokenStream()->getText(interval) << std::endl; -#endif - - if (parser != nullptr) { - parser->getErrorListenerDispatch().reportAmbiguity(parser, dfa, startIndex, stopIndex, exact, ambigAlts, configs); - } -} - -void ParserATNSimulator::setPredictionMode(PredictionMode newMode) { - _mode = newMode; -} - -atn::PredictionMode ParserATNSimulator::getPredictionMode() { - return _mode; -} - -Parser* ParserATNSimulator::getParser() { - return parser; -} - -#ifdef _MSC_VER -#pragma warning (disable:4996) // 'getenv': This function or variable may be unsafe. Consider using _dupenv_s instead. -#endif - -bool ParserATNSimulator::getLrLoopSetting() { - char *var = std::getenv("TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT"); - if (var == nullptr) - return false; - std::string value(var); - return value == "true" || value == "1"; -} - -#ifdef _MSC_VER -#pragma warning (default:4996) -#endif - -void ParserATNSimulator::InitializeInstanceFields() { - _mode = PredictionMode::LL; - _startIndex = 0; -} diff --git a/src/include/atn/ParserATNSimulator.h b/src/include/atn/ParserATNSimulator.h deleted file mode 100755 index 28fd059d..00000000 --- a/src/include/atn/ParserATNSimulator.h +++ /dev/null @@ -1,911 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "PredictionMode.h" -#include "dfa/DFAState.h" -#include "atn/ATNSimulator.h" -#include "atn/PredictionContext.h" -#include "atn/PredictionContextMergeCache.h" -#include "atn/ParserATNSimulatorOptions.h" -#include "SemanticContext.h" -#include "atn/ATNConfig.h" - -namespace antlr4 { -namespace atn { - - /** - * The embodiment of the adaptive LL(*), ALL(*), parsing strategy. - * - *

- * The basic complexity of the adaptive strategy makes it harder to understand. - * We begin with ATN simulation to build paths in a DFA. Subsequent prediction - * requests go through the DFA first. If they reach a state without an edge for - * the current symbol, the algorithm fails over to the ATN simulation to - * complete the DFA path for the current input (until it finds a conflict state - * or uniquely predicting state).

- * - *

- * All of that is done without using the outer context because we want to create - * a DFA that is not dependent upon the rule invocation stack when we do a - * prediction. One DFA works in all contexts. We avoid using context not - * necessarily because it's slower, although it can be, but because of the DFA - * caching problem. The closure routine only considers the rule invocation stack - * created during prediction beginning in the decision rule. For example, if - * prediction occurs without invoking another rule's ATN, there are no context - * stacks in the configurations. When lack of context leads to a conflict, we - * don't know if it's an ambiguity or a weakness in the strong LL(*) parsing - * strategy (versus full LL(*)).

- * - *

- * When SLL yields a configuration set with conflict, we rewind the input and - * retry the ATN simulation, this time using full outer context without adding - * to the DFA. Configuration context stacks will be the full invocation stacks - * from the start rule. If we get a conflict using full context, then we can - * definitively say we have a true ambiguity for that input sequence. If we - * don't get a conflict, it implies that the decision is sensitive to the outer - * context. (It is not context-sensitive in the sense of context-sensitive - * grammars.)

- * - *

- * The next time we reach this DFA state with an SLL conflict, through DFA - * simulation, we will again retry the ATN simulation using full context mode. - * This is slow because we can't save the results and have to "interpret" the - * ATN each time we get that input.

- * - *

- * CACHING FULL CONTEXT PREDICTIONS

- * - *

- * We could cache results from full context to predicted alternative easily and - * that saves a lot of time but doesn't work in presence of predicates. The set - * of visible predicates from the ATN start state changes depending on the - * context, because closure can fall off the end of a rule. I tried to cache - * tuples (stack context, semantic context, predicted alt) but it was slower - * than interpreting and much more complicated. Also required a huge amount of - * memory. The goal is not to create the world's fastest parser anyway. I'd like - * to keep this algorithm simple. By launching multiple threads, we can improve - * the speed of parsing across a large number of files.

- * - *

- * There is no strict ordering between the amount of input used by SLL vs LL, - * which makes it really hard to build a cache for full context. Let's say that - * we have input A B C that leads to an SLL conflict with full context X. That - * implies that using X we might only use A B but we could also use A B C D to - * resolve conflict. Input A B C D could predict alternative 1 in one position - * in the input and A B C E could predict alternative 2 in another position in - * input. The conflicting SLL configurations could still be non-unique in the - * full context prediction, which would lead us to requiring more input than the - * original A B C. To make a prediction cache work, we have to track the exact - * input used during the previous prediction. That amounts to a cache that maps - * X to a specific DFA for that context.

- * - *

- * Something should be done for left-recursive expression predictions. They are - * likely LL(1) + pred eval. Easier to do the whole SLL unless error and retry - * with full LL thing Sam does.

- * - *

- * AVOIDING FULL CONTEXT PREDICTION

- * - *

- * We avoid doing full context retry when the outer context is empty, we did not - * dip into the outer context by falling off the end of the decision state rule, - * or when we force SLL mode.

- * - *

- * As an example of the not dip into outer context case, consider as super - * constructor calls versus function calls. One grammar might look like - * this:

- * - *
-   * ctorBody
-   *   : '{' superCall? stat* '}'
-   *   ;
-   * 
- * - *

- * Or, you might see something like

- * - *
-   * stat
-   *   : superCall ';'
-   *   | expression ';'
-   *   | ...
-   *   ;
-   * 
- * - *

- * In both cases I believe that no closure operations will dip into the outer - * context. In the first case ctorBody in the worst case will stop at the '}'. - * In the 2nd case it should stop at the ';'. Both cases should stay within the - * entry rule and not dip into the outer context.

- * - *

- * PREDICATES

- * - *

- * Predicates are always evaluated if present in either SLL or LL both. SLL and - * LL simulation deals with predicates differently. SLL collects predicates as - * it performs closure operations like ANTLR v3 did. It delays predicate - * evaluation until it reaches and accept state. This allows us to cache the SLL - * ATN simulation whereas, if we had evaluated predicates on-the-fly during - * closure, the DFA state configuration sets would be different and we couldn't - * build up a suitable DFA.

- * - *

- * When building a DFA accept state during ATN simulation, we evaluate any - * predicates and return the sole semantically valid alternative. If there is - * more than 1 alternative, we report an ambiguity. If there are 0 alternatives, - * we throw an exception. Alternatives without predicates act like they have - * true predicates. The simple way to think about it is to strip away all - * alternatives with false predicates and choose the minimum alternative that - * remains.

- * - *

- * When we start in the DFA and reach an accept state that's predicated, we test - * those and return the minimum semantically viable alternative. If no - * alternatives are viable, we throw an exception.

- * - *

- * During full LL ATN simulation, closure always evaluates predicates and - * on-the-fly. This is crucial to reducing the configuration set size during - * closure. It hits a landmine when parsing with the Java grammar, for example, - * without this on-the-fly evaluation.

- * - *

- * SHARING DFA

- * - *

- * All instances of the same parser share the same decision DFAs through a - * static field. Each instance gets its own ATN simulator but they share the - * same {@link #decisionToDFA} field. They also share a - * {@link PredictionContextCache} object that makes sure that all - * {@link PredictionContext} objects are shared among the DFA states. This makes - * a big size difference.

- * - *

- * THREAD SAFETY

- * - *

- * The {@link ParserATNSimulator} locks on the {@link #decisionToDFA} field when - * it adds a new DFA object to that array. {@link #addDFAEdge} - * locks on the DFA for the current decision when setting the - * {@link DFAState#edges} field. {@link #addDFAState} locks on - * the DFA for the current decision when looking up a DFA state to see if it - * already exists. We must make sure that all requests to add DFA states that - * are equivalent result in the same shared DFA object. This is because lots of - * threads will be trying to update the DFA at once. The - * {@link #addDFAState} method also locks inside the DFA lock - * but this time on the shared context cache when it rebuilds the - * configurations' {@link PredictionContext} objects using cached - * subgraphs/nodes. No other locking occurs, even during DFA simulation. This is - * safe as long as we can guarantee that all threads referencing - * {@code s.edge[t]} get the same physical target {@link DFAState}, or - * {@code null}. Once into the DFA, the DFA simulation does not reference the - * {@link DFA#states} map. It follows the {@link DFAState#edges} field to new - * targets. The DFA simulator will either find {@link DFAState#edges} to be - * {@code null}, to be non-{@code null} and {@code dfa.edges[t]} null, or - * {@code dfa.edges[t]} to be non-null. The - * {@link #addDFAEdge} method could be racing to set the field - * but in either case the DFA simulator works; if {@code null}, and requests ATN - * simulation. It could also race trying to get {@code dfa.edges[t]}, but either - * way it will work because it's not doing a test and set operation.

- * - *

- * Starting with SLL then failing to combined SLL/LL (Two-Stage - * Parsing)

- * - *

- * Sam pointed out that if SLL does not give a syntax error, then there is no - * point in doing full LL, which is slower. We only have to try LL if we get a - * syntax error. For maximum speed, Sam starts the parser set to pure SLL - * mode with the {@link BailErrorStrategy}:

- * - *
-   * parser.{@link Parser#getInterpreter() getInterpreter()}.{@link #setPredictionMode setPredictionMode}{@code (}{@link PredictionMode#SLL}{@code )};
-   * parser.{@link Parser#setErrorHandler setErrorHandler}(new {@link BailErrorStrategy}());
-   * 
- * - *

- * If it does not get a syntax error, then we're done. If it does get a syntax - * error, we need to retry with the combined SLL/LL strategy.

- * - *

- * The reason this works is as follows. If there are no SLL conflicts, then the - * grammar is SLL (at least for that input set). If there is an SLL conflict, - * the full LL analysis must yield a set of viable alternatives which is a - * subset of the alternatives reported by SLL. If the LL set is a singleton, - * then the grammar is LL but not SLL. If the LL set is the same size as the SLL - * set, the decision is SLL. If the LL set has size > 1, then that decision - * is truly ambiguous on the current input. If the LL set is smaller, then the - * SLL conflict resolution might choose an alternative that the full LL would - * rule out as a possibility based upon better context information. If that's - * the case, then the SLL parse will definitely get an error because the full LL - * analysis says it's not viable. If SLL conflict resolution chooses an - * alternative within the LL set, them both SLL and LL would choose the same - * alternative because they both choose the minimum of multiple conflicting - * alternatives.

- * - *

- * Let's say we have a set of SLL conflicting alternatives {@code {1, 2, 3}} and - * a smaller LL set called s. If s is {@code {2, 3}}, then SLL - * parsing will get an error because SLL will pursue alternative 1. If - * s is {@code {1, 2}} or {@code {1, 3}} then both SLL and LL will - * choose the same alternative because alternative one is the minimum of either - * set. If s is {@code {2}} or {@code {3}} then SLL will get a syntax - * error. If s is {@code {1}} then SLL will succeed.

- * - *

- * Of course, if the input is invalid, then we will get an error for sure in - * both SLL and LL parsing. Erroneous input will therefore require 2 passes over - * the input.

- */ - class ANTLR4CPP_PUBLIC ParserATNSimulator : public ATNSimulator { - public: - /// Testing only! - ParserATNSimulator(const ATN &atn, std::vector &decisionToDFA, - PredictionContextCache &sharedContextCache); - - ParserATNSimulator(Parser *parser, const ATN &atn, std::vector &decisionToDFA, - PredictionContextCache &sharedContextCache); - - ParserATNSimulator(Parser *parser, const ATN &atn, std::vector &decisionToDFA, - PredictionContextCache &sharedContextCache, - const ParserATNSimulatorOptions &options); - - virtual void reset() override; - virtual void clearDFA() override; - virtual size_t adaptivePredict(TokenStream *input, size_t decision, ParserRuleContext *outerContext); - - static const bool TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT; - - std::vector &decisionToDFA; - - /** Implements first-edge (loop entry) elimination as an optimization - * during closure operations. See antlr/antlr4#1398. - * - * The optimization is to avoid adding the loop entry config when - * the exit path can only lead back to the same - * StarLoopEntryState after popping context at the rule end state - * (traversing only epsilon edges, so we're still in closure, in - * this same rule). - * - * We need to detect any state that can reach loop entry on - * epsilon w/o exiting rule. We don't have to look at FOLLOW - * links, just ensure that all stack tops for config refer to key - * states in LR rule. - * - * To verify we are in the right situation we must first check - * closure is at a StarLoopEntryState generated during LR removal. - * Then we check that each stack top of context is a return state - * from one of these cases: - * - * 1. 'not' expr, '(' type ')' expr. The return state points at loop entry state - * 2. expr op expr. The return state is the block end of internal block of (...)* - * 3. 'between' expr 'and' expr. The return state of 2nd expr reference. - * That state points at block end of internal block of (...)*. - * 4. expr '?' expr ':' expr. The return state points at block end, - * which points at loop entry state. - * - * If any is true for each stack top, then closure does not add a - * config to the current config set for edge[0], the loop entry branch. - * - * Conditions fail if any context for the current config is: - * - * a. empty (we'd fall out of expr to do a global FOLLOW which could - * even be to some weird spot in expr) or, - * b. lies outside of expr or, - * c. lies within expr but at a state not the BlockEndState - * generated during LR removal - * - * Do we need to evaluate predicates ever in closure for this case? - * - * No. Predicates, including precedence predicates, are only - * evaluated when computing a DFA start state. I.e., only before - * the lookahead (but not parser) consumes a token. - * - * There are no epsilon edges allowed in LR rule alt blocks or in - * the "primary" part (ID here). If closure is in - * StarLoopEntryState any lookahead operation will have consumed a - * token as there are no epsilon-paths that lead to - * StarLoopEntryState. We do not have to evaluate predicates - * therefore if we are in the generated StarLoopEntryState of a LR - * rule. Note that when making a prediction starting at that - * decision point, decision d=2, compute-start-state performs - * closure starting at edges[0], edges[1] emanating from - * StarLoopEntryState. That means it is not performing closure on - * StarLoopEntryState during compute-start-state. - * - * How do we know this always gives same prediction answer? - * - * Without predicates, loop entry and exit paths are ambiguous - * upon remaining input +b (in, say, a+b). Either paths lead to - * valid parses. Closure can lead to consuming + immediately or by - * falling out of this call to expr back into expr and loop back - * again to StarLoopEntryState to match +b. In this special case, - * we choose the more efficient path, which is to take the bypass - * path. - * - * The lookahead language has not changed because closure chooses - * one path over the other. Both paths lead to consuming the same - * remaining input during a lookahead operation. If the next token - * is an operator, lookahead will enter the choice block with - * operators. If it is not, lookahead will exit expr. Same as if - * closure had chosen to enter the choice block immediately. - * - * Closure is examining one config (some loopentrystate, some alt, - * context) which means it is considering exactly one alt. Closure - * always copies the same alt to any derived configs. - * - * How do we know this optimization doesn't mess up precedence in - * our parse trees? - * - * Looking through expr from left edge of stat only has to confirm - * that an input, say, a+b+c; begins with any valid interpretation - * of an expression. The precedence actually doesn't matter when - * making a decision in stat seeing through expr. It is only when - * parsing rule expr that we must use the precedence to get the - * right interpretation and, hence, parse tree. - */ - bool canDropLoopEntryEdgeInLeftRecursiveRule(ATNConfig *config) const; - virtual std::string getRuleName(size_t index); - - virtual Ref precedenceTransition(Ref const& config, const PrecedencePredicateTransition *pt, - bool collectPredicates, bool inContext, bool fullCtx); - - void setPredictionMode(PredictionMode newMode); - PredictionMode getPredictionMode(); - - Parser* getParser(); - - virtual std::string getTokenName(size_t t); - - virtual std::string getLookaheadName(TokenStream *input); - - /// - /// Used for debugging in adaptivePredict around execATN but I cut - /// it out for clarity now that alg. works well. We can leave this - /// "dead" code for a bit. - /// - virtual void dumpDeadEndConfigs(NoViableAltException &nvae); - - protected: - Parser *const parser; - - /// - /// Each prediction operation uses a cache for merge of prediction contexts. - /// Don't keep around as it wastes huge amounts of memory. The merge cache - /// isn't synchronized but we're ok since two threads shouldn't reuse same - /// parser/atnsim object because it can only handle one input at a time. - /// This maps graphs a and b to merged result c. (a,b)->c. We can avoid - /// the merge if we ever see a and b again. Note that (b,a)->c should - /// also be examined during cache lookup. - /// - PredictionContextMergeCache mergeCache; - size_t _mergeCacheCounter = 0; - - // LAME globals to avoid parameters!!!!! I need these down deep in predTransition - TokenStream *_input; - size_t _startIndex; - ParserRuleContext *_outerContext; - dfa::DFA *_dfa; // Reference into the decisionToDFA vector. - - /// - /// Performs ATN simulation to compute a predicted alternative based - /// upon the remaining input, but also updates the DFA cache to avoid - /// having to traverse the ATN again for the same input sequence. - /// - /// There are some key conditions we're looking for after computing a new - /// set of ATN configs (proposed DFA state): - /// if the set is empty, there is no viable alternative for current symbol - /// does the state uniquely predict an alternative? - /// does the state have a conflict that would prevent us from - /// putting it on the work list? - /// - /// We also have some key operations to do: - /// add an edge from previous DFA state to potentially new DFA state, D, - /// upon current symbol but only if adding to work list, which means in all - /// cases except no viable alternative (and possibly non-greedy decisions?) - /// collecting predicates and adding semantic context to DFA accept states - /// adding rule context to context-sensitive DFA accept states - /// consuming an input symbol - /// reporting a conflict - /// reporting an ambiguity - /// reporting a context sensitivity - /// reporting insufficient predicates - /// - /// cover these cases: - /// dead end - /// single alt - /// single alt + preds - /// conflict - /// conflict + preds - /// - virtual size_t execATN(dfa::DFA &dfa, dfa::DFAState *s0, TokenStream *input, size_t startIndex, - ParserRuleContext *outerContext); - - /// - /// Get an existing target state for an edge in the DFA. If the target state - /// for the edge has not yet been computed or is otherwise not available, - /// this method returns {@code null}. - /// - /// The current DFA state - /// The next input symbol - /// The existing target DFA state for the given input symbol - /// {@code t}, or {@code null} if the target state for this edge is not - /// already cached - virtual dfa::DFAState* getExistingTargetState(dfa::DFAState *previousD, size_t t); - - /// - /// Compute a target state for an edge in the DFA, and attempt to add the - /// computed state and corresponding edge to the DFA. - /// - /// The DFA - /// The current DFA state - /// The next input symbol - /// - /// The computed target DFA state for the given input symbol - /// {@code t}. If {@code t} does not lead to a valid DFA state, this method - /// returns . - virtual dfa::DFAState *computeTargetState(dfa::DFA &dfa, dfa::DFAState *previousD, size_t t); - - virtual void predicateDFAState(dfa::DFAState *dfaState, DecisionState *decisionState); - - // comes back with reach.uniqueAlt set to a valid alt - virtual size_t execATNWithFullContext(dfa::DFA &dfa, dfa::DFAState *D, ATNConfigSet *s0, - TokenStream *input, size_t startIndex, ParserRuleContext *outerContext); // how far we got before failing over - - virtual std::unique_ptr computeReachSet(ATNConfigSet *closure, size_t t, bool fullCtx); - - /// - /// Return a configuration set containing only the configurations from - /// {@code configs} which are in a . If all - /// configurations in {@code configs} are already in a rule stop state, this - /// method simply returns {@code configs}. - ///

- /// When {@code lookToEndOfRule} is true, this method uses - /// for each configuration in {@code configs} which is - /// not already in a rule stop state to see if a rule stop state is reachable - /// from the configuration via epsilon-only transitions. - ///

- /// the configuration set to update - /// when true, this method checks for rule stop states - /// reachable by epsilon-only transitions from each configuration in - /// {@code configs}. - /// - /// {@code configs} if all configurations in {@code configs} are in a - /// rule stop state, otherwise return a new configuration set containing only - /// the configurations from {@code configs} which are in a rule stop state - virtual ATNConfigSet* removeAllConfigsNotInRuleStopState(ATNConfigSet *configs, bool lookToEndOfRule); - - virtual std::unique_ptr computeStartState(ATNState *p, RuleContext *ctx, bool fullCtx); - - /* parrt internal source braindump that doesn't mess up - * external API spec. - - applyPrecedenceFilter is an optimization to avoid highly - nonlinear prediction of expressions and other left recursive - rules. The precedence predicates such as {3>=prec}? Are highly - context-sensitive in that they can only be properly evaluated - in the context of the proper prec argument. Without pruning, - these predicates are normal predicates evaluated when we reach - conflict state (or unique prediction). As we cannot evaluate - these predicates out of context, the resulting conflict leads - to full LL evaluation and nonlinear prediction which shows up - very clearly with fairly large expressions. - - Example grammar: - - e : e '*' e - | e '+' e - | INT - ; - - We convert that to the following: - - e[int prec] - : INT - ( {3>=prec}? '*' e[4] - | {2>=prec}? '+' e[3] - )* - ; - - The (..)* loop has a decision for the inner block as well as - an enter or exit decision, which is what concerns us here. At - the 1st + of input 1+2+3, the loop entry sees both predicates - and the loop exit also sees both predicates by falling off the - edge of e. This is because we have no stack information with - SLL and find the follow of e, which will hit the return states - inside the loop after e[4] and e[3], which brings it back to - the enter or exit decision. In this case, we know that we - cannot evaluate those predicates because we have fallen off - the edge of the stack and will in general not know which prec - parameter is the right one to use in the predicate. - - Because we have special information, that these are precedence - predicates, we can resolve them without failing over to full - LL despite their context sensitive nature. We make an - assumption that prec[-1] <= prec[0], meaning that the current - precedence level is greater than or equal to the precedence - level of recursive invocations above us in the stack. For - example, if predicate {3>=prec}? is true of the current prec, - then one option is to enter the loop to match it now. The - other option is to exit the loop and the left recursive rule - to match the current operator in rule invocation further up - the stack. But, we know that all of those prec are lower or - the same value and so we can decide to enter the loop instead - of matching it later. That means we can strip out the other - configuration for the exit branch. - - So imagine we have (14,1,$,{2>=prec}?) and then - (14,2,$-dipsIntoOuterContext,{2>=prec}?). The optimization - allows us to collapse these two configurations. We know that - if {2>=prec}? is true for the current prec parameter, it will - also be true for any prec from an invoking e call, indicated - by dipsIntoOuterContext. As the predicates are both true, we - have the option to evaluate them early in the decision start - state. We do this by stripping both predicates and choosing to - enter the loop as it is consistent with the notion of operator - precedence. It's also how the full LL conflict resolution - would work. - - The solution requires a different DFA start state for each - precedence level. - - The basic filter mechanism is to remove configurations of the - form (p, 2, pi) if (p, 1, pi) exists for the same p and pi. In - other words, for the same ATN state and predicate context, - remove any configuration associated with an exit branch if - there is a configuration associated with the enter branch. - - It's also the case that the filter evaluates precedence - predicates and resolves conflicts according to precedence - levels. For example, for input 1+2+3 at the first +, we see - prediction filtering - - [(11,1,[$],{3>=prec}?), (14,1,[$],{2>=prec}?), (5,2,[$],up=1), - (11,2,[$],up=1), (14,2,[$],up=1)],hasSemanticContext=true,dipsIntoOuterContext - - to - - [(11,1,[$]), (14,1,[$]), (5,2,[$],up=1)],dipsIntoOuterContext - - This filters because {3>=prec}? evals to true and collapses - (11,1,[$],{3>=prec}?) and (11,2,[$],up=1) since early conflict - resolution based upon rules of operator precedence fits with - our usual match first alt upon conflict. - - We noticed a problem where a recursive call resets precedence - to 0. Sam's fix: each config has flag indicating if it has - returned from an expr[0] call. then just don't filter any - config with that flag set. flag is carried along in - closure(). so to avoid adding field, set bit just under sign - bit of dipsIntoOuterContext (SUPPRESS_PRECEDENCE_FILTER). - With the change you filter "unless (p, 2, pi) was reached - after leaving the rule stop state of the LR rule containing - state p, corresponding to a rule invocation with precedence - level 0" - */ - - /** - * This method transforms the start state computed by - * {@link #computeStartState} to the special start state used by a - * precedence DFA for a particular precedence value. The transformation - * process applies the following changes to the start state's configuration - * set. - * - *
    - *
  1. Evaluate the precedence predicates for each configuration using - * {@link SemanticContext#evalPrecedence}.
  2. - *
  3. When {@link ATNConfig#isPrecedenceFilterSuppressed} is {@code false}, - * remove all configurations which predict an alternative greater than 1, - * for which another configuration that predicts alternative 1 is in the - * same ATN state with the same prediction context. This transformation is - * valid for the following reasons: - *
      - *
    • The closure block cannot contain any epsilon transitions which bypass - * the body of the closure, so all states reachable via alternative 1 are - * part of the precedence alternatives of the transformed left-recursive - * rule.
    • - *
    • The "primary" portion of a left recursive rule cannot contain an - * epsilon transition, so the only way an alternative other than 1 can exist - * in a state that is also reachable via alternative 1 is by nesting calls - * to the left-recursive rule, with the outer calls not being at the - * preferred precedence level. The - * {@link ATNConfig#isPrecedenceFilterSuppressed} property marks ATN - * configurations which do not meet this condition, and therefore are not - * eligible for elimination during the filtering process.
    • - *
    - *
  4. - *
- * - *

- * The prediction context must be considered by this filter to address - * situations like the following. - *

- * - *
-     * grammar TA;
-     * prog: statement* EOF;
-     * statement: letterA | statement letterA 'b' ;
-     * letterA: 'a';
-     * 
- *
- *

- * If the above grammar, the ATN state immediately before the token - * reference {@code 'a'} in {@code letterA} is reachable from the left edge - * of both the primary and closure blocks of the left-recursive rule - * {@code statement}. The prediction context associated with each of these - * configurations distinguishes between them, and prevents the alternative - * which stepped out to {@code prog} (and then back in to {@code statement} - * from being eliminated by the filter. - *

- * - * @param configs The configuration set computed by - * {@link #computeStartState} as the start state for the DFA. - * @return The transformed configuration set representing the start state - * for a precedence DFA at a particular precedence level (determined by - * calling {@link Parser#getPrecedence}). - */ - std::unique_ptr applyPrecedenceFilter(ATNConfigSet *configs); - - virtual ATNState *getReachableTarget(const Transition *trans, size_t ttype); - - virtual std::vector> getPredsForAmbigAlts(const antlrcpp::BitSet &ambigAlts, - ATNConfigSet *configs, size_t nalts); - - std::vector getPredicatePredictions(const antlrcpp::BitSet &ambigAlts, - const std::vector> &altToPred); - - /** - * This method is used to improve the localization of error messages by - * choosing an alternative rather than throwing a - * {@link NoViableAltException} in particular prediction scenarios where the - * {@link #ERROR} state was reached during ATN simulation. - * - *

- * The default implementation of this method uses the following - * algorithm to identify an ATN configuration which successfully parsed the - * decision entry rule. Choosing such an alternative ensures that the - * {@link ParserRuleContext} returned by the calling rule will be complete - * and valid, and the syntax error will be reported later at a more - * localized location.

- * - *
    - *
  • If a syntactically valid path or paths reach the end of the decision rule and - * they are semantically valid if predicated, return the min associated alt.
  • - *
  • Else, if a semantically invalid but syntactically valid path exist - * or paths exist, return the minimum associated alt. - *
  • - *
  • Otherwise, return {@link ATN#INVALID_ALT_NUMBER}.
  • - *
- * - *

- * In some scenarios, the algorithm described above could predict an - * alternative which will result in a {@link FailedPredicateException} in - * the parser. Specifically, this could occur if the only configuration - * capable of successfully parsing to the end of the decision rule is - * blocked by a semantic predicate. By choosing this alternative within - * {@link #adaptivePredict} instead of throwing a - * {@link NoViableAltException}, the resulting - * {@link FailedPredicateException} in the parser will identify the specific - * predicate which is preventing the parser from successfully parsing the - * decision rule, which helps developers identify and correct logic errors - * in semantic predicates. - *

- * - * @param configs The ATN configurations which were valid immediately before - * the {@link #ERROR} state was reached - * @param outerContext The is the \gamma_0 initial parser context from the paper - * or the parser stack at the instant before prediction commences. - * - * @return The value to return from {@link #adaptivePredict}, or - * {@link ATN#INVALID_ALT_NUMBER} if a suitable alternative was not - * identified and {@link #adaptivePredict} should report an error instead. - */ - size_t getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(ATNConfigSet *configs, - ParserRuleContext *outerContext); - - virtual size_t getAltThatFinishedDecisionEntryRule(ATNConfigSet *configs); - - /** Walk the list of configurations and split them according to - * those that have preds evaluating to true/false. If no pred, assume - * true pred and include in succeeded set. Returns Pair of sets. - * - * Create a new set so as not to alter the incoming parameter. - * - * Assumption: the input stream has been restored to the starting point - * prediction, which is where predicates need to evaluate. - */ - std::pair splitAccordingToSemanticValidity(ATNConfigSet *configs, - ParserRuleContext *outerContext); - - /// - /// Look through a list of predicate/alt pairs, returning alts for the - /// pairs that win. A {@code NONE} predicate indicates an alt containing an - /// unpredicated config which behaves as "always true." If !complete - /// then we stop at the first predicate that evaluates to true. This - /// includes pairs with null predicates. - /// - antlrcpp::BitSet evalSemanticContext(const std::vector &predPredictions, - ParserRuleContext *outerContext, bool complete); - - /** - * Evaluate a semantic context within a specific parser context. - * - *

- * This method might not be called for every semantic context evaluated - * during the prediction process. In particular, we currently do not - * evaluate the following but it may change in the future:

- * - *
    - *
  • Precedence predicates (represented by - * {@link SemanticContext.PrecedencePredicate}) are not currently evaluated - * through this method.
  • - *
  • Operator predicates (represented by {@link SemanticContext.AND} and - * {@link SemanticContext.OR}) are evaluated as a single semantic - * context, rather than evaluating the operands individually. - * Implementations which require evaluation results from individual - * predicates should override this method to explicitly handle evaluation of - * the operands within operator predicates.
  • - *
- * - * @param pred The semantic context to evaluate - * @param parserCallStack The parser context in which to evaluate the - * semantic context - * @param alt The alternative which is guarded by {@code pred} - * @param fullCtx {@code true} if the evaluation is occurring during LL - * prediction; otherwise, {@code false} if the evaluation is occurring - * during SLL prediction - * - * @since 4.3 - */ - virtual bool evalSemanticContext(Ref const& pred, ParserRuleContext *parserCallStack, - size_t alt, bool fullCtx); - - /* TODO: If we are doing predicates, there is no point in pursuing - closure operations if we reach a DFA state that uniquely predicts - alternative. We will not be caching that DFA state and it is a - waste to pursue the closure. Might have to advance when we do - ambig detection thought :( - */ - virtual void closure(Ref const& config, ATNConfigSet *configs, ATNConfig::Set &closureBusy, - bool collectPredicates, bool fullCtx, bool treatEofAsEpsilon); - - virtual void closureCheckingStopState(Ref const& config, ATNConfigSet *configs, ATNConfig::Set &closureBusy, - bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon); - - /// Do the actual work of walking epsilon edges. - virtual void closure_(Ref const& config, ATNConfigSet *configs, ATNConfig::Set &closureBusy, - bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon); - - virtual Ref getEpsilonTarget(Ref const& config, const Transition *t, bool collectPredicates, - bool inContext, bool fullCtx, bool treatEofAsEpsilon); - virtual Ref actionTransition(Ref const& config, const ActionTransition *t); - - virtual Ref predTransition(Ref const& config, const PredicateTransition *pt, bool collectPredicates, - bool inContext, bool fullCtx); - - virtual Ref ruleTransition(Ref const& config, const RuleTransition *t); - - /** - * Gets a {@link BitSet} containing the alternatives in {@code configs} - * which are part of one or more conflicting alternative subsets. - * - * @param configs The {@link ATNConfigSet} to analyze. - * @return The alternatives in {@code configs} which are part of one or more - * conflicting alternative subsets. If {@code configs} does not contain any - * conflicting subsets, this method returns an empty {@link BitSet}. - */ - virtual antlrcpp::BitSet getConflictingAlts(ATNConfigSet *configs); - - /// - /// Sam pointed out a problem with the previous definition, v3, of - /// ambiguous states. If we have another state associated with conflicting - /// alternatives, we should keep going. For example, the following grammar - /// - /// s : (ID | ID ID?) ';' ; - /// - /// When the ATN simulation reaches the state before ';', it has a DFA - /// state that looks like: [12|1|[], 6|2|[], 12|2|[]]. Naturally - /// 12|1|[] and 12|2|[] conflict, but we cannot stop processing this node - /// because alternative to has another way to continue, via [6|2|[]]. - /// The key is that we have a single state that has config's only associated - /// with a single alternative, 2, and crucially the state transitions - /// among the configurations are all non-epsilon transitions. That means - /// we don't consider any conflicts that include alternative 2. So, we - /// ignore the conflict between alts 1 and 2. We ignore a set of - /// conflicting alts when there is an intersection with an alternative - /// associated with a single alt state in the state->config-list map. - /// - /// It's also the case that we might have two conflicting configurations but - /// also a 3rd nonconflicting configuration for a different alternative: - /// [1|1|[], 1|2|[], 8|3|[]]. This can come about from grammar: - /// - /// a : A | A | A B ; - /// - /// After matching input A, we reach the stop state for rule A, state 1. - /// State 8 is the state right before B. Clearly alternatives 1 and 2 - /// conflict and no amount of further lookahead will separate the two. - /// However, alternative 3 will be able to continue and so we do not - /// stop working on this state. In the previous example, we're concerned - /// with states associated with the conflicting alternatives. Here alt - /// 3 is not associated with the conflicting configs, but since we can continue - /// looking for input reasonably, I don't declare the state done. We - /// ignore a set of conflicting alts when we have an alternative - /// that we still need to pursue. - /// - - virtual antlrcpp::BitSet getConflictingAltsOrUniqueAlt(ATNConfigSet *configs); - - virtual NoViableAltException noViableAlt(TokenStream *input, ParserRuleContext *outerContext, - ATNConfigSet *configs, size_t startIndex, bool deleteConfigs); - - static size_t getUniqueAlt(ATNConfigSet *configs); - - /// - /// Add an edge to the DFA, if possible. This method calls - /// to ensure the {@code to} state is present in the - /// DFA. If {@code from} is {@code null}, or if {@code t} is outside the - /// range of edges that can be represented in the DFA tables, this method - /// returns without adding the edge to the DFA. - ///

- /// If {@code to} is {@code null}, this method returns {@code null}. - /// Otherwise, this method returns the returned by calling - /// for the {@code to} state. - ///

- /// The DFA - /// The source state for the edge - /// The input symbol - /// The target state for the edge - /// - /// If {@code to} is {@code null}, this method returns {@code null}; - /// otherwise this method returns the result of calling - /// on {@code to} - virtual dfa::DFAState *addDFAEdge(dfa::DFA &dfa, dfa::DFAState *from, ssize_t t, dfa::DFAState *to); - - /// - /// Add state {@code D} to the DFA if it is not already present, and return - /// the actual instance stored in the DFA. If a state equivalent to {@code D} - /// is already in the DFA, the existing state is returned. Otherwise this - /// method returns {@code D} after adding it to the DFA. - ///

- /// If {@code D} is , this method returns and - /// does not change the DFA. - ///

- /// The dfa - /// The DFA state to add - /// The state stored in the DFA. This will be either the existing - /// state if {@code D} is already in the DFA, or {@code D} itself if the - /// state was not already present. - virtual dfa::DFAState *addDFAState(dfa::DFA &dfa, dfa::DFAState *D); - - virtual void reportAttemptingFullContext(dfa::DFA &dfa, const antlrcpp::BitSet &conflictingAlts, - ATNConfigSet *configs, size_t startIndex, size_t stopIndex); - - virtual void reportContextSensitivity(dfa::DFA &dfa, size_t prediction, ATNConfigSet *configs, - size_t startIndex, size_t stopIndex); - - /// If context sensitive parsing, we know it's ambiguity not conflict. - virtual void reportAmbiguity(dfa::DFA &dfa, - dfa::DFAState *D, // the DFA state from execATN() that had SLL conflicts - size_t startIndex, size_t stopIndex, - bool exact, - const antlrcpp::BitSet &ambigAlts, - ATNConfigSet *configs); // configs that LL not SLL considered conflicting - - private: - // SLL, LL, or LL + exact ambig detection? - PredictionMode _mode; - - static bool getLrLoopSetting(); - void InitializeInstanceFields(); - }; - -} // namespace atn -} // namespace antlr4 - diff --git a/src/include/atn/ParserATNSimulatorOptions.h b/src/include/atn/ParserATNSimulatorOptions.h deleted file mode 100644 index ea31226d..00000000 --- a/src/include/atn/ParserATNSimulatorOptions.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2012-2022 The ANTLR Project -// -// 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. Neither the name of the copyright holder nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR -// CONTRIBUTORS 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 - -#include "atn/PredictionContextMergeCacheOptions.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC ParserATNSimulatorOptions final { - public: - ParserATNSimulatorOptions& setPredictionContextMergeCacheOptions( - PredictionContextMergeCacheOptions predictionContextMergeCacheOptions) { - _predictionContextMergeCacheOptions = std::move(predictionContextMergeCacheOptions); - return *this; - } - - const PredictionContextMergeCacheOptions& getPredictionContextMergeCacheOptions() const { - return _predictionContextMergeCacheOptions; - } - - private: - PredictionContextMergeCacheOptions _predictionContextMergeCacheOptions; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PlusBlockStartState.h b/src/include/atn/PlusBlockStartState.h deleted file mode 100755 index 6f67a8ac..00000000 --- a/src/include/atn/PlusBlockStartState.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/BlockStartState.h" - -namespace antlr4 { -namespace atn { - - /// Start of {@code (A|B|...)+} loop. Technically a decision state, but - /// we don't use for code generation; somebody might need it, so I'm defining - /// it for completeness. In reality, the node is the - /// real decision-making note for {@code A+}. - class ANTLR4CPP_PUBLIC PlusBlockStartState final : public BlockStartState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::PLUS_BLOCK_START; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - PlusLoopbackState *loopBackState = nullptr; - - PlusBlockStartState() : BlockStartState(ATNStateType::PLUS_BLOCK_START) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PlusLoopbackState.h b/src/include/atn/PlusLoopbackState.h deleted file mode 100755 index d83ed7d0..00000000 --- a/src/include/atn/PlusLoopbackState.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionState.h" - -namespace antlr4 { -namespace atn { - - /// Decision state for {@code A+} and {@code (A|B)+}. It has two transitions: - /// one to the loop back to start of the block and one to exit. - class ANTLR4CPP_PUBLIC PlusLoopbackState final : public DecisionState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::PLUS_LOOP_BACK; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - PlusLoopbackState() : DecisionState(ATNStateType::PLUS_LOOP_BACK) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PrecedencePredicateTransition.cpp b/src/include/atn/PrecedencePredicateTransition.cpp deleted file mode 100755 index a0d123fd..00000000 --- a/src/include/atn/PrecedencePredicateTransition.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/PrecedencePredicateTransition.h" - -using namespace antlr4::atn; - -PrecedencePredicateTransition::PrecedencePredicateTransition(ATNState *target, int precedence) - : Transition(TransitionType::PRECEDENCE, target), _predicate(std::make_shared(precedence)) {} - -bool PrecedencePredicateTransition::isEpsilon() const { - return true; -} - -bool PrecedencePredicateTransition::matches(size_t /*symbol*/, size_t /*minVocabSymbol*/, size_t /*maxVocabSymbol*/) const { - return false; -} - -std::string PrecedencePredicateTransition::toString() const { - return "PRECEDENCE " + Transition::toString() + " { precedence: " + std::to_string(getPrecedence()) + " }"; -} diff --git a/src/include/atn/PrecedencePredicateTransition.h b/src/include/atn/PrecedencePredicateTransition.h deleted file mode 100755 index 1bf83fb7..00000000 --- a/src/include/atn/PrecedencePredicateTransition.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/Transition.h" -#include "atn/SemanticContext.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC PrecedencePredicateTransition final : public Transition { - public: - static bool is(const Transition &transition) { return transition.getTransitionType() == TransitionType::PRECEDENCE; } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - PrecedencePredicateTransition(ATNState *target, int precedence); - - int getPrecedence() const { return _predicate->precedence; } - - bool isEpsilon() const override; - bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - std::string toString() const override; - - const Ref& getPredicate() const { return _predicate; } - - private: - const std::shared_ptr _predicate; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PredicateEvalInfo.cpp b/src/include/atn/PredicateEvalInfo.cpp deleted file mode 100755 index 73ee2a2b..00000000 --- a/src/include/atn/PredicateEvalInfo.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "SemanticContext.h" - -#include "atn/PredicateEvalInfo.h" - -using namespace antlr4; -using namespace antlr4::atn; - -PredicateEvalInfo::PredicateEvalInfo(size_t decision, TokenStream *input, size_t startIndex, size_t stopIndex, - Ref semctx, bool evalResult, size_t predictedAlt, bool fullCtx) - : DecisionEventInfo(decision, nullptr, input, startIndex, stopIndex, fullCtx), - semctx(std::move(semctx)), predictedAlt(predictedAlt), evalResult(evalResult) { -} diff --git a/src/include/atn/PredicateEvalInfo.h b/src/include/atn/PredicateEvalInfo.h deleted file mode 100755 index f343f541..00000000 --- a/src/include/atn/PredicateEvalInfo.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionEventInfo.h" - -namespace antlr4 { -namespace atn { - - /// - /// This class represents profiling event information for semantic predicate - /// evaluations which occur during prediction. - /// - /// - class ANTLR4CPP_PUBLIC PredicateEvalInfo : public DecisionEventInfo { - public: - /// The semantic context which was evaluated. - const Ref semctx; - - /// - /// The alternative number for the decision which is guarded by the semantic - /// context . Note that other ATN - /// configurations may predict the same alternative which are guarded by - /// other semantic contexts and/or . - /// - const size_t predictedAlt; - - /// The result of evaluating the semantic context . - const bool evalResult; - - /// - /// Constructs a new instance of the class with the - /// specified detailed predicate evaluation information. - /// - /// The decision number - /// The input token stream - /// The start index for the current prediction - /// The index at which the predicate evaluation was - /// triggered. Note that the input stream may be reset to other positions for - /// the actual evaluation of individual predicates. - /// The semantic context which was evaluated - /// The results of evaluating the semantic context - /// The alternative number for the decision which is - /// guarded by the semantic context {@code semctx}. See - /// for more information. - /// {@code true} if the semantic context was - /// evaluated during LL prediction; otherwise, {@code false} if the semantic - /// context was evaluated during SLL prediction - /// - /// - /// - PredicateEvalInfo(size_t decision, TokenStream *input, size_t startIndex, size_t stopIndex, - Ref semctx, bool evalResult, size_t predictedAlt, bool fullCtx); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PredicateTransition.cpp b/src/include/atn/PredicateTransition.cpp deleted file mode 100755 index 4ba50730..00000000 --- a/src/include/atn/PredicateTransition.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/PredicateTransition.h" - -using namespace antlr4::atn; - -PredicateTransition::PredicateTransition(ATNState *target, size_t ruleIndex, size_t predIndex, bool isCtxDependent) - : Transition(TransitionType::PREDICATE, target), _predicate(std::make_shared(ruleIndex, predIndex, isCtxDependent)) {} - -bool PredicateTransition::isEpsilon() const { - return true; -} - -bool PredicateTransition::matches(size_t /*symbol*/, size_t /*minVocabSymbol*/, size_t /*maxVocabSymbol*/) const { - return false; -} - -std::string PredicateTransition::toString() const { - return "PREDICATE " + Transition::toString() + " { ruleIndex: " + std::to_string(getRuleIndex()) + - ", predIndex: " + std::to_string(getPredIndex()) + ", isCtxDependent: " + std::to_string(isCtxDependent()) + " }"; -} diff --git a/src/include/atn/PredicateTransition.h b/src/include/atn/PredicateTransition.h deleted file mode 100755 index e889b1c1..00000000 --- a/src/include/atn/PredicateTransition.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/Transition.h" -#include "atn/SemanticContext.h" - -namespace antlr4 { -namespace atn { - - /// TODO: this is old comment: - /// A tree of semantic predicates from the grammar AST if label==SEMPRED. - /// In the ATN, labels will always be exactly one predicate, but the DFA - /// may have to combine a bunch of them as it collects predicates from - /// multiple ATN configurations into a single DFA state. - class ANTLR4CPP_PUBLIC PredicateTransition final : public Transition { - public: - static bool is(const Transition &transition) { return transition.getTransitionType() == TransitionType::PREDICATE; } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - PredicateTransition(ATNState *target, size_t ruleIndex, size_t predIndex, bool isCtxDependent); - - size_t getRuleIndex() const { - return _predicate->ruleIndex; - } - - size_t getPredIndex() const { - return _predicate->predIndex; - } - - bool isCtxDependent() const { - return _predicate->isCtxDependent; - } - - bool isEpsilon() const override; - bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - std::string toString() const override; - - const Ref& getPredicate() const { return _predicate; } - - private: - const std::shared_ptr _predicate; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PredictionContext.cpp b/src/include/atn/PredictionContext.cpp deleted file mode 100755 index b976de8f..00000000 --- a/src/include/atn/PredictionContext.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/SingletonPredictionContext.h" -#include "misc/MurmurHash.h" -#include "atn/ArrayPredictionContext.h" -#include "atn/PredictionContextCache.h" -#include "atn/PredictionContextMergeCache.h" -#include "RuleContext.h" -#include "ParserRuleContext.h" -#include "atn/RuleTransition.h" -#include "support/Arrays.h" -#include "support/CPPUtils.h" -#include "support/Casts.h" - -#include "atn/PredictionContext.h" - -using namespace antlr4; -using namespace antlr4::misc; -using namespace antlr4::atn; -using namespace antlrcpp; - -namespace { - - void combineCommonParents(std::vector> &parents) { - std::unordered_set> uniqueParents; - uniqueParents.reserve(parents.size()); - for (const auto &parent : parents) { - uniqueParents.insert(parent); - } - for (auto &parent : parents) { - parent = *uniqueParents.find(parent); - } - } - - Ref getCachedContextImpl(const Ref &context, - PredictionContextCache &contextCache, - std::unordered_map, - Ref> &visited) { - if (context->isEmpty()) { - return context; - } - - { - auto iterator = visited.find(context); - if (iterator != visited.end()) { - return iterator->second; // Not necessarly the same as context. - } - } - - auto cached = contextCache.get(context); - if (cached) { - visited[context] = cached; - return cached; - } - - bool changed = false; - - std::vector> parents(context->size()); - for (size_t i = 0; i < parents.size(); i++) { - auto parent = getCachedContextImpl(context->getParent(i), contextCache, visited); - if (changed || parent != context->getParent(i)) { - if (!changed) { - parents.clear(); - for (size_t j = 0; j < context->size(); j++) { - parents.push_back(context->getParent(j)); - } - - changed = true; - } - - parents[i] = std::move(parent); - } - } - - if (!changed) { - visited[context] = context; - contextCache.put(context); - return context; - } - - Ref updated; - if (parents.empty()) { - updated = PredictionContext::EMPTY; - } else if (parents.size() == 1) { - updated = SingletonPredictionContext::create(std::move(parents[0]), context->getReturnState(0)); - contextCache.put(updated); - } else { - updated = std::make_shared(std::move(parents), downCast(context.get())->returnStates); - contextCache.put(updated); - } - - visited[updated] = updated; - visited[context] = updated; - - return updated; - } - - void getAllContextNodesImpl(const Ref &context, - std::vector> &nodes, - std::unordered_set &visited) { - - if (visited.find(context.get()) != visited.end()) { - return; // Already done. - } - - visited.insert(context.get()); - nodes.push_back(context); - - for (size_t i = 0; i < context->size(); i++) { - getAllContextNodesImpl(context->getParent(i), nodes, visited); - } - } - - size_t insertOrAssignNodeId(std::unordered_map &nodeIds, size_t &nodeId, const PredictionContext *node) { - auto existing = nodeIds.find(node); - if (existing != nodeIds.end()) { - return existing->second; - } - return nodeIds.insert({node, nodeId++}).first->second; - } - -} - -const Ref PredictionContext::EMPTY = std::make_shared(nullptr, PredictionContext::EMPTY_RETURN_STATE); - -//----------------- PredictionContext ---------------------------------------------------------------------------------- - -PredictionContext::PredictionContext(PredictionContextType contextType) : _contextType(contextType), _hashCode(0) {} - -PredictionContext::PredictionContext(PredictionContext&& other) : _contextType(other._contextType), _hashCode(other._hashCode.exchange(0, std::memory_order_relaxed)) {} - -Ref PredictionContext::fromRuleContext(const ATN &atn, RuleContext *outerContext) { - if (outerContext == nullptr) { - return PredictionContext::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 == &ParserRuleContext::EMPTY) { - return PredictionContext::EMPTY; - } - - // If we have a parent, convert it to a PredictionContext graph - auto parent = PredictionContext::fromRuleContext(atn, RuleContext::is(outerContext->parent) ? downCast(outerContext->parent) : nullptr); - const auto *transition = downCast(atn.states[outerContext->invokingState]->transitions[0].get()); - return SingletonPredictionContext::create(std::move(parent), transition->followState->stateNumber); -} - -bool PredictionContext::hasEmptyPath() const { - // since EMPTY_RETURN_STATE can only appear in the last position, we check last one - return getReturnState(size() - 1) == EMPTY_RETURN_STATE; -} - -size_t PredictionContext::hashCode() const { - auto hash = cachedHashCode(); - if (hash == 0) { - hash = hashCodeImpl(); - if (hash == 0) { - hash = std::numeric_limits::max(); - } - _hashCode.store(hash, std::memory_order_relaxed); - } - return hash; -} - -Ref PredictionContext::merge(Ref a, Ref b, - bool rootIsWildcard, PredictionContextMergeCache *mergeCache) { - assert(a && b); - - // share same graph if both same - if (a == b || *a == *b) { - return a; - } - - const auto aType = a->getContextType(); - const auto bType = b->getContextType(); - - if (aType == PredictionContextType::SINGLETON && bType == PredictionContextType::SINGLETON) { - return mergeSingletons(std::static_pointer_cast(std::move(a)), - std::static_pointer_cast(std::move(b)), rootIsWildcard, mergeCache); - } - - // At least one of a or b is array. - // If one is $ and rootIsWildcard, return $ as * wildcard. - if (rootIsWildcard) { - if (a == PredictionContext::EMPTY) { - return a; - } - if (b == PredictionContext::EMPTY) { - return b; - } - } - - // convert singleton so both are arrays to normalize - Ref left; - if (aType == PredictionContextType::SINGLETON) { - left = std::make_shared(downCast(*a)); - } else { - left = std::static_pointer_cast(std::move(a)); - } - Ref right; - if (bType == PredictionContextType::SINGLETON) { - right = std::make_shared(downCast(*b)); - } else { - right = std::static_pointer_cast(std::move(b)); - } - return mergeArrays(std::move(left), std::move(right), rootIsWildcard, mergeCache); -} - -Ref PredictionContext::mergeSingletons(Ref a, Ref b, - bool rootIsWildcard, PredictionContextMergeCache *mergeCache) { - - if (mergeCache) { - auto existing = mergeCache->get(a, b); - if (existing) { - return existing; - } - existing = mergeCache->get(b, a); - if (existing) { - return existing; - } - } - - auto rootMerge = mergeRoot(a, b, rootIsWildcard); - if (rootMerge) { - if (mergeCache) { - return mergeCache->put(a, b, std::move(rootMerge)); - } - return rootMerge; - } - - const auto& parentA = a->parent; - const auto& parentB = b->parent; - if (a->returnState == b->returnState) { // a == b - auto parent = merge(parentA, parentB, rootIsWildcard, mergeCache); - - // If parent is same as existing a or b parent or reduced to a parent, return it. - if (parent == parentA) { // ax + bx = ax, if a=b - return a; - } - if (parent == parentB) { // ax + bx = bx, if a=b - return b; - } - - // else: ax + ay = a'[x,y] - // merge parents x and y, giving array node with x,y then remainders - // of those graphs. dup a, a' points at merged array - // new joined parent so create new singleton pointing to it, a' - auto c = SingletonPredictionContext::create(std::move(parent), a->returnState); - if (mergeCache) { - return mergeCache->put(a, b, std::move(c)); - } - return c; - } - // a != b payloads differ - // see if we can collapse parents due to $+x parents if local ctx - Ref singleParent; - if (a == b || (*parentA == *parentB)) { // ax + bx = [a,b]x - singleParent = parentA; - } - if (singleParent) { // parents are same, sort payloads and use same parent - std::vector payloads = { a->returnState, b->returnState }; - if (a->returnState > b->returnState) { - payloads[0] = b->returnState; - payloads[1] = a->returnState; - } - std::vector> parents = { singleParent, singleParent }; - auto c = std::make_shared(std::move(parents), std::move(payloads)); - if (mergeCache) { - return mergeCache->put(a, b, std::move(c)); - } - return c; - } - - // parents differ and can't merge them. Just pack together - // into array; can't merge. - // ax + by = [ax,by] - if (a->returnState > b->returnState) { // sort by payload - std::vector payloads = { b->returnState, a->returnState }; - std::vector> parents = { b->parent, a->parent }; - auto c = std::make_shared(std::move(parents), std::move(payloads)); - if (mergeCache) { - return mergeCache->put(a, b, std::move(c)); - } - return c; - } - std::vector payloads = {a->returnState, b->returnState}; - std::vector> parents = { a->parent, b->parent }; - auto c = std::make_shared(std::move(parents), std::move(payloads)); - if (mergeCache) { - return mergeCache->put(a, b, std::move(c)); - } - return c; -} - -Ref PredictionContext::mergeRoot(Ref a, Ref b, - bool rootIsWildcard) { - if (rootIsWildcard) { - if (a == EMPTY) { // * + b = * - return EMPTY; - } - if (b == EMPTY) { // a + * = * - return EMPTY; - } - } else { - if (a == EMPTY && b == EMPTY) { // $ + $ = $ - return EMPTY; - } - if (a == EMPTY) { // $ + x = [$,x] - std::vector payloads = { b->returnState, EMPTY_RETURN_STATE }; - std::vector> parents = { b->parent, nullptr }; - return std::make_shared(std::move(parents), std::move(payloads)); - } - if (b == EMPTY) { // x + $ = [$,x] ($ is always first if present) - std::vector payloads = { a->returnState, EMPTY_RETURN_STATE }; - std::vector> parents = { a->parent, nullptr }; - return std::make_shared(std::move(parents), std::move(payloads)); - } - } - return nullptr; -} - -Ref PredictionContext::mergeArrays(Ref a, Ref b, - bool rootIsWildcard, PredictionContextMergeCache *mergeCache) { - if (mergeCache) { - auto existing = mergeCache->get(a, b); - if (existing) { -#if TRACE_ATN_SIM == 1 - std::cout << "mergeArrays a=" << a->toString() << ",b=" << b->toString() << " -> previous" << std::endl; -#endif - return existing; - } - existing = mergeCache->get(b, a); - if (existing) { -#if TRACE_ATN_SIM == 1 - std::cout << "mergeArrays a=" << a->toString() << ",b=" << b->toString() << " -> previous" << std::endl; -#endif - return existing; - } - } - - // merge sorted payloads a + b => M - size_t i = 0; // walks a - size_t j = 0; // walks b - size_t k = 0; // walks target M array - - std::vector mergedReturnStates(a->returnStates.size() + b->returnStates.size()); - std::vector> mergedParents(a->returnStates.size() + b->returnStates.size()); - - // walk and merge to yield mergedParents, mergedReturnStates - while (i < a->returnStates.size() && j < b->returnStates.size()) { - const auto& parentA = a->parents[i]; - const auto& parentB = b->parents[j]; - if (a->returnStates[i] == b->returnStates[j]) { - // same payload (stack tops are equal), must yield merged singleton - size_t payload = a->returnStates[i]; - // $+$ = $ - bool both$ = payload == EMPTY_RETURN_STATE && !parentA && !parentB; - bool ax_ax = (parentA && parentB) && *parentA == *parentB; // ax+ax -> ax - if (both$ || ax_ax) { - mergedParents[k] = parentA; // choose left - mergedReturnStates[k] = payload; - } else { // ax+ay -> a'[x,y] - mergedParents[k] = merge(parentA, parentB, rootIsWildcard, mergeCache); - mergedReturnStates[k] = payload; - } - i++; // hop over left one as usual - j++; // but also skip one in right side since we merge - } else if (a->returnStates[i] < b->returnStates[j]) { // copy a[i] to M - mergedParents[k] = parentA; - mergedReturnStates[k] = a->returnStates[i]; - i++; - } else { // b > a, copy b[j] to M - mergedParents[k] = parentB; - mergedReturnStates[k] = b->returnStates[j]; - j++; - } - k++; - } - - // copy over any payloads remaining in either array - if (i < a->returnStates.size()) { - for (auto p = i; p < a->returnStates.size(); p++) { - mergedParents[k] = a->parents[p]; - mergedReturnStates[k] = a->returnStates[p]; - k++; - } - } else { - for (auto p = j; p < b->returnStates.size(); p++) { - mergedParents[k] = b->parents[p]; - mergedReturnStates[k] = b->returnStates[p]; - k++; - } - } - - // trim merged if we combined a few that had same stack tops - if (k < mergedParents.size()) { // write index < last position; trim - if (k == 1) { // for just one merged element, return singleton top - auto c = SingletonPredictionContext::create(std::move(mergedParents[0]), mergedReturnStates[0]); - if (mergeCache) { - return mergeCache->put(a, b, std::move(c)); - } - return c; - } - mergedParents.resize(k); - mergedReturnStates.resize(k); - } - - ArrayPredictionContext m(std::move(mergedParents), std::move(mergedReturnStates)); - - // if we created same array as a or b, return that instead - // TODO: track whether this is possible above during merge sort for speed - if (m == *a) { - if (mergeCache) { -#if TRACE_ATN_SIM == 1 - std::cout << "mergeArrays a=" << a->toString() << ",b=" << b->toString() << " -> a" << std::endl; -#endif - return mergeCache->put(a, b, a); - } -#if TRACE_ATN_SIM == 1 - std::cout << "mergeArrays a=" << a->toString() << ",b=" << b->toString() << " -> a" << std::endl; -#endif - return a; - } - if (m == *b) { - if (mergeCache) { -#if TRACE_ATN_SIM == 1 - std::cout << "mergeArrays a=" << a->toString() << ",b=" << b->toString() << " -> b" << std::endl; -#endif - return mergeCache->put(a, b, b); - } -#if TRACE_ATN_SIM == 1 - std::cout << "mergeArrays a=" << a->toString() << ",b=" << b->toString() << " -> b" << std::endl; -#endif - return b; - } - - combineCommonParents(m.parents); - auto c = std::make_shared(std::move(m)); - -#if TRACE_ATN_SIM == 1 - std::cout << "mergeArrays a=" << a->toString() << ",b=" << b->toString() << " -> " << c->toString() << std::endl; -#endif - - if (mergeCache) { - return mergeCache->put(a, b, std::move(c)); - } - return c; -} - -std::string PredictionContext::toDOTString(const Ref &context) { - if (context == nullptr) { - return ""; - } - - std::stringstream ss; - ss << "digraph G {\n" << "rankdir=LR;\n"; - - std::vector> nodes = getAllContextNodes(context); - std::unordered_map nodeIds; - size_t nodeId = 0; - - for (const auto ¤t : nodes) { - if (current->getContextType() == PredictionContextType::SINGLETON) { - std::string s = std::to_string(insertOrAssignNodeId(nodeIds, nodeId, current.get())); - ss << " s" << s; - std::string returnState = std::to_string(current->getReturnState(0)); - if (current == PredictionContext::EMPTY) { - returnState = "$"; - } - ss << " [label=\"" << returnState << "\"];\n"; - continue; - } - Ref arr = std::static_pointer_cast(current); - ss << " s" << insertOrAssignNodeId(nodeIds, nodeId, arr.get()) << " [shape=box, label=\"" << "["; - bool first = true; - for (auto inv : arr->returnStates) { - if (!first) { - ss << ", "; - } - if (inv == EMPTY_RETURN_STATE) { - ss << "$"; - } else { - ss << inv; - } - first = false; - } - ss << "]"; - ss << "\"];\n"; - } - - for (const auto ¤t : nodes) { - if (current == EMPTY) { - continue; - } - for (size_t i = 0; i < current->size(); i++) { - if (!current->getParent(i)) { - continue; - } - ss << " s" << insertOrAssignNodeId(nodeIds, nodeId, current.get()) << "->" << "s" << insertOrAssignNodeId(nodeIds, nodeId, current->getParent(i).get()); - if (current->size() > 1) { - ss << " [label=\"parent[" << i << "]\"];\n"; - } else { - ss << ";\n"; - } - } - } - - ss << "}\n"; - return ss.str(); -} - -// The "visited" map is just a temporary structure to control the retrieval process (which is recursive). -Ref PredictionContext::getCachedContext(const Ref &context, - PredictionContextCache &contextCache) { - std::unordered_map, Ref> visited; - return getCachedContextImpl(context, contextCache, visited); -} - -std::vector> PredictionContext::getAllContextNodes(const Ref &context) { - std::vector> nodes; - std::unordered_set visited; - getAllContextNodesImpl(context, nodes, visited); - return nodes; -} - -std::vector PredictionContext::toStrings(Recognizer *recognizer, int currentState) const { - return toStrings(recognizer, EMPTY, currentState); -} - -std::vector PredictionContext::toStrings(Recognizer *recognizer, const Ref &stop, int currentState) const { - - std::vector result; - - for (size_t perm = 0; ; perm++) { - size_t offset = 0; - bool last = true; - const PredictionContext *p = this; - size_t stateNumber = currentState; - - std::stringstream ss; - ss << "["; - bool outerContinue = false; - while (!p->isEmpty() && p != stop.get()) { - size_t index = 0; - if (p->size() > 0) { - size_t bits = 1; - while ((1ULL << bits) < p->size()) { - bits++; - } - - size_t mask = (1 << bits) - 1; - index = (perm >> offset) & mask; - last &= index >= p->size() - 1; - if (index >= p->size()) { - outerContinue = true; - break; - } - offset += bits; - } - - if (recognizer != nullptr) { - if (ss.tellp() > 1) { - // first char is '[', if more than that this isn't the first rule - ss << ' '; - } - - const ATN &atn = recognizer->getATN(); - ATNState *s = atn.states[stateNumber]; - std::string ruleName = recognizer->getRuleNames()[s->ruleIndex]; - ss << ruleName; - } else if (p->getReturnState(index) != EMPTY_RETURN_STATE) { - if (!p->isEmpty()) { - if (ss.tellp() > 1) { - // first char is '[', if more than that this isn't the first rule - ss << ' '; - } - - ss << p->getReturnState(index); - } - } - stateNumber = p->getReturnState(index); - p = p->getParent(index).get(); - } - - if (outerContinue) - continue; - - ss << "]"; - result.push_back(ss.str()); - - if (last) { - break; - } - } - - return result; -} diff --git a/src/include/atn/PredictionContext.h b/src/include/atn/PredictionContext.h deleted file mode 100755 index 23b68c30..00000000 --- a/src/include/atn/PredictionContext.h +++ /dev/null @@ -1,225 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include - -#include "Recognizer.h" -#include "atn/ATN.h" -#include "atn/ATNState.h" -#include "atn/PredictionContextType.h" - -namespace antlr4 { - - class RuleContext; - -namespace atn { - - class ATN; - class ArrayPredictionContext; - class SingletonPredictionContext; - class PredictionContextCache; - class PredictionContextMergeCache; - - class ANTLR4CPP_PUBLIC PredictionContext { - public: - /// Represents $ in local context prediction, which means wildcard. - /// *+x = *. - static const Ref EMPTY; - - /// Represents $ in an array in full context mode, when $ - /// doesn't mean wildcard: $ + x = [$,x]. Here, - /// $ = EMPTY_RETURN_STATE. - // ml: originally Integer.MAX_VALUE, which would be -1 for us, but this is already used in places where - // -1 is converted to unsigned, so we use a different value here. Any value does the job provided it doesn't - // conflict with real return states. - static constexpr size_t EMPTY_RETURN_STATE = std::numeric_limits::max() - 9; - - // dispatch - static Ref merge(Ref a, - Ref b, - bool rootIsWildcard, - PredictionContextMergeCache *mergeCache); - - /// - /// Merge two instances. - /// - ///

- /// - /// Stack tops equal, parents merge is same; return left graph.
- /// - /// - ///

- /// - /// Same stack top, parents differ; merge parents giving array node, then - /// remainders of those graphs. A new root node is created to point to the - /// merged parents.
- /// - /// - ///

- /// - /// Different stack tops pointing to same parent. Make array node for the - /// root where both element in the root point to the same (original) - /// parent.
- /// - /// - ///

- /// - /// Different stack tops pointing to different parents. Make array node for - /// the root where each element points to the corresponding original - /// parent.
- /// - ///

- /// the first - /// the second - /// {@code true} if this is a local-context merge, - /// otherwise false to indicate a full-context merge - /// - static Ref mergeSingletons(Ref a, - Ref b, - bool rootIsWildcard, - PredictionContextMergeCache *mergeCache); - - /** - * Handle case where at least one of {@code a} or {@code b} is - * {@link #EMPTY}. In the following diagrams, the symbol {@code $} is used - * to represent {@link #EMPTY}. - * - *

Local-Context Merges

- * - *

These local-context merge operations are used when {@code rootIsWildcard} - * is true.

- * - *

{@link #EMPTY} is superset of any graph; return {@link #EMPTY}.
- *

- * - *

{@link #EMPTY} and anything is {@code #EMPTY}, so merged parent is - * {@code #EMPTY}; return left graph.
- *

- * - *

Special case of last merge if local context.
- *

- * - *

Full-Context Merges

- * - *

These full-context merge operations are used when {@code rootIsWildcard} - * is false.

- * - *

- * - *

Must keep all contexts; {@link #EMPTY} in array is a special value (and - * null parent).
- *

- * - *

- * - * @param a the first {@link SingletonPredictionContext} - * @param b the second {@link SingletonPredictionContext} - * @param rootIsWildcard {@code true} if this is a local-context merge, - * otherwise false to indicate a full-context merge - */ - static Ref mergeRoot(Ref a, - Ref b, - bool rootIsWildcard); - - /** - * Merge two {@link ArrayPredictionContext} instances. - * - *

Different tops, different parents.
- *

- * - *

Shared top, same parents.
- *

- * - *

Shared top, different parents.
- *

- * - *

Shared top, all shared parents.
- *

- * - *

Equal tops, merge parents and reduce top to - * {@link SingletonPredictionContext}.
- *

- */ - static Ref mergeArrays(Ref a, - Ref b, - bool rootIsWildcard, - PredictionContextMergeCache *mergeCache); - - static std::string toDOTString(const Ref &context); - - static Ref getCachedContext(const Ref &context, - PredictionContextCache &contextCache); - - static std::vector> getAllContextNodes(const Ref &context); - - /// Convert a RuleContext tree to a PredictionContext graph. - /// Return EMPTY if outerContext is empty. - static Ref fromRuleContext(const ATN &atn, RuleContext *outerContext); - - PredictionContext(const PredictionContext&) = delete; - - virtual ~PredictionContext() = default; - - PredictionContext& operator=(const PredictionContext&) = delete; - PredictionContext& operator=(PredictionContext&&) = delete; - - PredictionContextType getContextType() const { return _contextType; } - - virtual size_t size() const = 0; - virtual const Ref& getParent(size_t index) const = 0; - virtual size_t getReturnState(size_t index) const = 0; - - /// This means only the EMPTY (wildcard? not sure) context is in set. - virtual bool isEmpty() const = 0; - bool hasEmptyPath() const; - - size_t hashCode() const; - - virtual bool equals(const PredictionContext &other) const = 0; - - virtual std::string toString() const = 0; - - std::vector toStrings(Recognizer *recognizer, int currentState) const; - std::vector toStrings(Recognizer *recognizer, - const Ref &stop, - int currentState) const; - - protected: - explicit PredictionContext(PredictionContextType contextType); - - PredictionContext(PredictionContext&& other); - - virtual size_t hashCodeImpl() const = 0; - - size_t cachedHashCode() const { return _hashCode.load(std::memory_order_relaxed); } - - private: - const PredictionContextType _contextType; - mutable std::atomic _hashCode; - }; - - inline bool operator==(const PredictionContext &lhs, const PredictionContext &rhs) { - return lhs.equals(rhs); - } - - inline bool operator!=(const PredictionContext &lhs, const PredictionContext &rhs) { - return !operator==(lhs, rhs); - } - -} // namespace atn -} // namespace antlr4 - -namespace std { - - template <> - struct hash<::antlr4::atn::PredictionContext> { - size_t operator()(const ::antlr4::atn::PredictionContext &predictionContext) const { - return predictionContext.hashCode(); - } - }; - -} // namespace std diff --git a/src/include/atn/PredictionContextCache.cpp b/src/include/atn/PredictionContextCache.cpp deleted file mode 100644 index 031a35cb..00000000 --- a/src/include/atn/PredictionContextCache.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2012-2022 The ANTLR Project -// -// 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. Neither the name of the copyright holder nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR -// CONTRIBUTORS 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 "atn/PredictionContextCache.h" - -using namespace antlr4::atn; - -void PredictionContextCache::put(const Ref &value) { - assert(value); - - _data.insert(value); -} - -Ref PredictionContextCache::get( - const Ref &value) const { - assert(value); - - auto iterator = _data.find(value); - if (iterator == _data.end()) { - return nullptr; - } - return *iterator; -} - -size_t PredictionContextCache::PredictionContextHasher::operator()( - const Ref &predictionContext) const { - return predictionContext->hashCode(); -} - -bool PredictionContextCache::PredictionContextComparer::operator()( - const Ref &lhs, - const Ref &rhs) const { - return *lhs == *rhs; -} diff --git a/src/include/atn/PredictionContextCache.h b/src/include/atn/PredictionContextCache.h deleted file mode 100644 index 78c8210d..00000000 --- a/src/include/atn/PredictionContextCache.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2012-2022 The ANTLR Project -// -// 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. Neither the name of the copyright holder nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR -// CONTRIBUTORS 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 - -#include "atn/PredictionContext.h" -#include "FlatHashSet.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC PredictionContextCache final { - public: - PredictionContextCache() = default; - - PredictionContextCache(const PredictionContextCache&) = delete; - PredictionContextCache(PredictionContextCache&&) = delete; - - PredictionContextCache& operator=(const PredictionContextCache&) = delete; - PredictionContextCache& operator=(PredictionContextCache&&) = delete; - - void put(const Ref &value); - - Ref get(const Ref &value) const; - - private: - struct ANTLR4CPP_PUBLIC PredictionContextHasher final { - size_t operator()(const Ref &predictionContext) const; - }; - - struct ANTLR4CPP_PUBLIC PredictionContextComparer final { - bool operator()(const Ref &lhs, - const Ref &rhs) const; - }; - - FlatHashSet, - PredictionContextHasher, PredictionContextComparer> _data; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PredictionContextMergeCache.cpp b/src/include/atn/PredictionContextMergeCache.cpp deleted file mode 100644 index 7160b599..00000000 --- a/src/include/atn/PredictionContextMergeCache.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2012-2022 The ANTLR Project -// -// 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. Neither the name of the copyright holder nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR -// CONTRIBUTORS 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 "atn/PredictionContextMergeCache.h" - -#include "misc/MurmurHash.h" - -using namespace antlr4::atn; -using namespace antlr4::misc; - -PredictionContextMergeCache::PredictionContextMergeCache( - const PredictionContextMergeCacheOptions &options) : _options(options) {} - -Ref PredictionContextMergeCache::put( - const Ref &key1, - const Ref &key2, - Ref value) { - assert(key1); - assert(key2); - - if (getOptions().getMaxSize() == 0) { - // Cache is effectively disabled. - return value; - } - - auto [existing, inserted] = _entries.try_emplace(std::make_pair(key1.get(), key2.get())); - if (inserted) { - try { - existing->second.reset(new Entry()); - } catch (...) { - _entries.erase(existing); - throw; - } - existing->second->key = std::make_pair(key1, key2); - existing->second->value = std::move(value); - pushToFront(existing->second.get()); - } else { - if (existing->second->value != value) { - existing->second->value = std::move(value); - } - moveToFront(existing->second.get()); - } - compact(existing->second.get()); - return existing->second->value; -} - -Ref PredictionContextMergeCache::get( - const Ref &key1, - const Ref &key2) const { - assert(key1); - assert(key2); - - if (getOptions().getMaxSize() == 0) { - // Cache is effectively disabled. - return nullptr; - } - - auto iterator = _entries.find(std::make_pair(key1.get(), key2.get())); - if (iterator == _entries.end()) { - return nullptr; - } - moveToFront(iterator->second.get()); - return iterator->second->value; -} - -void PredictionContextMergeCache::clear() { - Container().swap(_entries); - _head = _tail = nullptr; - _size = 0; -} - -void PredictionContextMergeCache::moveToFront(Entry *entry) const { - if (entry->prev == nullptr) { - assert(entry == _head); - return; - } - entry->prev->next = entry->next; - if (entry->next != nullptr) { - entry->next->prev = entry->prev; - } else { - assert(entry == _tail); - _tail = entry->prev; - } - entry->prev = nullptr; - entry->next = _head; - _head->prev = entry; - _head = entry; - assert(entry->prev == nullptr); -} - -void PredictionContextMergeCache::pushToFront(Entry *entry) { - ++_size; - entry->prev = nullptr; - entry->next = _head; - if (_head != nullptr) { - _head->prev = entry; - _head = entry; - } else { - assert(entry->next == nullptr); - _head = entry; - _tail = entry; - } - assert(entry->prev == nullptr); -} - -void PredictionContextMergeCache::remove(Entry *entry) { - if (entry->prev != nullptr) { - entry->prev->next = entry->next; - } else { - assert(entry == _head); - _head = entry->next; - } - if (entry->next != nullptr) { - entry->next->prev = entry->prev; - } else { - assert(entry == _tail); - _tail = entry->prev; - } - --_size; - _entries.erase(std::make_pair(entry->key.first.get(), entry->key.second.get())); -} - -void PredictionContextMergeCache::compact(const Entry *preserve) { - Entry *entry = _tail; - while (entry != nullptr && _size > getOptions().getMaxSize()) { - Entry *next = entry->prev; - if (entry != preserve) { - remove(entry); - } - entry = next; - } -} - -size_t PredictionContextMergeCache::PredictionContextHasher::operator()( - const PredictionContextPair &value) const { - size_t hash = MurmurHash::initialize(); - hash = MurmurHash::update(hash, value.first->hashCode()); - hash = MurmurHash::update(hash, value.second->hashCode()); - return MurmurHash::finish(hash, 2); -} - -bool PredictionContextMergeCache::PredictionContextComparer::operator()( - const PredictionContextPair &lhs, const PredictionContextPair &rhs) const { - return *lhs.first == *rhs.first && *lhs.second == *rhs.second; -} diff --git a/src/include/atn/PredictionContextMergeCache.h b/src/include/atn/PredictionContextMergeCache.h deleted file mode 100644 index efaeaef5..00000000 --- a/src/include/atn/PredictionContextMergeCache.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2012-2022 The ANTLR Project -// -// 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. Neither the name of the copyright holder nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR -// CONTRIBUTORS 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 - -#include - -#include "atn/PredictionContext.h" -#include "atn/PredictionContextMergeCacheOptions.h" -#include "FlatHashMap.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC PredictionContextMergeCache final { - public: - PredictionContextMergeCache() - : PredictionContextMergeCache(PredictionContextMergeCacheOptions()) {} - - explicit PredictionContextMergeCache(const PredictionContextMergeCacheOptions &options); - - PredictionContextMergeCache(const PredictionContextMergeCache&) = delete; - PredictionContextMergeCache(PredictionContextMergeCache&&) = delete; - - PredictionContextMergeCache& operator=(const PredictionContextMergeCache&) = delete; - PredictionContextMergeCache& operator=(PredictionContextMergeCache&&) = delete; - - Ref put(const Ref &key1, - const Ref &key2, - Ref value); - - Ref get(const Ref &key1, - const Ref &key2) const; - - const PredictionContextMergeCacheOptions& getOptions() const { return _options; } - - void clear(); - - private: - using PredictionContextPair = std::pair; - - struct ANTLR4CPP_PUBLIC PredictionContextHasher final { - size_t operator()(const PredictionContextPair &value) const; - }; - - struct ANTLR4CPP_PUBLIC PredictionContextComparer final { - bool operator()(const PredictionContextPair &lhs, const PredictionContextPair &rhs) const; - }; - - struct ANTLR4CPP_PUBLIC Entry final { - std::pair, Ref> key; - Ref value; - Entry *prev = nullptr; - Entry *next = nullptr; - }; - - void moveToFront(Entry *entry) const; - - void pushToFront(Entry *entry); - - void remove(Entry *entry); - - void compact(const Entry *preserve); - - using Container = FlatHashMap, - PredictionContextHasher, PredictionContextComparer>; - - const PredictionContextMergeCacheOptions _options; - - Container _entries; - - mutable Entry *_head = nullptr; - mutable Entry *_tail = nullptr; - - size_t _size = 0; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PredictionContextMergeCacheOptions.h b/src/include/atn/PredictionContextMergeCacheOptions.h deleted file mode 100644 index 7331cc17..00000000 --- a/src/include/atn/PredictionContextMergeCacheOptions.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2012-2022 The ANTLR Project -// -// 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. Neither the name of the copyright holder nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR -// CONTRIBUTORS 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 - -#include -#include -#include - -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC PredictionContextMergeCacheOptions final { - public: - PredictionContextMergeCacheOptions() = default; - - size_t getMaxSize() const { return _maxSize; } - - bool hasMaxSize() const { return getMaxSize() != std::numeric_limits::max(); } - - PredictionContextMergeCacheOptions& setMaxSize(size_t maxSize) { - _maxSize = maxSize; - return *this; - } - - size_t getClearEveryN() const { - return _clearEveryN; - } - - bool hasClearEveryN() const { return getClearEveryN() != 0; } - - PredictionContextMergeCacheOptions& setClearEveryN(uint64_t clearEveryN) { - _clearEveryN = clearEveryN; - return *this; - } - - PredictionContextMergeCacheOptions& neverClear() { - return setClearEveryN(0); - } - - private: - size_t _maxSize = std::numeric_limits::max(); - uint64_t _clearEveryN = 1; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PredictionContextType.h b/src/include/atn/PredictionContextType.h deleted file mode 100644 index c8c4473e..00000000 --- a/src/include/atn/PredictionContextType.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include - -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - - enum class PredictionContextType : size_t { - SINGLETON = 1, - ARRAY = 2, - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/PredictionMode.cpp b/src/include/atn/PredictionMode.cpp deleted file mode 100755 index 9db0b8bd..00000000 --- a/src/include/atn/PredictionMode.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/RuleStopState.h" -#include "atn/ATNConfigSet.h" -#include "atn/ATNConfig.h" -#include "misc/MurmurHash.h" -#include "SemanticContext.h" - -#include "PredictionMode.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlrcpp; - -struct AltAndContextConfigHasher -{ - /** - * The hash code is only a function of the {@link ATNState#stateNumber} - * and {@link ATNConfig#context}. - */ - size_t operator () (ATNConfig *o) const { - size_t hashCode = misc::MurmurHash::initialize(7); - hashCode = misc::MurmurHash::update(hashCode, o->state->stateNumber); - hashCode = misc::MurmurHash::update(hashCode, o->context); - return misc::MurmurHash::finish(hashCode, 2); - } -}; - -struct AltAndContextConfigComparer { - bool operator()(ATNConfig *a, ATNConfig *b) const - { - if (a == b) { - return true; - } - return a->state->stateNumber == b->state->stateNumber && *a->context == *b->context; - } -}; - -bool PredictionModeClass::hasSLLConflictTerminatingPrediction(PredictionMode mode, ATNConfigSet *configs) { - /* Configs in rule stop states indicate reaching the end of the decision - * rule (local context) or end of start rule (full context). If all - * configs meet this condition, then none of the configurations is able - * to match additional input so we terminate prediction. - */ - if (allConfigsInRuleStopStates(configs)) { - return true; - } - - bool heuristic; - - // Pure SLL mode parsing or SLL+LL if: - // Don't bother with combining configs from different semantic - // contexts if we can fail over to full LL; costs more time - // since we'll often fail over anyway. - if (mode == PredictionMode::SLL || !configs->hasSemanticContext) { - std::vector altsets = getConflictingAltSubsets(configs); - heuristic = hasConflictingAltSet(altsets) && !hasStateAssociatedWithOneAlt(configs); - } else { - // dup configs, tossing out semantic predicates - ATNConfigSet dup(true); - for (auto &config : configs->configs) { - Ref c = std::make_shared(*config, SemanticContext::Empty::Instance); - dup.add(c); - } - std::vector altsets = getConflictingAltSubsets(&dup); - heuristic = hasConflictingAltSet(altsets) && !hasStateAssociatedWithOneAlt(&dup); - } - - return heuristic; -} - -bool PredictionModeClass::hasConfigInRuleStopState(ATNConfigSet *configs) { - for (const auto &config : configs->configs) { - if (RuleStopState::is(config->state)) { - return true; - } - } - - return false; -} - -bool PredictionModeClass::allConfigsInRuleStopStates(ATNConfigSet *configs) { - for (const auto &config : configs->configs) { - if (!RuleStopState::is(config->state)) { - return false; - } - } - - return true; -} - -size_t PredictionModeClass::resolvesToJustOneViableAlt(const std::vector& altsets) { - return getSingleViableAlt(altsets); -} - -bool PredictionModeClass::allSubsetsConflict(const std::vector& altsets) { - return !hasNonConflictingAltSet(altsets); -} - -bool PredictionModeClass::hasNonConflictingAltSet(const std::vector& altsets) { - for (antlrcpp::BitSet alts : altsets) { - if (alts.count() == 1) { - return true; - } - } - return false; -} - -bool PredictionModeClass::hasConflictingAltSet(const std::vector& altsets) { - for (antlrcpp::BitSet alts : altsets) { - if (alts.count() > 1) { - return true; - } - } - return false; -} - -bool PredictionModeClass::allSubsetsEqual(const std::vector& altsets) { - if (altsets.empty()) { - return true; - } - - const antlrcpp::BitSet& first = *altsets.begin(); - for (const antlrcpp::BitSet& alts : altsets) { - if (alts != first) { - return false; - } - } - return true; -} - -size_t PredictionModeClass::getUniqueAlt(const std::vector& altsets) { - antlrcpp::BitSet all = getAlts(altsets); - if (all.count() == 1) { - return all.nextSetBit(0); - } - return ATN::INVALID_ALT_NUMBER; -} - -antlrcpp::BitSet PredictionModeClass::getAlts(const std::vector& altsets) { - antlrcpp::BitSet all; - for (const auto &alts : altsets) { - all |= alts; - } - - return all; -} - -antlrcpp::BitSet PredictionModeClass::getAlts(ATNConfigSet *configs) { - antlrcpp::BitSet alts; - for (const auto &config : configs->configs) { - alts.set(config->alt); - } - return alts; -} - -std::vector PredictionModeClass::getConflictingAltSubsets(ATNConfigSet *configs) { - std::unordered_map configToAlts; - for (auto &config : configs->configs) { - configToAlts[config.get()].set(config->alt); - } - std::vector values; - values.reserve(configToAlts.size()); - for (const auto &pair : configToAlts) { - values.push_back(pair.second); - } - return values; -} - -std::unordered_map PredictionModeClass::getStateToAltMap(ATNConfigSet *configs) { - std::unordered_map m; - for (const auto &c : configs->configs) { - m[c->state].set(c->alt); - } - return m; -} - -bool PredictionModeClass::hasStateAssociatedWithOneAlt(ATNConfigSet *configs) { - auto x = getStateToAltMap(configs); - for (const auto &pair : x){ - if (pair.second.count() == 1) return true; - } - return false; -} - -size_t PredictionModeClass::getSingleViableAlt(const std::vector& altsets) { - antlrcpp::BitSet viableAlts; - for (const auto &alts : altsets) { - size_t minAlt = alts.nextSetBit(0); - - viableAlts.set(minAlt); - if (viableAlts.count() > 1) // more than 1 viable alt - { - return ATN::INVALID_ALT_NUMBER; - } - } - - return viableAlts.nextSetBit(0); -} diff --git a/src/include/atn/PredictionMode.h b/src/include/atn/PredictionMode.h deleted file mode 100755 index 11d1bbe0..00000000 --- a/src/include/atn/PredictionMode.h +++ /dev/null @@ -1,436 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "support/BitSet.h" - -namespace antlr4 { -namespace atn { - - /** - * This enumeration defines the prediction modes available in ANTLR 4 along with - * utility methods for analyzing configuration sets for conflicts and/or - * ambiguities. - */ - enum class PredictionMode { - /** - * The SLL(*) prediction mode. This prediction mode ignores the current - * parser context when making predictions. This is the fastest prediction - * mode, and provides correct results for many grammars. This prediction - * mode is more powerful than the prediction mode provided by ANTLR 3, but - * may result in syntax errors for grammar and input combinations which are - * not SLL. - * - *

- * When using this prediction mode, the parser will either return a correct - * parse tree (i.e. the same parse tree that would be returned with the - * {@link #LL} prediction mode), or it will report a syntax error. If a - * syntax error is encountered when using the {@link #SLL} prediction mode, - * it may be due to either an actual syntax error in the input or indicate - * that the particular combination of grammar and input requires the more - * powerful {@link #LL} prediction abilities to complete successfully.

- * - *

- * This prediction mode does not provide any guarantees for prediction - * behavior for syntactically-incorrect inputs.

- */ - SLL, - - /** - * The LL(*) prediction mode. This prediction mode allows the current parser - * context to be used for resolving SLL conflicts that occur during - * prediction. This is the fastest prediction mode that guarantees correct - * parse results for all combinations of grammars with syntactically correct - * inputs. - * - *

- * When using this prediction mode, the parser will make correct decisions - * for all syntactically-correct grammar and input combinations. However, in - * cases where the grammar is truly ambiguous this prediction mode might not - * report a precise answer for exactly which alternatives are - * ambiguous.

- * - *

- * This prediction mode does not provide any guarantees for prediction - * behavior for syntactically-incorrect inputs.

- */ - LL, - - /** - * The LL(*) prediction mode with exact ambiguity detection. In addition to - * the correctness guarantees provided by the {@link #LL} prediction mode, - * this prediction mode instructs the prediction algorithm to determine the - * complete and exact set of ambiguous alternatives for every ambiguous - * decision encountered while parsing. - * - *

- * This prediction mode may be used for diagnosing ambiguities during - * grammar development. Due to the performance overhead of calculating sets - * of ambiguous alternatives, this prediction mode should be avoided when - * the exact results are not necessary.

- * - *

- * This prediction mode does not provide any guarantees for prediction - * behavior for syntactically-incorrect inputs.

- */ - LL_EXACT_AMBIG_DETECTION - }; - - class ANTLR4CPP_PUBLIC PredictionModeClass { - public: - /** - * Computes the SLL prediction termination condition. - * - *

- * This method computes the SLL prediction termination condition for both of - * the following cases.

- * - *
    - *
  • The usual SLL+LL fallback upon SLL conflict
  • - *
  • Pure SLL without LL fallback
  • - *
- * - *

COMBINED SLL+LL PARSING

- * - *

When LL-fallback is enabled upon SLL conflict, correct predictions are - * ensured regardless of how the termination condition is computed by this - * method. Due to the substantially higher cost of LL prediction, the - * prediction should only fall back to LL when the additional lookahead - * cannot lead to a unique SLL prediction.

- * - *

Assuming combined SLL+LL parsing, an SLL configuration set with only - * conflicting subsets should fall back to full LL, even if the - * configuration sets don't resolve to the same alternative (e.g. - * {@code {1,2}} and {@code {3,4}}. If there is at least one non-conflicting - * configuration, SLL could continue with the hopes that more lookahead will - * resolve via one of those non-conflicting configurations.

- * - *

Here's the prediction termination rule them: SLL (for SLL+LL parsing) - * stops when it sees only conflicting configuration subsets. In contrast, - * full LL keeps going when there is uncertainty.

- * - *

HEURISTIC

- * - *

As a heuristic, we stop prediction when we see any conflicting subset - * unless we see a state that only has one alternative associated with it. - * The single-alt-state thing lets prediction continue upon rules like - * (otherwise, it would admit defeat too soon):

- * - *

{@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) ';' ;}

- * - *

When the ATN simulation reaches the state before {@code ';'}, it has a - * DFA state that looks like: {@code [12|1|[], 6|2|[], 12|2|[]]}. Naturally - * {@code 12|1|[]} and {@code 12|2|[]} conflict, but we cannot stop - * processing this node because alternative to has another way to continue, - * via {@code [6|2|[]]}.

- * - *

It also let's us continue for this rule:

- * - *

{@code [1|1|[], 1|2|[], 8|3|[]] a : A | A | A B ;}

- * - *

After matching input A, we reach the stop state for rule A, state 1. - * State 8 is the state right before B. Clearly alternatives 1 and 2 - * conflict and no amount of further lookahead will separate the two. - * However, alternative 3 will be able to continue and so we do not stop - * working on this state. In the previous example, we're concerned with - * states associated with the conflicting alternatives. Here alt 3 is not - * associated with the conflicting configs, but since we can continue - * looking for input reasonably, don't declare the state done.

- * - *

PURE SLL PARSING

- * - *

To handle pure SLL parsing, all we have to do is make sure that we - * combine stack contexts for configurations that differ only by semantic - * predicate. From there, we can do the usual SLL termination heuristic.

- * - *

PREDICATES IN SLL+LL PARSING

- * - *

SLL decisions don't evaluate predicates until after they reach DFA stop - * states because they need to create the DFA cache that works in all - * semantic situations. In contrast, full LL evaluates predicates collected - * during start state computation so it can ignore predicates thereafter. - * This means that SLL termination detection can totally ignore semantic - * predicates.

- * - *

Implementation-wise, {@link ATNConfigSet} combines stack contexts but not - * semantic predicate contexts so we might see two configurations like the - * following.

- * - *

{@code (s, 1, x, {}), (s, 1, x', {p})}

- * - *

Before testing these configurations against others, we have to merge - * {@code x} and {@code x'} (without modifying the existing configurations). - * For example, we test {@code (x+x')==x''} when looking for conflicts in - * the following configurations.

- * - *

{@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x'', {})}

- * - *

If the configuration set has predicates (as indicated by - * {@link ATNConfigSet#hasSemanticContext}), this algorithm makes a copy of - * the configurations to strip out all of the predicates so that a standard - * {@link ATNConfigSet} will merge everything ignoring predicates.

- */ - static bool hasSLLConflictTerminatingPrediction(PredictionMode mode, ATNConfigSet *configs); - - /// - /// Checks if any configuration in {@code configs} is in a - /// . Configurations meeting this condition have - /// reached - /// the end of the decision rule (local context) or end of start rule (full - /// context). - /// - /// the configuration set to test - /// {@code true} if any configuration in {@code configs} is in a - /// , otherwise {@code false} - static bool hasConfigInRuleStopState(ATNConfigSet *configs); - - /// - /// Checks if all configurations in {@code configs} are in a - /// . Configurations meeting this condition have - /// reached - /// the end of the decision rule (local context) or end of start rule (full - /// context). - /// - /// the configuration set to test - /// {@code true} if all configurations in {@code configs} are in a - /// , otherwise {@code false} - static bool allConfigsInRuleStopStates(ATNConfigSet *configs); - - /** - * Full LL prediction termination. - * - *

Can we stop looking ahead during ATN simulation or is there some - * uncertainty as to which alternative we will ultimately pick, after - * consuming more input? Even if there are partial conflicts, we might know - * that everything is going to resolve to the same minimum alternative. That - * means we can stop since no more lookahead will change that fact. On the - * other hand, there might be multiple conflicts that resolve to different - * minimums. That means we need more look ahead to decide which of those - * alternatives we should predict.

- * - *

The basic idea is to split the set of configurations {@code C}, into - * conflicting subsets {@code (s, _, ctx, _)} and singleton subsets with - * non-conflicting configurations. Two configurations conflict if they have - * identical {@link ATNConfig#state} and {@link ATNConfig#context} values - * but different {@link ATNConfig#alt} value, e.g. {@code (s, i, ctx, _)} - * and {@code (s, j, ctx, _)} for {@code i!=j}.

- * - *

Reduce these configuration subsets to the set of possible alternatives. - * You can compute the alternative subsets in one pass as follows:

- * - *

{@code A_s,ctx = {i | (s, i, ctx, _)}} for each configuration in - * {@code C} holding {@code s} and {@code ctx} fixed.

- * - *

Or in pseudo-code, for each configuration {@code c} in {@code C}:

- * - *
-     * map[c] U= c.{@link ATNConfig#alt alt} # map hash/equals uses s and x, not
-     * alt and not pred
-     * 
- * - *

The values in {@code map} are the set of {@code A_s,ctx} sets.

- * - *

If {@code |A_s,ctx|=1} then there is no conflict associated with - * {@code s} and {@code ctx}.

- * - *

Reduce the subsets to singletons by choosing a minimum of each subset. If - * the union of these alternative subsets is a singleton, then no amount of - * more lookahead will help us. We will always pick that alternative. If, - * however, there is more than one alternative, then we are uncertain which - * alternative to predict and must continue looking for resolution. We may - * or may not discover an ambiguity in the future, even if there are no - * conflicting subsets this round.

- * - *

The biggest sin is to terminate early because it means we've made a - * decision but were uncertain as to the eventual outcome. We haven't used - * enough lookahead. On the other hand, announcing a conflict too late is no - * big deal; you will still have the conflict. It's just inefficient. It - * might even look until the end of file.

- * - *

No special consideration for semantic predicates is required because - * predicates are evaluated on-the-fly for full LL prediction, ensuring that - * no configuration contains a semantic context during the termination - * check.

- * - *

CONFLICTING CONFIGS

- * - *

Two configurations {@code (s, i, x)} and {@code (s, j, x')}, conflict - * when {@code i!=j} but {@code x=x'}. Because we merge all - * {@code (s, i, _)} configurations together, that means that there are at - * most {@code n} configurations associated with state {@code s} for - * {@code n} possible alternatives in the decision. The merged stacks - * complicate the comparison of configuration contexts {@code x} and - * {@code x'}. Sam checks to see if one is a subset of the other by calling - * merge and checking to see if the merged result is either {@code x} or - * {@code x'}. If the {@code x} associated with lowest alternative {@code i} - * is the superset, then {@code i} is the only possible prediction since the - * others resolve to {@code min(i)} as well. However, if {@code x} is - * associated with {@code j>i} then at least one stack configuration for - * {@code j} is not in conflict with alternative {@code i}. The algorithm - * should keep going, looking for more lookahead due to the uncertainty.

- * - *

For simplicity, I'm doing a equality check between {@code x} and - * {@code x'} that lets the algorithm continue to consume lookahead longer - * than necessary. The reason I like the equality is of course the - * simplicity but also because that is the test you need to detect the - * alternatives that are actually in conflict.

- * - *

CONTINUE/STOP RULE

- * - *

Continue if union of resolved alternative sets from non-conflicting and - * conflicting alternative subsets has more than one alternative. We are - * uncertain about which alternative to predict.

- * - *

The complete set of alternatives, {@code [i for (_,i,_)]}, tells us which - * alternatives are still in the running for the amount of input we've - * consumed at this point. The conflicting sets let us to strip away - * configurations that won't lead to more states because we resolve - * conflicts to the configuration with a minimum alternate for the - * conflicting set.

- * - *

CASES

- * - *
    - * - *
  • no conflicts and more than 1 alternative in set => continue
  • - * - *
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s, 3, z)}, - * {@code (s', 1, y)}, {@code (s', 2, y)} yields non-conflicting set - * {@code {3}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} = - * {@code {1,3}} => continue - *
  • - * - *
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)}, - * {@code (s', 2, y)}, {@code (s'', 1, z)} yields non-conflicting set - * {@code {1}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} = - * {@code {1}} => stop and predict 1
  • - * - *
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)}, - * {@code (s', 2, y)} yields conflicting, reduced sets {@code {1}} U - * {@code {1}} = {@code {1}} => stop and predict 1, can announce - * ambiguity {@code {1,2}}
  • - * - *
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 2, y)}, - * {@code (s', 3, y)} yields conflicting, reduced sets {@code {1}} U - * {@code {2}} = {@code {1,2}} => continue
  • - * - *
  • {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 3, y)}, - * {@code (s', 4, y)} yields conflicting, reduced sets {@code {1}} U - * {@code {3}} = {@code {1,3}} => continue
  • - * - *
- * - *

EXACT AMBIGUITY DETECTION

- * - *

If all states report the same conflicting set of alternatives, then we - * know we have the exact ambiguity set.

- * - *

|A_i|>1 and - * A_i = A_j for all i, j.

- * - *

In other words, we continue examining lookahead until all {@code A_i} - * have more than one alternative and all {@code A_i} are the same. If - * {@code A={{1,2}, {1,3}}}, then regular LL prediction would terminate - * because the resolved set is {@code {1}}. To determine what the real - * ambiguity is, we have to know whether the ambiguity is between one and - * two or one and three so we keep going. We can only stop prediction when - * we need exact ambiguity detection when the sets look like - * {@code A={{1,2}}} or {@code {{1,2},{1,2}}}, etc...

- */ - static size_t resolvesToJustOneViableAlt(const std::vector &altsets); - - /// - /// Determines if every alternative subset in {@code altsets} contains more - /// than one alternative. - /// - /// a collection of alternative subsets - /// {@code true} if every in {@code altsets} - /// has - /// > 1, otherwise {@code - /// false} - static bool allSubsetsConflict(const std::vector &altsets); - - /// - /// Determines if any single alternative subset in {@code altsets} contains - /// exactly one alternative. - /// - /// a collection of alternative subsets - /// {@code true} if {@code altsets} contains a with - /// 1, otherwise {@code false} - /// - static bool hasNonConflictingAltSet(const std::vector &altsets); - - /// - /// Determines if any single alternative subset in {@code altsets} contains - /// more than one alternative. - /// - /// a collection of alternative subsets - /// {@code true} if {@code altsets} contains a with - /// > 1, otherwise {@code - /// false} - static bool hasConflictingAltSet(const std::vector &altsets); - - /// - /// Determines if every alternative subset in {@code altsets} is equivalent. - /// - /// a collection of alternative subsets - /// {@code true} if every member of {@code altsets} is equal to the - /// others, otherwise {@code false} - static bool allSubsetsEqual(const std::vector &altsets); - - /// - /// Returns the unique alternative predicted by all alternative subsets in - /// {@code altsets}. If no such alternative exists, this method returns - /// . - /// - /// a collection of alternative subsets - static size_t getUniqueAlt(const std::vector &altsets); - - /// - /// Gets the complete set of represented alternatives for a collection of - /// alternative subsets. This method returns the union of each - /// in {@code altsets}. - /// - /// a collection of alternative subsets - /// the set of represented alternatives in {@code altsets} - static antlrcpp::BitSet getAlts(const std::vector &altsets); - - /** Get union of all alts from configs. @since 4.5.1 */ - static antlrcpp::BitSet getAlts(ATNConfigSet *configs); - - /// - /// This function gets the conflicting alt subsets from a configuration set. - /// For each configuration {@code c} in {@code configs}: - /// - ///
-    /// map[c] U= c. # map hash/equals uses s and
-    /// x, not
-    /// alt and not pred
-    /// 
- ///
- static std::vector getConflictingAltSubsets(ATNConfigSet *configs); - - /// - /// Get a map from state to alt subset from a configuration set. For each - /// configuration {@code c} in {@code configs}: - /// - ///
-    /// map[c.] U= c.
-    /// 
- ///
- static std::unordered_map getStateToAltMap(ATNConfigSet *configs); - - static bool hasStateAssociatedWithOneAlt(ATNConfigSet *configs); - - static size_t getSingleViableAlt(const std::vector &altsets); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/ProfilingATNSimulator.cpp b/src/include/atn/ProfilingATNSimulator.cpp deleted file mode 100755 index 9fd86d67..00000000 --- a/src/include/atn/ProfilingATNSimulator.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/PredicateEvalInfo.h" -#include "atn/LookaheadEventInfo.h" -#include "Parser.h" -#include "atn/ATNConfigSet.h" -#include "support/CPPUtils.h" - -#include "atn/ProfilingATNSimulator.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlr4::dfa; -using namespace antlrcpp; - -using namespace std::chrono; - -ProfilingATNSimulator::ProfilingATNSimulator(Parser *parser) - : ParserATNSimulator(parser, parser->getInterpreter()->atn, - parser->getInterpreter()->decisionToDFA, - parser->getInterpreter()->getSharedContextCache()) { - for (size_t i = 0; i < atn.decisionToState.size(); i++) { - _decisions.push_back(DecisionInfo(i)); - } -} - -size_t ProfilingATNSimulator::adaptivePredict(TokenStream *input, size_t decision, ParserRuleContext *outerContext) { - auto onExit = finally([this](){ - _currentDecision = 0; // Originally -1, but that makes no sense (index into a vector and init value is also 0). - }); - - _sllStopIndex = -1; - _llStopIndex = -1; - _currentDecision = decision; - high_resolution_clock::time_point start = high_resolution_clock::now(); - size_t alt = ParserATNSimulator::adaptivePredict(input, decision, outerContext); - high_resolution_clock::time_point stop = high_resolution_clock::now(); - _decisions[decision].timeInPrediction += duration_cast(stop - start).count(); - _decisions[decision].invocations++; - - long long SLL_k = _sllStopIndex - _startIndex + 1; - _decisions[decision].SLL_TotalLook += SLL_k; - _decisions[decision].SLL_MinLook = _decisions[decision].SLL_MinLook == 0 ? SLL_k : std::min(_decisions[decision].SLL_MinLook, SLL_k); - if (SLL_k > _decisions[decision].SLL_MaxLook) { - _decisions[decision].SLL_MaxLook = SLL_k; - _decisions[decision].SLL_MaxLookEvent = std::make_shared(decision, nullptr, alt, input, _startIndex, _sllStopIndex, false); - } - - if (_llStopIndex >= 0) { - long long LL_k = _llStopIndex - _startIndex + 1; - _decisions[decision].LL_TotalLook += LL_k; - _decisions[decision].LL_MinLook = _decisions[decision].LL_MinLook == 0 ? LL_k : std::min(_decisions[decision].LL_MinLook, LL_k); - if (LL_k > _decisions[decision].LL_MaxLook) { - _decisions[decision].LL_MaxLook = LL_k; - _decisions[decision].LL_MaxLookEvent = std::make_shared(decision, nullptr, alt, input, _startIndex, _llStopIndex, true); - } - } - - return alt; -} - -DFAState* ProfilingATNSimulator::getExistingTargetState(DFAState *previousD, size_t t) { - // this method is called after each time the input position advances - // during SLL prediction - _sllStopIndex = (int)_input->index(); - - DFAState *existingTargetState = ParserATNSimulator::getExistingTargetState(previousD, t); - if (existingTargetState != nullptr) { - _decisions[_currentDecision].SLL_DFATransitions++; // count only if we transition over a DFA state - if (existingTargetState == ERROR.get()) { - _decisions[_currentDecision].errors.push_back( - ErrorInfo(_currentDecision, previousD->configs.get(), _input, _startIndex, _sllStopIndex, false) - ); - } - } - - _currentState = existingTargetState; - return existingTargetState; -} - -DFAState* ProfilingATNSimulator::computeTargetState(DFA &dfa, DFAState *previousD, size_t t) { - DFAState *state = ParserATNSimulator::computeTargetState(dfa, previousD, t); - _currentState = state; - return state; -} - -std::unique_ptr ProfilingATNSimulator::computeReachSet(ATNConfigSet *closure, size_t t, bool fullCtx) { - if (fullCtx) { - // this method is called after each time the input position advances - // during full context prediction - _llStopIndex = (int)_input->index(); - } - - std::unique_ptr reachConfigs = ParserATNSimulator::computeReachSet(closure, t, fullCtx); - if (fullCtx) { - _decisions[_currentDecision].LL_ATNTransitions++; // count computation even if error - if (reachConfigs != nullptr) { - } else { // no reach on current lookahead symbol. ERROR. - // TODO: does not handle delayed errors per getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule() - _decisions[_currentDecision].errors.push_back(ErrorInfo(_currentDecision, closure, _input, _startIndex, _llStopIndex, true)); - } - } else { - ++_decisions[_currentDecision].SLL_ATNTransitions; - if (reachConfigs != nullptr) { - } else { // no reach on current lookahead symbol. ERROR. - _decisions[_currentDecision].errors.push_back(ErrorInfo(_currentDecision, closure, _input, _startIndex, _sllStopIndex, false)); - } - } - return reachConfigs; -} - -bool ProfilingATNSimulator::evalSemanticContext(Ref const& pred, ParserRuleContext *parserCallStack, - size_t alt, bool fullCtx) { - bool result = ParserATNSimulator::evalSemanticContext(pred, parserCallStack, alt, fullCtx); - if (!(std::dynamic_pointer_cast(pred) != nullptr)) { - bool fullContext = _llStopIndex >= 0; - int stopIndex = fullContext ? _llStopIndex : _sllStopIndex; - _decisions[_currentDecision].predicateEvals.push_back( - PredicateEvalInfo(_currentDecision, _input, _startIndex, stopIndex, pred, result, alt, fullCtx)); - } - - return result; -} - -void ProfilingATNSimulator::reportAttemptingFullContext(DFA &dfa, const BitSet &conflictingAlts, ATNConfigSet *configs, - size_t startIndex, size_t stopIndex) { - if (conflictingAlts.count() > 0) { - conflictingAltResolvedBySLL = conflictingAlts.nextSetBit(0); - } else { - conflictingAltResolvedBySLL = configs->getAlts().nextSetBit(0); - } - _decisions[_currentDecision].LL_Fallback++; - ParserATNSimulator::reportAttemptingFullContext(dfa, conflictingAlts, configs, startIndex, stopIndex); -} - -void ProfilingATNSimulator::reportContextSensitivity(DFA &dfa, size_t prediction, ATNConfigSet *configs, - size_t startIndex, size_t stopIndex) { - if (prediction != conflictingAltResolvedBySLL) { - _decisions[_currentDecision].contextSensitivities.push_back( - ContextSensitivityInfo(_currentDecision, configs, _input, startIndex, stopIndex) - ); - } - ParserATNSimulator::reportContextSensitivity(dfa, prediction, configs, startIndex, stopIndex); -} - -void ProfilingATNSimulator::reportAmbiguity(DFA &dfa, DFAState *D, size_t startIndex, size_t stopIndex, bool exact, - const BitSet &ambigAlts, ATNConfigSet *configs) { - size_t prediction; - if (ambigAlts.count() > 0) { - prediction = ambigAlts.nextSetBit(0); - } else { - prediction = configs->getAlts().nextSetBit(0); - } - if (configs->fullCtx && prediction != conflictingAltResolvedBySLL) { - // Even though this is an ambiguity we are reporting, we can - // still detect some context sensitivities. Both SLL and LL - // are showing a conflict, hence an ambiguity, but if they resolve - // to different minimum alternatives we have also identified a - // context sensitivity. - _decisions[_currentDecision].contextSensitivities.push_back( - ContextSensitivityInfo(_currentDecision, configs, _input, startIndex, stopIndex) - ); - } - _decisions[_currentDecision].ambiguities.push_back( - AmbiguityInfo(_currentDecision, configs, ambigAlts, _input, startIndex, stopIndex, configs->fullCtx) - ); - ParserATNSimulator::reportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configs); -} - -std::vector ProfilingATNSimulator::getDecisionInfo() const { - return _decisions; -} - -DFAState* ProfilingATNSimulator::getCurrentState() const { - return _currentState; -} diff --git a/src/include/atn/ProfilingATNSimulator.h b/src/include/atn/ProfilingATNSimulator.h deleted file mode 100755 index 551efb85..00000000 --- a/src/include/atn/ProfilingATNSimulator.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ParserATNSimulator.h" -#include "atn/DecisionInfo.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC ProfilingATNSimulator : public ParserATNSimulator { - public: - explicit ProfilingATNSimulator(Parser *parser); - - virtual size_t adaptivePredict(TokenStream *input, size_t decision, ParserRuleContext *outerContext) override; - - virtual std::vector getDecisionInfo() const; - virtual dfa::DFAState* getCurrentState() const; - - protected: - std::vector _decisions; - - int _sllStopIndex = 0; - int _llStopIndex = 0; - - size_t _currentDecision = 0; - dfa::DFAState *_currentState; - - /// - /// At the point of LL failover, we record how SLL would resolve the conflict so that - /// we can determine whether or not a decision / input pair is context-sensitive. - /// If LL gives a different result than SLL's predicted alternative, we have a - /// context sensitivity for sure. The converse is not necessarily true, however. - /// It's possible that after conflict resolution chooses minimum alternatives, - /// SLL could get the same answer as LL. Regardless of whether or not the result indicates - /// an ambiguity, it is not treated as a context sensitivity because LL prediction - /// was not required in order to produce a correct prediction for this decision and input sequence. - /// It may in fact still be a context sensitivity but we don't know by looking at the - /// minimum alternatives for the current input. - /// - size_t conflictingAltResolvedBySLL = 0; - - virtual dfa::DFAState* getExistingTargetState(dfa::DFAState *previousD, size_t t) override; - virtual dfa::DFAState* computeTargetState(dfa::DFA &dfa, dfa::DFAState *previousD, size_t t) override; - virtual std::unique_ptr computeReachSet(ATNConfigSet *closure, size_t t, bool fullCtx) override; - virtual bool evalSemanticContext(Ref const& pred, ParserRuleContext *parserCallStack, - size_t alt, bool fullCtx) override; - virtual void reportAttemptingFullContext(dfa::DFA &dfa, const antlrcpp::BitSet &conflictingAlts, ATNConfigSet *configs, - size_t startIndex, size_t stopIndex) override; - virtual void reportContextSensitivity(dfa::DFA &dfa, size_t prediction, ATNConfigSet *configs, - size_t startIndex, size_t stopIndex) override; - virtual void reportAmbiguity(dfa::DFA &dfa, dfa::DFAState *D, size_t startIndex, size_t stopIndex, bool exact, - const antlrcpp::BitSet &ambigAlts, ATNConfigSet *configs) override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/RangeTransition.cpp b/src/include/atn/RangeTransition.cpp deleted file mode 100755 index 101a3bb0..00000000 --- a/src/include/atn/RangeTransition.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/IntervalSet.h" - -#include "atn/RangeTransition.h" - -using namespace antlr4; -using namespace antlr4::atn; - -RangeTransition::RangeTransition(ATNState *target, size_t from, size_t to) : Transition(TransitionType::RANGE, target), from(from), to(to) { -} - -misc::IntervalSet RangeTransition::label() const { - return misc::IntervalSet::of((int)from, (int)to); -} - -bool RangeTransition::matches(size_t symbol, size_t /*minVocabSymbol*/, size_t /*maxVocabSymbol*/) const { - return symbol >= from && symbol <= to; -} - -std::string RangeTransition::toString() const { - return "RANGE " + Transition::toString() + " { from: " + std::to_string(from) + ", to: " + std::to_string(to) + " }"; -} diff --git a/src/include/atn/RangeTransition.h b/src/include/atn/RangeTransition.h deleted file mode 100755 index 721b712d..00000000 --- a/src/include/atn/RangeTransition.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/Transition.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC RangeTransition final : public Transition { - public: - static bool is(const Transition &transition) { return transition.getTransitionType() == TransitionType::RANGE; } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - const size_t from; - const size_t to; - - RangeTransition(ATNState *target, size_t from, size_t to); - - virtual misc::IntervalSet label() const override; - virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - - virtual std::string toString() const override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/RuleStartState.h b/src/include/atn/RuleStartState.h deleted file mode 100755 index 0d396dfc..00000000 --- a/src/include/atn/RuleStartState.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNState.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC RuleStartState final : public ATNState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::RULE_START; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - RuleStopState *stopState = nullptr; - bool isLeftRecursiveRule = false; - - RuleStartState() : ATNState(ATNStateType::RULE_START) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/RuleStopState.h b/src/include/atn/RuleStopState.h deleted file mode 100755 index e5f4dc4c..00000000 --- a/src/include/atn/RuleStopState.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNState.h" - -namespace antlr4 { -namespace atn { - - /// The last node in the ATN for a rule, unless that rule is the start symbol. - /// In that case, there is one transition to EOF. Later, we might encode - /// references to all calls to this rule to compute FOLLOW sets for - /// error handling. - class ANTLR4CPP_PUBLIC RuleStopState final : public ATNState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::RULE_STOP; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - RuleStopState() : ATNState(ATNStateType::RULE_STOP) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/RuleTransition.cpp b/src/include/atn/RuleTransition.cpp deleted file mode 100755 index f2f7f707..00000000 --- a/src/include/atn/RuleTransition.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/RuleStartState.h" -#include "atn/RuleTransition.h" - -using namespace antlr4::atn; - -RuleTransition::RuleTransition(RuleStartState *ruleStart, size_t ruleIndex, ATNState *followState) - : RuleTransition(ruleStart, ruleIndex, 0, followState) { -} - -RuleTransition::RuleTransition(RuleStartState *ruleStart, size_t ruleIndex, int precedence, ATNState *followState) - : Transition(TransitionType::RULE, ruleStart), ruleIndex(ruleIndex), precedence(precedence) { - this->followState = followState; -} - -bool RuleTransition::isEpsilon() const { - return true; -} - -bool RuleTransition::matches(size_t /*symbol*/, size_t /*minVocabSymbol*/, size_t /*maxVocabSymbol*/) const { - return false; -} - -std::string RuleTransition::toString() const { - std::stringstream ss; - ss << "RULE " << Transition::toString() << " { ruleIndex: " << ruleIndex << ", precedence: " << precedence << - ", followState: " << std::hex << followState << " }"; - return ss.str(); -} diff --git a/src/include/atn/RuleTransition.h b/src/include/atn/RuleTransition.h deleted file mode 100755 index 943152d0..00000000 --- a/src/include/atn/RuleTransition.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/Transition.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC RuleTransition final : public Transition { - public: - static bool is(const Transition &transition) { return transition.getTransitionType() == TransitionType::RULE; } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - /// Ptr to the rule definition object for this rule ref. - const size_t ruleIndex; // no Rule object at runtime - - const int precedence; - - /// What node to begin computations following ref to rule. - ATNState *followState; - - /// @deprecated Use - /// instead. - RuleTransition(RuleStartState *ruleStart, size_t ruleIndex, ATNState *followState); - - RuleTransition(RuleStartState *ruleStart, size_t ruleIndex, int precedence, ATNState *followState); - RuleTransition(RuleTransition const&) = delete; - RuleTransition& operator=(RuleTransition const&) = delete; - - virtual bool isEpsilon() const override; - virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - - virtual std::string toString() const override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/SemanticContext.cpp b/src/include/atn/SemanticContext.cpp deleted file mode 100755 index 7d7fe068..00000000 --- a/src/include/atn/SemanticContext.cpp +++ /dev/null @@ -1,418 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include -#include - -#include "misc/MurmurHash.h" -#include "support/Casts.h" -#include "support/CPPUtils.h" -#include "support/Arrays.h" - -#include "SemanticContext.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlrcpp; - -namespace { - - struct SemanticContextHasher final { - size_t operator()(const SemanticContext *semanticContext) const { - return semanticContext->hashCode(); - } - }; - - struct SemanticContextComparer final { - bool operator()(const SemanticContext *lhs, const SemanticContext *rhs) const { - return *lhs == *rhs; - } - }; - - template - void insertSemanticContext(const Ref &semanticContext, - std::unordered_set &operandSet, - std::vector> &operandList, - Ref &precedencePredicate, - Comparer comparer) { - if (semanticContext != nullptr) { - if (semanticContext->getContextType() == SemanticContextType::PRECEDENCE) { - if (precedencePredicate == nullptr || comparer(downCast(semanticContext.get())->precedence, precedencePredicate->precedence)) { - precedencePredicate = std::static_pointer_cast(semanticContext); - } - } else { - auto [existing, inserted] = operandSet.insert(semanticContext.get()); - if (inserted) { - operandList.push_back(semanticContext); - } - } - } - } - - template - void insertSemanticContext(Ref &&semanticContext, - std::unordered_set &operandSet, - std::vector> &operandList, - Ref &precedencePredicate, - Comparer comparer) { - if (semanticContext != nullptr) { - if (semanticContext->getContextType() == SemanticContextType::PRECEDENCE) { - if (precedencePredicate == nullptr || comparer(downCast(semanticContext.get())->precedence, precedencePredicate->precedence)) { - precedencePredicate = std::static_pointer_cast(std::move(semanticContext)); - } - } else { - auto [existing, inserted] = operandSet.insert(semanticContext.get()); - if (inserted) { - operandList.push_back(std::move(semanticContext)); - } - } - } - } - - size_t predictOperandCapacity(const Ref &x) { - switch (x->getContextType()) { - case SemanticContextType::AND: - return downCast(*x).getOperands().size(); - case SemanticContextType::OR: - return downCast(*x).getOperands().size(); - default: - return 1; - } - } - - size_t predictOperandCapacity(const Ref &a, const Ref &b) { - return predictOperandCapacity(a) + predictOperandCapacity(b); - } - -} - -//------------------ Predicate ----------------------------------------------------------------------------------------- - -SemanticContext::Predicate::Predicate(size_t ruleIndex, size_t predIndex, bool isCtxDependent) - : SemanticContext(SemanticContextType::PREDICATE), ruleIndex(ruleIndex), predIndex(predIndex), isCtxDependent(isCtxDependent) {} - -bool SemanticContext::Predicate::eval(Recognizer *parser, RuleContext *parserCallStack) const { - RuleContext *localctx = nullptr; - if (isCtxDependent) { - localctx = parserCallStack; - } - return parser->sempred(localctx, ruleIndex, predIndex); -} - -size_t SemanticContext::Predicate::hashCode() const { - size_t hashCode = misc::MurmurHash::initialize(); - hashCode = misc::MurmurHash::update(hashCode, static_cast(getContextType())); - hashCode = misc::MurmurHash::update(hashCode, ruleIndex); - hashCode = misc::MurmurHash::update(hashCode, predIndex); - hashCode = misc::MurmurHash::update(hashCode, isCtxDependent ? 1 : 0); - hashCode = misc::MurmurHash::finish(hashCode, 4); - return hashCode; -} - -bool SemanticContext::Predicate::equals(const SemanticContext &other) const { - if (this == &other) { - return true; - } - if (getContextType() != other.getContextType()) { - return false; - } - const Predicate &p = downCast(other); - return ruleIndex == p.ruleIndex && predIndex == p.predIndex && isCtxDependent == p.isCtxDependent; -} - -std::string SemanticContext::Predicate::toString() const { - return std::string("{") + std::to_string(ruleIndex) + std::string(":") + std::to_string(predIndex) + std::string("}?"); -} - -//------------------ PrecedencePredicate ------------------------------------------------------------------------------- - -SemanticContext::PrecedencePredicate::PrecedencePredicate(int precedence) : SemanticContext(SemanticContextType::PRECEDENCE), precedence(precedence) {} - -bool SemanticContext::PrecedencePredicate::eval(Recognizer *parser, RuleContext *parserCallStack) const { - return parser->precpred(parserCallStack, precedence); -} - -Ref SemanticContext::PrecedencePredicate::evalPrecedence(Recognizer *parser, - RuleContext *parserCallStack) const { - if (parser->precpred(parserCallStack, precedence)) { - return SemanticContext::Empty::Instance; - } - return nullptr; -} - -size_t SemanticContext::PrecedencePredicate::hashCode() const { - size_t hashCode = misc::MurmurHash::initialize(); - hashCode = misc::MurmurHash::update(hashCode, static_cast(getContextType())); - hashCode = misc::MurmurHash::update(hashCode, static_cast(precedence)); - return misc::MurmurHash::finish(hashCode, 2); -} - -bool SemanticContext::PrecedencePredicate::equals(const SemanticContext &other) const { - if (this == &other) { - return true; - } - if (getContextType() != other.getContextType()) { - return false; - } - const PrecedencePredicate &predicate = downCast(other); - return precedence == predicate.precedence; -} - -std::string SemanticContext::PrecedencePredicate::toString() const { - return "{" + std::to_string(precedence) + ">=prec}?"; -} - -//------------------ AND ----------------------------------------------------------------------------------------------- - -SemanticContext::AND::AND(Ref a, Ref b) : Operator(SemanticContextType::AND) { - std::unordered_set operands; - Ref precedencePredicate; - - _opnds.reserve(predictOperandCapacity(a, b) + 1); - - if (a->getContextType() == SemanticContextType::AND) { - for (const auto &operand : downCast(a.get())->getOperands()) { - insertSemanticContext(operand, operands, _opnds, precedencePredicate, std::less{}); - } - } else { - insertSemanticContext(std::move(a), operands, _opnds, precedencePredicate, std::less{}); - } - - if (b->getContextType() == SemanticContextType::AND) { - for (const auto &operand : downCast(b.get())->getOperands()) { - insertSemanticContext(operand, operands, _opnds, precedencePredicate, std::less{}); - } - } else { - insertSemanticContext(std::move(b), operands, _opnds, precedencePredicate, std::less{}); - } - - if (precedencePredicate != nullptr) { - // interested in the transition with the lowest precedence - auto [existing, inserted] = operands.insert(precedencePredicate.get()); - if (inserted) { - _opnds.push_back(std::move(precedencePredicate)); - } - } -} - -const std::vector>& SemanticContext::AND::getOperands() const { - return _opnds; -} - -bool SemanticContext::AND::equals(const SemanticContext &other) const { - if (this == &other) { - return true; - } - if (getContextType() != other.getContextType()) { - return false; - } - const AND &context = downCast(other); - return Arrays::equals(getOperands(), context.getOperands()); -} - -size_t SemanticContext::AND::hashCode() const { - size_t hash = misc::MurmurHash::initialize(); - hash = misc::MurmurHash::update(hash, static_cast(getContextType())); - return misc::MurmurHash::hashCode(getOperands(), hash); -} - -bool SemanticContext::AND::eval(Recognizer *parser, RuleContext *parserCallStack) const { - for (const auto &opnd : getOperands()) { - if (!opnd->eval(parser, parserCallStack)) { - return false; - } - } - return true; -} - -Ref SemanticContext::AND::evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const { - bool differs = false; - std::vector> operands; - for (const auto &context : getOperands()) { - auto evaluated = context->evalPrecedence(parser, parserCallStack); - differs |= (evaluated != context); - if (evaluated == nullptr) { - // The AND context is false if any element is false. - return nullptr; - } - if (evaluated != Empty::Instance) { - // Reduce the result by skipping true elements. - operands.push_back(std::move(evaluated)); - } - } - - if (!differs) { - return shared_from_this(); - } - - if (operands.empty()) { - // All elements were true, so the AND context is true. - return Empty::Instance; - } - - Ref result = std::move(operands[0]); - for (size_t i = 1; i < operands.size(); ++i) { - result = SemanticContext::And(std::move(result), std::move(operands[i])); - } - - return result; -} - -std::string SemanticContext::AND::toString() const { - std::string tmp; - for (const auto &var : getOperands()) { - tmp += var->toString() + " && "; - } - return tmp; -} - -//------------------ OR ------------------------------------------------------------------------------------------------ - -SemanticContext::OR::OR(Ref a, Ref b) : Operator(SemanticContextType::OR) { - std::unordered_set operands; - Ref precedencePredicate; - - _opnds.reserve(predictOperandCapacity(a, b) + 1); - - if (a->getContextType() == SemanticContextType::OR) { - for (const auto &operand : downCast(a.get())->getOperands()) { - insertSemanticContext(operand, operands, _opnds, precedencePredicate, std::greater{}); - } - } else { - insertSemanticContext(std::move(a), operands, _opnds, precedencePredicate, std::greater{}); - } - - if (b->getContextType() == SemanticContextType::OR) { - for (const auto &operand : downCast(b.get())->getOperands()) { - insertSemanticContext(operand, operands, _opnds, precedencePredicate, std::greater{}); - } - } else { - insertSemanticContext(std::move(b), operands, _opnds, precedencePredicate, std::greater{}); - } - - if (precedencePredicate != nullptr) { - // interested in the transition with the highest precedence - auto [existing, inserted] = operands.insert(precedencePredicate.get()); - if (inserted) { - _opnds.push_back(std::move(precedencePredicate)); - } - } -} - -const std::vector>& SemanticContext::OR::getOperands() const { - return _opnds; -} - -bool SemanticContext::OR::equals(const SemanticContext &other) const { - if (this == &other) { - return true; - } - if (getContextType() != other.getContextType()) { - return false; - } - const OR &context = downCast(other); - return Arrays::equals(getOperands(), context.getOperands()); -} - -size_t SemanticContext::OR::hashCode() const { - size_t hash = misc::MurmurHash::initialize(); - hash = misc::MurmurHash::update(hash, static_cast(getContextType())); - return misc::MurmurHash::hashCode(getOperands(), hash); -} - -bool SemanticContext::OR::eval(Recognizer *parser, RuleContext *parserCallStack) const { - for (const auto &opnd : getOperands()) { - if (opnd->eval(parser, parserCallStack)) { - return true; - } - } - return false; -} - -Ref SemanticContext::OR::evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const { - bool differs = false; - std::vector> operands; - for (const auto &context : getOperands()) { - auto evaluated = context->evalPrecedence(parser, parserCallStack); - differs |= (evaluated != context); - if (evaluated == Empty::Instance) { - // The OR context is true if any element is true. - return Empty::Instance; - } - if (evaluated != nullptr) { - // Reduce the result by skipping false elements. - operands.push_back(std::move(evaluated)); - } - } - - if (!differs) { - return shared_from_this(); - } - - if (operands.empty()) { - // All elements were false, so the OR context is false. - return nullptr; - } - - Ref result = std::move(operands[0]); - for (size_t i = 1; i < operands.size(); ++i) { - result = SemanticContext::Or(std::move(result), std::move(operands[i])); - } - - return result; -} - -std::string SemanticContext::OR::toString() const { - std::string tmp; - for(const auto &var : getOperands()) { - tmp += var->toString() + " || "; - } - return tmp; -} - -//------------------ SemanticContext ----------------------------------------------------------------------------------- - -const Ref SemanticContext::Empty::Instance = std::make_shared(INVALID_INDEX, INVALID_INDEX, false); - -Ref SemanticContext::evalPrecedence(Recognizer * /*parser*/, RuleContext * /*parserCallStack*/) const { - return shared_from_this(); -} - -Ref SemanticContext::And(Ref a, Ref b) { - if (!a || a == Empty::Instance) { - return b; - } - - if (!b || b == Empty::Instance) { - return a; - } - - Ref result = std::make_shared(std::move(a), std::move(b)); - if (result->getOperands().size() == 1) { - return result->getOperands()[0]; - } - - return result; -} - -Ref SemanticContext::Or(Ref a, Ref b) { - if (!a) { - return b; - } - if (!b) { - return a; - } - - if (a == Empty::Instance || b == Empty::Instance) { - return Empty::Instance; - } - - Ref result = std::make_shared(std::move(a), std::move(b)); - if (result->getOperands().size() == 1) { - return result->getOperands()[0]; - } - - return result; -} diff --git a/src/include/atn/SemanticContext.h b/src/include/atn/SemanticContext.h deleted file mode 100755 index 8116fc0b..00000000 --- a/src/include/atn/SemanticContext.h +++ /dev/null @@ -1,237 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "Recognizer.h" -#include "support/CPPUtils.h" -#include "atn/SemanticContextType.h" - -namespace antlr4 { -namespace atn { - - /// A tree structure used to record the semantic context in which - /// an ATN configuration is valid. It's either a single predicate, - /// a conjunction "p1 && p2", or a sum of products "p1||p2". - /// - /// I have scoped the AND, OR, and Predicate subclasses of - /// SemanticContext within the scope of this outer class. - class ANTLR4CPP_PUBLIC SemanticContext : public std::enable_shared_from_this { - public: - virtual ~SemanticContext() = default; - - SemanticContextType getContextType() const { return _contextType; } - - /// - /// For context independent predicates, we evaluate them without a local - /// context (i.e., null context). That way, we can evaluate them without - /// having to create proper rule-specific context during prediction (as - /// opposed to the parser, which creates them naturally). In a practical - /// sense, this avoids a cast exception from RuleContext to myruleContext. - ///

- /// For context dependent predicates, we must pass in a local context so that - /// references such as $arg evaluate properly as _localctx.arg. We only - /// capture context dependent predicates in the context in which we begin - /// prediction, so we passed in the outer context here in case of context - /// dependent predicate evaluation. - ///

- virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) const = 0; - - /** - * Evaluate the precedence predicates for the context and reduce the result. - * - * @param parser The parser instance. - * @param parserCallStack - * @return The simplified semantic context after precedence predicates are - * evaluated, which will be one of the following values. - *
    - *
  • {@link #NONE}: if the predicate simplifies to {@code true} after - * precedence predicates are evaluated.
  • - *
  • {@code null}: if the predicate simplifies to {@code false} after - * precedence predicates are evaluated.
  • - *
  • {@code this}: if the semantic context is not changed as a result of - * precedence predicate evaluation.
  • - *
  • A non-{@code null} {@link SemanticContext}: the new simplified - * semantic context after precedence predicates are evaluated.
  • - *
- */ - virtual Ref evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const; - - virtual size_t hashCode() const = 0; - - virtual bool equals(const SemanticContext &other) const = 0; - - virtual std::string toString() const = 0; - - static Ref And(Ref a, Ref b); - - /// See also: ParserATNSimulator::getPredsForAmbigAlts. - static Ref Or(Ref a, Ref b); - - class Empty; - class Predicate; - class PrecedencePredicate; - class Operator; - class AND; - class OR; - - protected: - explicit SemanticContext(SemanticContextType contextType) : _contextType(contextType) {} - - private: - const SemanticContextType _contextType; - }; - - inline bool operator==(const SemanticContext &lhs, const SemanticContext &rhs) { - return lhs.equals(rhs); - } - - inline bool operator!=(const SemanticContext &lhs, const SemanticContext &rhs) { - return !operator==(lhs, rhs); - } - - class ANTLR4CPP_PUBLIC SemanticContext::Empty : public SemanticContext{ - public: - /** - * The default {@link SemanticContext}, which is semantically equivalent to - * a predicate of the form {@code {true}?}. - */ - static const Ref Instance; - }; - - class ANTLR4CPP_PUBLIC SemanticContext::Predicate final : public SemanticContext { - public: - static bool is(const SemanticContext &semanticContext) { return semanticContext.getContextType() == SemanticContextType::PREDICATE; } - - static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); } - - const size_t ruleIndex; - const size_t predIndex; - const bool isCtxDependent; // e.g., $i ref in pred - - Predicate(size_t ruleIndex, size_t predIndex, bool isCtxDependent); - - bool eval(Recognizer *parser, RuleContext *parserCallStack) const override; - size_t hashCode() const override; - bool equals(const SemanticContext &other) const override; - std::string toString() const override; - }; - - class ANTLR4CPP_PUBLIC SemanticContext::PrecedencePredicate final : public SemanticContext { - public: - static bool is(const SemanticContext &semanticContext) { return semanticContext.getContextType() == SemanticContextType::PRECEDENCE; } - - static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); } - - const int precedence; - - explicit PrecedencePredicate(int precedence); - - bool eval(Recognizer *parser, RuleContext *parserCallStack) const override; - Ref evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const override; - size_t hashCode() const override; - bool equals(const SemanticContext &other) const override; - std::string toString() const override; - }; - - /** - * This is the base class for semantic context "operators", which operate on - * a collection of semantic context "operands". - * - * @since 4.3 - */ - class ANTLR4CPP_PUBLIC SemanticContext::Operator : public SemanticContext { - public: - static bool is(const SemanticContext &semanticContext) { - const auto contextType = semanticContext.getContextType(); - return contextType == SemanticContextType::AND || contextType == SemanticContextType::OR; - } - - static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); } - - /** - * Gets the operands for the semantic context operator. - * - * @return a collection of {@link SemanticContext} operands for the - * operator. - * - * @since 4.3 - */ - - virtual const std::vector>& getOperands() const = 0; - - protected: - using SemanticContext::SemanticContext; - }; - - /** - * A semantic context which is true whenever none of the contained contexts - * is false. - */ - class ANTLR4CPP_PUBLIC SemanticContext::AND final : public SemanticContext::Operator { - public: - static bool is(const SemanticContext &semanticContext) { return semanticContext.getContextType() == SemanticContextType::AND; } - - static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); } - - AND(Ref a, Ref b) ; - - const std::vector>& getOperands() const override; - - /** - * The evaluation of predicates by this context is short-circuiting, but - * unordered.

- */ - bool eval(Recognizer *parser, RuleContext *parserCallStack) const override; - Ref evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const override; - size_t hashCode() const override; - bool equals(const SemanticContext &other) const override; - std::string toString() const override; - - private: - std::vector> _opnds; - }; - - /** - * A semantic context which is true whenever at least one of the contained - * contexts is true. - */ - class ANTLR4CPP_PUBLIC SemanticContext::OR final : public SemanticContext::Operator { - public: - static bool is(const SemanticContext &semanticContext) { return semanticContext.getContextType() == SemanticContextType::OR; } - - static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); } - - OR(Ref a, Ref b); - - const std::vector>& getOperands() const override; - - /** - * The evaluation of predicates by this context is short-circuiting, but - * unordered. - */ - bool eval(Recognizer *parser, RuleContext *parserCallStack) const override; - Ref evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const override; - size_t hashCode() const override; - bool equals(const SemanticContext &other) const override; - std::string toString() const override; - - private: - std::vector> _opnds; - }; - -} // namespace atn -} // namespace antlr4 - -namespace std { - - template <> - struct hash<::antlr4::atn::SemanticContext> { - size_t operator()(const ::antlr4::atn::SemanticContext &semanticContext) const { - return semanticContext.hashCode(); - } - }; - -} // namespace std diff --git a/src/include/atn/SemanticContextType.h b/src/include/atn/SemanticContextType.h deleted file mode 100644 index bca6e421..00000000 --- a/src/include/atn/SemanticContextType.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include - -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - - enum class SemanticContextType : size_t { - PREDICATE = 1, - PRECEDENCE = 2, - AND = 3, - OR = 4, - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/SerializedATNView.h b/src/include/atn/SerializedATNView.h deleted file mode 100644 index a723589b..00000000 --- a/src/include/atn/SerializedATNView.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include -#include -#include -#include -#include - -#include "antlr4-common.h" -#include "misc/MurmurHash.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC SerializedATNView final { - public: - using value_type = int32_t; - using size_type = size_t; - using difference_type = ptrdiff_t; - using reference = int32_t&; - using const_reference = const int32_t&; - using pointer = int32_t*; - using const_pointer = const int32_t*; - using iterator = const_pointer; - using const_iterator = const_pointer; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - - SerializedATNView() = default; - - SerializedATNView(const_pointer data, size_type size) : _data(data), _size(size) {} - - SerializedATNView(const std::vector &serializedATN) : _data(serializedATN.data()), _size(serializedATN.size()) {} - - SerializedATNView(const SerializedATNView&) = default; - - SerializedATNView& operator=(const SerializedATNView&) = default; - - const_iterator begin() const { return data(); } - - const_iterator cbegin() const { return data(); } - - const_iterator end() const { return data() + size(); } - - const_iterator cend() const { return data() + size(); } - - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - - const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); } - - const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - - const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); } - - bool empty() const { return size() == 0; } - - const_pointer data() const { return _data; } - - size_type size() const { return _size; } - - size_type size_bytes() const { return size() * sizeof(value_type); } - - const_reference operator[](size_type index) const { return _data[index]; } - - private: - const_pointer _data = nullptr; - size_type _size = 0; - }; - - inline bool operator==(const SerializedATNView &lhs, const SerializedATNView &rhs) { - return (lhs.data() == rhs.data() && lhs.size() == rhs.size()) || - (lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size_bytes()) == 0); - } - - inline bool operator!=(const SerializedATNView &lhs, const SerializedATNView &rhs) { - return !operator==(lhs, rhs); - } - - inline bool operator<(const SerializedATNView &lhs, const SerializedATNView &rhs) { - int diff = std::memcmp(lhs.data(), rhs.data(), std::min(lhs.size_bytes(), rhs.size_bytes())); - return diff < 0 || (diff == 0 && lhs.size() < rhs.size()); - } - -} // namespace atn -} // namespace antlr4 - -namespace std { - - template <> - struct hash<::antlr4::atn::SerializedATNView> { - size_t operator()(const ::antlr4::atn::SerializedATNView &serializedATNView) const { - return ::antlr4::misc::MurmurHash::hashCode(serializedATNView.data(), serializedATNView.size()); - } - }; - -} // namespace std diff --git a/src/include/atn/SetTransition.cpp b/src/include/atn/SetTransition.cpp deleted file mode 100755 index 69395832..00000000 --- a/src/include/atn/SetTransition.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "Token.h" -#include "misc/IntervalSet.h" - -#include "atn/SetTransition.h" - -using namespace antlr4; -using namespace antlr4::atn; - -SetTransition::SetTransition(TransitionType transitionType, ATNState *target, misc::IntervalSet aSet) - : Transition(transitionType, target), set(aSet.isEmpty() ? misc::IntervalSet::of(Token::INVALID_TYPE) : std::move(aSet)) { -} - -misc::IntervalSet SetTransition::label() const { - return set; -} - -bool SetTransition::matches(size_t symbol, size_t /*minVocabSymbol*/, size_t /*maxVocabSymbol*/) const { - return set.contains(symbol); -} - -std::string SetTransition::toString() const { - return "SET " + Transition::toString() + " { set: " + set.toString() + "}"; -} diff --git a/src/include/atn/SetTransition.h b/src/include/atn/SetTransition.h deleted file mode 100755 index cc514c3d..00000000 --- a/src/include/atn/SetTransition.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/Transition.h" - -namespace antlr4 { -namespace atn { - - /// - /// A transition containing a set of values. - class ANTLR4CPP_PUBLIC SetTransition : public Transition { - public: - static bool is(const Transition &transition) { - const auto transitionType = transition.getTransitionType(); - return transitionType == TransitionType::SET || transitionType == TransitionType::NOT_SET; - } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - const misc::IntervalSet set; - - SetTransition(ATNState *target, misc::IntervalSet set) : SetTransition(TransitionType::SET, target, std::move(set)) {} - - virtual misc::IntervalSet label() const override; - virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - - virtual std::string toString() const override; - - protected: - SetTransition(TransitionType transitionType, ATNState *target, misc::IntervalSet set); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/SingletonPredictionContext.cpp b/src/include/atn/SingletonPredictionContext.cpp deleted file mode 100755 index 3dc5464d..00000000 --- a/src/include/atn/SingletonPredictionContext.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/SingletonPredictionContext.h" - -#include "support/Casts.h" -#include "misc/MurmurHash.h" -#include "atn/HashUtils.h" - -using namespace antlr4::atn; -using namespace antlrcpp; - -SingletonPredictionContext::SingletonPredictionContext(Ref parent, size_t returnState) - : PredictionContext(PredictionContextType::SINGLETON), parent(std::move(parent)), returnState(returnState) { - assert(returnState != ATNState::INVALID_STATE_NUMBER); -} - -Ref SingletonPredictionContext::create(Ref parent, size_t returnState) { - if (returnState == EMPTY_RETURN_STATE && parent == nullptr) { - // someone can pass in the bits of an array ctx that mean $ - return std::dynamic_pointer_cast(EMPTY); - } - return std::make_shared(std::move(parent), returnState); -} - -bool SingletonPredictionContext::isEmpty() const { - return parent == nullptr && returnState == EMPTY_RETURN_STATE; -} - -size_t SingletonPredictionContext::size() const { - return 1; -} - -const Ref& SingletonPredictionContext::getParent(size_t index) const { - assert(index == 0); - static_cast(index); - return parent; -} - -size_t SingletonPredictionContext::getReturnState(size_t index) const { - assert(index == 0); - static_cast(index); - return returnState; -} - -size_t SingletonPredictionContext::hashCodeImpl() const { - size_t hash = misc::MurmurHash::initialize(); - hash = misc::MurmurHash::update(hash, static_cast(getContextType())); - hash = misc::MurmurHash::update(hash, parent); - hash = misc::MurmurHash::update(hash, returnState); - return misc::MurmurHash::finish(hash, 3); -} - -bool SingletonPredictionContext::equals(const PredictionContext &other) const { - if (this == std::addressof(other)) { - return true; - } - if (getContextType() != other.getContextType()) { - return false; - } - const auto &singleton = downCast(other); - return returnState == singleton.returnState && - cachedHashCodeEqual(cachedHashCode(), singleton.cachedHashCode()) && - (parent == singleton.parent || (parent != nullptr && singleton.parent != nullptr && *parent == *singleton.parent)); -} - -std::string SingletonPredictionContext::toString() const { - //std::string up = !parent.expired() ? parent.lock()->toString() : ""; - std::string up = parent != nullptr ? parent->toString() : ""; - if (up.length() == 0) { - if (returnState == EMPTY_RETURN_STATE) { - return "$"; - } - return std::to_string(returnState); - } - return std::to_string(returnState) + " " + up; -} diff --git a/src/include/atn/SingletonPredictionContext.h b/src/include/atn/SingletonPredictionContext.h deleted file mode 100755 index 646a6fdd..00000000 --- a/src/include/atn/SingletonPredictionContext.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/PredictionContext.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC SingletonPredictionContext final : public PredictionContext { - public: - static bool is(const PredictionContext &predictionContext) { return predictionContext.getContextType() == PredictionContextType::SINGLETON; } - - static bool is(const PredictionContext *predictionContext) { return predictionContext != nullptr && is(*predictionContext); } - - static Ref create(Ref parent, size_t returnState); - - // Usually a parent is linked via a weak ptr. Not so here as we have kinda reverse reference chain. - // There are no child contexts stored here and often the parent context is left dangling when it's - // owning ATNState is released. In order to avoid having this context released as well (leaving all other contexts - // which got this one as parent with a null reference) we use a shared_ptr here instead, to keep those left alone - // parent contexts alive. - const Ref parent; - const size_t returnState; - - SingletonPredictionContext(Ref parent, size_t returnState); - - bool isEmpty() const override; - size_t size() const override; - const Ref& getParent(size_t index) const override; - size_t getReturnState(size_t index) const override; - bool equals(const PredictionContext &other) const override; - std::string toString() const override; - - protected: - size_t hashCodeImpl() const override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/StarBlockStartState.h b/src/include/atn/StarBlockStartState.h deleted file mode 100755 index a162631d..00000000 --- a/src/include/atn/StarBlockStartState.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/BlockStartState.h" - -namespace antlr4 { -namespace atn { - - /// The block that begins a closure loop. - class ANTLR4CPP_PUBLIC StarBlockStartState final : public BlockStartState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::STAR_BLOCK_START; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - StarBlockStartState() : BlockStartState(ATNStateType::STAR_BLOCK_START) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/StarLoopEntryState.h b/src/include/atn/StarLoopEntryState.h deleted file mode 100755 index c3f47b8f..00000000 --- a/src/include/atn/StarLoopEntryState.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionState.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC StarLoopEntryState final : public DecisionState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::STAR_LOOP_ENTRY; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - /** - * Indicates whether this state can benefit from a precedence DFA during SLL - * decision making. - * - *

This is a computed property that is calculated during ATN deserialization - * and stored for use in {@link ParserATNSimulator} and - * {@link ParserInterpreter}.

- * - * @see DFA#isPrecedenceDfa() - */ - bool isPrecedenceDecision = false; - - StarLoopbackState *loopBackState = nullptr; - - StarLoopEntryState() : DecisionState(ATNStateType::STAR_LOOP_ENTRY) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/StarLoopbackState.cpp b/src/include/atn/StarLoopbackState.cpp deleted file mode 100755 index 40d05e69..00000000 --- a/src/include/atn/StarLoopbackState.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/StarLoopEntryState.h" -#include "atn/Transition.h" -#include "support/Casts.h" - -#include "atn/StarLoopbackState.h" - -using namespace antlr4::atn; - -StarLoopEntryState *StarLoopbackState::getLoopEntryState() const { - if (transitions[0]->target != nullptr && transitions[0]->target->getStateType() == ATNStateType::STAR_LOOP_ENTRY) { - return antlrcpp::downCast(transitions[0]->target); - } - return nullptr; -} diff --git a/src/include/atn/StarLoopbackState.h b/src/include/atn/StarLoopbackState.h deleted file mode 100755 index 0780b4c2..00000000 --- a/src/include/atn/StarLoopbackState.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/ATNState.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC StarLoopbackState final : public ATNState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::STAR_LOOP_BACK; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - StarLoopbackState() : ATNState(ATNStateType::STAR_LOOP_BACK) {} - - StarLoopEntryState *getLoopEntryState() const; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/TokensStartState.h b/src/include/atn/TokensStartState.h deleted file mode 100755 index e1d043e7..00000000 --- a/src/include/atn/TokensStartState.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/DecisionState.h" - -namespace antlr4 { -namespace atn { - - /// The Tokens rule start state linking to each lexer rule start state. - class ANTLR4CPP_PUBLIC TokensStartState final : public DecisionState { - public: - static bool is(const ATNState &atnState) { return atnState.getStateType() == ATNStateType::TOKEN_START; } - - static bool is(const ATNState *atnState) { return atnState != nullptr && is(*atnState); } - - TokensStartState() : DecisionState(ATNStateType::TOKEN_START) {} - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/Transition.cpp b/src/include/atn/Transition.cpp deleted file mode 100755 index da9b7fd4..00000000 --- a/src/include/atn/Transition.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "Exceptions.h" -#include "support/Arrays.h" - -#include "atn/Transition.h" - -using namespace antlr4; -using namespace antlr4::atn; -using namespace antlrcpp; - -Transition::Transition(TransitionType transitionType, ATNState *target) : _transitionType(transitionType) { - if (target == nullptr) { - throw NullPointerException("target cannot be null."); - } - - this->target = target; -} - -bool Transition::isEpsilon() const { - return false; -} - -misc::IntervalSet Transition::label() const { - return misc::IntervalSet::EMPTY_SET; -} - -std::string Transition::toString() const { - std::stringstream ss; - ss << "(Transition " << std::hex << this << ", target: " << std::hex << target << ')'; - - return ss.str(); -} diff --git a/src/include/atn/Transition.h b/src/include/atn/Transition.h deleted file mode 100755 index 72db7512..00000000 --- a/src/include/atn/Transition.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "misc/IntervalSet.h" -#include "atn/TransitionType.h" - -namespace antlr4 { -namespace atn { - - /// - /// An ATN transition between any two ATN states. Subclasses define - /// atom, set, epsilon, action, predicate, rule transitions. - ///

- /// This is a one way link. It emanates from a state (usually via a list of - /// transitions) and has a target state. - ///

- /// Since we never have to change the ATN transitions once we construct it, - /// we can fix these transitions as specific classes. The DFA transitions - /// on the other hand need to update the labels as it adds transitions to - /// the states. We'll use the term Edge for the DFA to distinguish them from - /// ATN transitions. - ///

- class ANTLR4CPP_PUBLIC Transition { - public: - /// The target of this transition. - // ml: this is a reference into the ATN. - ATNState *target; - - virtual ~Transition() = default; - - TransitionType getTransitionType() const { return _transitionType; } - - /** - * Determines if the transition is an "epsilon" transition. - * - *

The default implementation returns {@code false}.

- * - * @return {@code true} if traversing this transition in the ATN does not - * consume an input symbol; otherwise, {@code false} if traversing this - * transition consumes (matches) an input symbol. - */ - virtual bool isEpsilon() const; - virtual misc::IntervalSet label() const; - virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const = 0; - - virtual std::string toString() const; - - Transition(Transition const&) = delete; - Transition& operator=(Transition const&) = delete; - - protected: - Transition(TransitionType transitionType, ATNState *target); - - private: - const TransitionType _transitionType; - }; - - using ConstTransitionPtr = std::unique_ptr; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/TransitionType.cpp b/src/include/atn/TransitionType.cpp deleted file mode 100644 index 78769b2a..00000000 --- a/src/include/atn/TransitionType.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "atn/TransitionType.h" - -std::string antlr4::atn::transitionTypeName(TransitionType transitionType) { - switch (transitionType) { - case TransitionType::EPSILON: - return "EPSILON"; - case TransitionType::RANGE: - return "RANGE"; - case TransitionType::RULE: - return "RULE"; - case TransitionType::PREDICATE: - return "PREDICATE"; - case TransitionType::ATOM: - return "ATOM"; - case TransitionType::ACTION: - return "ACTION"; - case TransitionType::SET: - return "SET"; - case TransitionType::NOT_SET: - return "NOT_SET"; - case TransitionType::WILDCARD: - return "WILDCARD"; - case TransitionType::PRECEDENCE: - return "PRECEDENCE"; - } - return "UNKNOWN"; -} diff --git a/src/include/atn/TransitionType.h b/src/include/atn/TransitionType.h deleted file mode 100644 index d5d5f3bd..00000000 --- a/src/include/atn/TransitionType.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include -#include - -#include "antlr4-common.h" - -namespace antlr4 { -namespace atn { - - // Constants for transition serialization. - enum class TransitionType : size_t { - EPSILON = 1, - RANGE = 2, - RULE = 3, - PREDICATE = 4, // e.g., {isType(input.LT(1))}? - ATOM = 5, - ACTION = 6, - SET = 7, // ~(A|B) or ~atom, wildcard, which convert to next 2 - NOT_SET = 8, - WILDCARD = 9, - PRECEDENCE = 10, - }; - - ANTLR4CPP_PUBLIC std::string transitionTypeName(TransitionType transitionType); - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/atn/WildcardTransition.cpp b/src/include/atn/WildcardTransition.cpp deleted file mode 100755 index 9614815e..00000000 --- a/src/include/atn/WildcardTransition.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ATNState.h" - -#include "atn/WildcardTransition.h" - -using namespace antlr4::atn; - -WildcardTransition::WildcardTransition(ATNState *target) : Transition(TransitionType::WILDCARD, target) { -} - -bool WildcardTransition::matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const { - return symbol >= minVocabSymbol && symbol <= maxVocabSymbol; -} - -std::string WildcardTransition::toString() const { - return "WILDCARD " + Transition::toString() + " {}"; -} diff --git a/src/include/atn/WildcardTransition.h b/src/include/atn/WildcardTransition.h deleted file mode 100755 index e088e893..00000000 --- a/src/include/atn/WildcardTransition.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "atn/Transition.h" - -namespace antlr4 { -namespace atn { - - class ANTLR4CPP_PUBLIC WildcardTransition final : public Transition { - public: - static bool is(const Transition &transition) { return transition.getTransitionType() == TransitionType::WILDCARD; } - - static bool is(const Transition *transition) { return transition != nullptr && is(*transition); } - - explicit WildcardTransition(ATNState *target); - - virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override; - - virtual std::string toString() const override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/dfa/DFA.cpp b/src/include/dfa/DFA.cpp deleted file mode 100755 index ef5b07c5..00000000 --- a/src/include/dfa/DFA.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "dfa/DFASerializer.h" -#include "dfa/LexerDFASerializer.h" -#include "support/CPPUtils.h" -#include "atn/StarLoopEntryState.h" -#include "atn/ATNConfigSet.h" -#include "support/Casts.h" - -#include "dfa/DFA.h" - -using namespace antlr4; -using namespace antlr4::dfa; -using namespace antlrcpp; - -DFA::DFA(atn::DecisionState *atnStartState) : DFA(atnStartState, 0) { -} - -DFA::DFA(atn::DecisionState *atnStartState, size_t decision) - : atnStartState(atnStartState), s0(nullptr), decision(decision) { - - _precedenceDfa = false; - if (atn::StarLoopEntryState::is(atnStartState)) { - if (downCast(atnStartState)->isPrecedenceDecision) { - _precedenceDfa = true; - s0 = new DFAState(std::unique_ptr(new atn::ATNConfigSet())); - s0->isAcceptState = false; - s0->requiresFullContext = false; - } - } -} - -DFA::DFA(DFA &&other) : atnStartState(other.atnStartState), s0(other.s0), decision(other.decision) { - // Source states are implicitly cleared by the move. - states = std::move(other.states); - - other.atnStartState = nullptr; - other.decision = 0; - other.s0 = nullptr; - _precedenceDfa = other._precedenceDfa; - other._precedenceDfa = false; -} - -DFA::~DFA() { - bool s0InList = (s0 == nullptr); - for (auto *state : states) { - if (state == s0) - s0InList = true; - delete state; - } - - if (!s0InList) { - delete s0; - } -} - -bool DFA::isPrecedenceDfa() const { - return _precedenceDfa; -} - -DFAState* DFA::getPrecedenceStartState(int precedence) const { - assert(_precedenceDfa); // Only precedence DFAs may contain a precedence start state. - - auto iterator = s0->edges.find(precedence); - if (iterator == s0->edges.end()) - return nullptr; - - return iterator->second; -} - -void DFA::setPrecedenceStartState(int precedence, DFAState *startState) { - if (!isPrecedenceDfa()) { - throw IllegalStateException("Only precedence DFAs may contain a precedence start state."); - } - - if (precedence < 0) { - return; - } - - s0->edges[precedence] = startState; -} - -std::vector DFA::getStates() const { - std::vector result; - for (auto *state : states) - result.push_back(state); - - std::sort(result.begin(), result.end(), [](DFAState *o1, DFAState *o2) -> bool { - return o1->stateNumber < o2->stateNumber; - }); - - return result; -} - -std::string DFA::toString(const Vocabulary &vocabulary) const { - if (s0 == nullptr) { - return ""; - } - - DFASerializer serializer(this, vocabulary); - return serializer.toString(); -} - -std::string DFA::toLexerString() const { - if (s0 == nullptr) { - return ""; - } - LexerDFASerializer serializer(this); - - return serializer.toString(); -} - diff --git a/src/include/dfa/DFA.h b/src/include/dfa/DFA.h deleted file mode 100755 index f6766557..00000000 --- a/src/include/dfa/DFA.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "dfa/DFAState.h" - -namespace antlr4 { -namespace dfa { - - class ANTLR4CPP_PUBLIC DFA final { - private: - struct DFAStateHasher final { - size_t operator()(const DFAState *dfaState) const { - return dfaState->hashCode(); - } - }; - - struct DFAStateComparer final { - bool operator()(const DFAState *lhs, const DFAState *rhs) const { - return lhs == rhs || *lhs == *rhs; - } - }; - - public: - /// A set of all DFA states. Use a map so we can get old state back. - /// Set only allows you to see if it's there. - - /// From which ATN state did we create this DFA? - atn::DecisionState *atnStartState; - std::unordered_set states; // States are owned by this class. - DFAState *s0; - size_t decision; - - explicit DFA(atn::DecisionState *atnStartState); - DFA(atn::DecisionState *atnStartState, size_t decision); - DFA(const DFA &other) = delete; - DFA(DFA &&other); - ~DFA(); - - /** - * Gets whether this DFA is a precedence DFA. Precedence DFAs use a special - * start state {@link #s0} which is not stored in {@link #states}. The - * {@link DFAState#edges} array for this start state contains outgoing edges - * supplying individual start states corresponding to specific precedence - * values. - * - * @return {@code true} if this is a precedence DFA; otherwise, - * {@code false}. - * @see Parser#getPrecedence() - */ - bool isPrecedenceDfa() const; - - /** - * Get the start state for a specific precedence value. - * - * @param precedence The current precedence. - * @return The start state corresponding to the specified precedence, or - * {@code null} if no start state exists for the specified precedence. - * - * @throws IllegalStateException if this is not a precedence DFA. - * @see #isPrecedenceDfa() - */ - DFAState* getPrecedenceStartState(int precedence) const; - - /** - * Set the start state for a specific precedence value. - * - * @param precedence The current precedence. - * @param startState The start state corresponding to the specified - * precedence. - * - * @throws IllegalStateException if this is not a precedence DFA. - * @see #isPrecedenceDfa() - */ - void setPrecedenceStartState(int precedence, DFAState *startState); - - /// Return a list of all states in this DFA, ordered by state number. - std::vector getStates() const; - - std::string toString(const Vocabulary &vocabulary) const; - - std::string toLexerString() const; - - private: - /** - * {@code true} if this DFA is for a precedence decision; otherwise, - * {@code false}. This is the backing field for {@link #isPrecedenceDfa}. - */ - bool _precedenceDfa; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/dfa/DFASerializer.cpp b/src/include/dfa/DFASerializer.cpp deleted file mode 100755 index 50c86c43..00000000 --- a/src/include/dfa/DFASerializer.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "dfa/DFA.h" -#include "Vocabulary.h" - -#include "dfa/DFASerializer.h" - -using namespace antlr4::dfa; - -DFASerializer::DFASerializer(const DFA *dfa, const Vocabulary &vocabulary) : _dfa(dfa), _vocabulary(vocabulary) { -} - -std::string DFASerializer::toString() const { - if (_dfa->s0 == nullptr) { - return ""; - } - - std::stringstream ss; - std::vector states = _dfa->getStates(); - for (auto *s : states) { - for (size_t i = 0; i < s->edges.size(); i++) { - DFAState *t = s->edges[i]; - if (t != nullptr && t->stateNumber != INT32_MAX) { - ss << getStateString(s); - std::string label = getEdgeLabel(i); - ss << "-" << label << "->" << getStateString(t) << "\n"; - } - } - } - - return ss.str(); -} - -std::string DFASerializer::getEdgeLabel(size_t i) const { - return _vocabulary.getDisplayName(i); // ml: no longer needed -1 as we use a map for edges, without offset. -} - -std::string DFASerializer::getStateString(DFAState *s) const { - size_t n = s->stateNumber; - - const std::string baseStateStr = std::string(s->isAcceptState ? ":" : "") + "s" + std::to_string(n) + - (s->requiresFullContext ? "^" : ""); - - if (s->isAcceptState) { - if (!s->predicates.empty()) { - std::string buf; - for (size_t i = 0; i < s->predicates.size(); i++) { - buf.append(s->predicates[i].toString()); - } - return baseStateStr + "=>" + buf; - } else { - return baseStateStr + "=>" + std::to_string(s->prediction); - } - } else { - return baseStateStr; - } -} diff --git a/src/include/dfa/DFASerializer.h b/src/include/dfa/DFASerializer.h deleted file mode 100755 index 155c8b20..00000000 --- a/src/include/dfa/DFASerializer.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "Vocabulary.h" - -namespace antlr4 { -namespace dfa { - - /// A DFA walker that knows how to dump them to serialized strings. - class ANTLR4CPP_PUBLIC DFASerializer { - public: - DFASerializer(const DFA *dfa, const Vocabulary &vocabulary); - - virtual ~DFASerializer() = default; - - std::string toString() const; - - protected: - virtual std::string getEdgeLabel(size_t i) const; - std::string getStateString(DFAState *s) const; - - private: - const DFA *_dfa; - const Vocabulary &_vocabulary; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/dfa/DFAState.cpp b/src/include/dfa/DFAState.cpp deleted file mode 100755 index 85acff81..00000000 --- a/src/include/dfa/DFAState.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ATNConfigSet.h" -#include "atn/SemanticContext.h" -#include "atn/ATNConfig.h" -#include "misc/MurmurHash.h" - -#include "dfa/DFAState.h" - -using namespace antlr4::dfa; -using namespace antlr4::atn; - -std::string DFAState::PredPrediction::toString() const { - return std::string("(") + pred->toString() + ", " + std::to_string(alt) + ")"; -} - -std::set DFAState::getAltSet() const { - std::set alts; - if (configs != nullptr) { - for (size_t i = 0; i < configs->size(); i++) { - alts.insert(configs->get(i)->alt); - } - } - return alts; -} - -size_t DFAState::hashCode() const { - return configs != nullptr ? configs->hashCode() : 0; -} - -bool DFAState::equals(const DFAState &other) const { - if (this == std::addressof(other)) { - return true; - } - return configs == other.configs || - (configs != nullptr && other.configs != nullptr && *configs == *other.configs); -} - -std::string DFAState::toString() const { - std::stringstream ss; - ss << stateNumber; - if (configs) { - ss << ":" << configs->toString(); - } - if (isAcceptState) { - ss << "=>"; - if (!predicates.empty()) { - for (size_t i = 0; i < predicates.size(); i++) { - ss << predicates[i].toString(); - } - } else { - ss << prediction; - } - } - return ss.str(); -} diff --git a/src/include/dfa/DFAState.h b/src/include/dfa/DFAState.h deleted file mode 100755 index 5b33a885..00000000 --- a/src/include/dfa/DFAState.h +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -#include "atn/ATNConfigSet.h" -#include "FlatHashMap.h" - -namespace antlr4 { -namespace dfa { - - /// - /// A DFA state represents a set of possible ATN configurations. - /// As Aho, Sethi, Ullman p. 117 says "The DFA uses its state - /// to keep track of all possible states the ATN can be in after - /// reading each input symbol. That is to say, after reading - /// input a1a2..an, the DFA is in a state that represents the - /// subset T of the states of the ATN that are reachable from the - /// ATN's start state along some path labeled a1a2..an." - /// In conventional NFA->DFA conversion, therefore, the subset T - /// would be a bitset representing the set of states the - /// ATN could be in. We need to track the alt predicted by each - /// state as well, however. More importantly, we need to maintain - /// a stack of states, tracking the closure operations as they - /// jump from rule to rule, emulating rule invocations (method calls). - /// I have to add a stack to simulate the proper lookahead sequences for - /// the underlying LL grammar from which the ATN was derived. - ///

- /// I use a set of ATNConfig objects not simple states. An ATNConfig - /// is both a state (ala normal conversion) and a RuleContext describing - /// the chain of rules (if any) followed to arrive at that state. - ///

- /// A DFA state may have multiple references to a particular state, - /// but with different ATN contexts (with same or different alts) - /// meaning that state was reached via a different set of rule invocations. - ///

- class ANTLR4CPP_PUBLIC DFAState final { - public: - struct ANTLR4CPP_PUBLIC PredPrediction final { - public: - Ref pred; // never null; at least SemanticContext.NONE - int alt; - - PredPrediction() = delete; - - PredPrediction(const PredPrediction&) = default; - PredPrediction(PredPrediction&&) = default; - - PredPrediction(Ref pred, int alt) : pred(std::move(pred)), alt(alt) {} - - PredPrediction& operator=(const PredPrediction&) = default; - PredPrediction& operator=(PredPrediction&&) = default; - - std::string toString() const; - }; - - std::unique_ptr configs; - - /// {@code edges[symbol]} points to target of symbol. Shift up by 1 so (-1) - /// maps to {@code edges[0]}. - // ml: this is a sparse list, so we use a map instead of a vector. - // Watch out: we no longer have the -1 offset, as it isn't needed anymore. - FlatHashMap edges; - - /// if accept state, what ttype do we match or alt do we predict? - /// This is set to when {@code !=null} or - /// . - size_t prediction = 0; - - Ref lexerActionExecutor; - - /// - /// During SLL parsing, this is a list of predicates associated with the - /// ATN configurations of the DFA state. When we have predicates, - /// is {@code false} since full context prediction evaluates predicates - /// on-the-fly. If this is not null, then is - /// . - ///

- /// We only use these for non- but conflicting states. That - /// means we know from the context (it's $ or we don't dip into outer - /// context) that it's an ambiguity not a conflict. - ///

- /// This list is computed by . - ///

- std::vector predicates; - - int stateNumber = -1; - - bool isAcceptState = false; - - /// - /// Indicates that this state was created during SLL prediction that - /// discovered a conflict between the configurations in the state. Future - /// invocations immediately jumped doing - /// full context prediction if this field is true. - /// - bool requiresFullContext = false; - - /// Map a predicate to a predicted alternative. - DFAState() = default; - - explicit DFAState(int stateNumber) : stateNumber(stateNumber) {} - - explicit DFAState(std::unique_ptr configs) : configs(std::move(configs)) {} - - /// - /// Get the set of all alts mentioned by all ATN configurations in this - /// DFA state. - /// - std::set getAltSet() const; - - size_t hashCode() const; - - /// Two DFAState instances are equal if their ATN configuration sets - /// are the same. This method is used to see if a state already exists. - /// - /// Because the number of alternatives and number of ATN configurations are - /// finite, there is a finite number of DFA states that can be processed. - /// This is necessary to show that the algorithm terminates. - /// - /// Cannot test the DFA state numbers here because in - /// ParserATNSimulator#addDFAState we need to know if any other state - /// exists that has this exact set of ATN configurations. The - /// stateNumber is irrelevant. - bool equals(const DFAState &other) const; - - std::string toString() const; - }; - - inline bool operator==(const DFAState &lhs, const DFAState &rhs) { - return lhs.equals(rhs); - } - - inline bool operator!=(const DFAState &lhs, const DFAState &rhs) { - return !operator==(lhs, rhs); - } - -} // namespace dfa -} // namespace antlr4 - -namespace std { - - template <> - struct hash<::antlr4::dfa::DFAState> { - size_t operator()(const ::antlr4::dfa::DFAState &dfaState) const { - return dfaState.hashCode(); - } - }; - -} // namespace std diff --git a/src/include/dfa/LexerDFASerializer.cpp b/src/include/dfa/LexerDFASerializer.cpp deleted file mode 100755 index fe95fd19..00000000 --- a/src/include/dfa/LexerDFASerializer.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "Vocabulary.h" - -#include "dfa/LexerDFASerializer.h" - -using namespace antlr4::dfa; - -LexerDFASerializer::LexerDFASerializer(const DFA *dfa) : DFASerializer(dfa, Vocabulary()) { -} - -std::string LexerDFASerializer::getEdgeLabel(size_t i) const { - return std::string("'") + static_cast(i) + "'"; -} diff --git a/src/include/dfa/LexerDFASerializer.h b/src/include/dfa/LexerDFASerializer.h deleted file mode 100755 index 3a6c7822..00000000 --- a/src/include/dfa/LexerDFASerializer.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "dfa/DFASerializer.h" - -namespace antlr4 { -namespace dfa { - - class ANTLR4CPP_PUBLIC LexerDFASerializer final : public DFASerializer { - public: - explicit LexerDFASerializer(const DFA *dfa); - - protected: - std::string getEdgeLabel(size_t i) const override; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/internal/Synchronization.cpp b/src/include/internal/Synchronization.cpp deleted file mode 100644 index dd30ef97..00000000 --- a/src/include/internal/Synchronization.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2012-2022 The ANTLR Project -// -// 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. Neither the name of the copyright holder nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR -// CONTRIBUTORS 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 "internal/Synchronization.h" - -using namespace antlr4::internal; - -void Mutex::lock() { -#if ANTLR4CPP_USING_ABSEIL - _impl.Lock(); -#else - _impl.lock(); -#endif -} - -bool Mutex::try_lock() { -#if ANTLR4CPP_USING_ABSEIL - return _impl.TryLock(); -#else - return _impl.try_lock(); -#endif -} - -void Mutex::unlock() { -#if ANTLR4CPP_USING_ABSEIL - _impl.Unlock(); -#else - _impl.unlock(); -#endif -} - -void SharedMutex::lock() { -#if ANTLR4CPP_USING_ABSEIL - _impl.WriterLock(); -#else - _impl.lock(); -#endif -} - -bool SharedMutex::try_lock() { -#if ANTLR4CPP_USING_ABSEIL - return _impl.WriterTryLock(); -#else - return _impl.try_lock(); -#endif -} - -void SharedMutex::unlock() { -#if ANTLR4CPP_USING_ABSEIL - _impl.WriterUnlock(); -#else - _impl.unlock(); -#endif -} - -void SharedMutex::lock_shared() { -#if ANTLR4CPP_USING_ABSEIL - _impl.ReaderLock(); -#else - _impl.lock_shared(); -#endif -} - -bool SharedMutex::try_lock_shared() { -#if ANTLR4CPP_USING_ABSEIL - return _impl.ReaderTryLock(); -#else - return _impl.try_lock_shared(); -#endif -} - -void SharedMutex::unlock_shared() { -#if ANTLR4CPP_USING_ABSEIL - _impl.ReaderUnlock(); -#else - _impl.unlock_shared(); -#endif -} diff --git a/src/include/internal/Synchronization.h b/src/include/internal/Synchronization.h deleted file mode 100644 index 4f969a8a..00000000 --- a/src/include/internal/Synchronization.h +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2012-2022 The ANTLR Project -// -// 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. Neither the name of the copyright holder nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR -// CONTRIBUTORS 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 - -#include "antlr4-common.h" - -#include -#include -#include - -#if ANTLR4CPP_USING_ABSEIL -#include "absl/base/call_once.h" -#include "absl/base/thread_annotations.h" -#include "absl/synchronization/mutex.h" -#define ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS ABSL_NO_THREAD_SAFETY_ANALYSIS -#else -#define ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS -#endif - -// By default ANTLRv4 uses synchronization primitives provided by the C++ standard library. In most -// deployments this is fine, however in some using custom synchronization primitives may be -// preferred. This header allows that by optionally supporting some alternative implementations and -// allowing for more easier patching of other alternatives. - -namespace antlr4::internal { - - // Must be compatible with C++ standard library Mutex requirement. - class ANTLR4CPP_PUBLIC Mutex final { - public: - Mutex() = default; - - // No copying or moving, we are as strict as possible to support other implementations. - Mutex(const Mutex&) = delete; - Mutex(Mutex&&) = delete; - - // No copying or moving, we are as strict as possible to support other implementations. - Mutex& operator=(const Mutex&) = delete; - Mutex& operator=(Mutex&&) = delete; - - void lock() ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS; - - bool try_lock() ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS; - - void unlock() ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS; - - private: -#if ANTLR4CPP_USING_ABSEIL - absl::Mutex _impl; -#else - std::mutex _impl; -#endif - }; - - template - using UniqueLock = std::unique_lock; - - // Must be compatible with C++ standard library SharedMutex requirement. - class ANTLR4CPP_PUBLIC SharedMutex final { - public: - SharedMutex() = default; - - // No copying or moving, we are as strict as possible to support other implementations. - SharedMutex(const SharedMutex&) = delete; - SharedMutex(SharedMutex&&) = delete; - - // No copying or moving, we are as strict as possible to support other implementations. - SharedMutex& operator=(const SharedMutex&) = delete; - SharedMutex& operator=(SharedMutex&&) = delete; - - void lock() ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS; - - bool try_lock() ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS; - - void unlock() ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS; - - void lock_shared() ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS; - - bool try_lock_shared() ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS; - - void unlock_shared() ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS; - - private: -#if ANTLR4CPP_USING_ABSEIL - absl::Mutex _impl; -#else - std::shared_mutex _impl; -#endif - }; - - template - using SharedLock = std::shared_lock; - - class OnceFlag; - - template - void call_once(OnceFlag &onceFlag, Callable &&callable, Args&&... args); - - // Must be compatible with std::once_flag. - class ANTLR4CPP_PUBLIC OnceFlag final { - public: - constexpr OnceFlag() = default; - - // No copying or moving, we are as strict as possible to support other implementations. - OnceFlag(const OnceFlag&) = delete; - OnceFlag(OnceFlag&&) = delete; - - // No copying or moving, we are as strict as possible to support other implementations. - OnceFlag& operator=(const OnceFlag&) = delete; - OnceFlag& operator=(OnceFlag&&) = delete; - - private: - template - friend void call_once(OnceFlag &onceFlag, Callable &&callable, Args&&... args); - -#if ANTLR4CPP_USING_ABSEIL - absl::once_flag _impl; -#else - std::once_flag _impl; -#endif - }; - - template - void call_once(OnceFlag &onceFlag, Callable &&callable, Args&&... args) { -#if ANTLR4CPP_USING_ABSEIL - absl::call_once(onceFlag._impl, std::forward(callable), std::forward(args)...); -#else - std::call_once(onceFlag._impl, std::forward(callable), std::forward(args)...); -#endif - } - -} // namespace antlr4::internal diff --git a/src/include/misc/InterpreterDataReader.cpp b/src/include/misc/InterpreterDataReader.cpp deleted file mode 100755 index 0bcaf07b..00000000 --- a/src/include/misc/InterpreterDataReader.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "atn/ATN.h" -#include "atn/ATNDeserializer.h" -#include "Vocabulary.h" - -#include "misc/InterpreterDataReader.h" - -using namespace antlr4::dfa; -using namespace antlr4::atn; -using namespace antlr4::misc; - -InterpreterData::InterpreterData(std::vector const& literalNames, std::vector const& symbolicNames) -: vocabulary(literalNames, symbolicNames) { -} - -InterpreterData InterpreterDataReader::parseFile(std::string const& fileName) { - // The structure of the data file is very simple. Everything is line based with empty lines - // separating the different parts. For lexers the layout is: - // token literal names: - // ... - // - // token symbolic names: - // ... - // - // rule names: - // ... - // - // channel names: - // ... - // - // mode names: - // ... - // - // atn: - // enclosed in a pair of squared brackets. - // - // Data for a parser does not contain channel and mode names. - - std::ifstream input(fileName); - if (!input.good()) - return {}; - - std::vector literalNames; - std::vector symbolicNames; - - std::string line; - - std::getline(input, line, '\n'); - assert(line == "token literal names:"); - while (true) { - std::getline(input, line, '\n'); - if (line.empty()) - break; - - literalNames.push_back(line == "null" ? "" : line); - }; - - std::getline(input, line, '\n'); - assert(line == "token symbolic names:"); - while (true) { - std::getline(input, line, '\n'); - if (line.empty()) - break; - - symbolicNames.push_back(line == "null" ? "" : line); - }; - InterpreterData result(literalNames, symbolicNames); - - std::getline(input, line, '\n'); - assert(line == "rule names:"); - while (true) { - std::getline(input, line, '\n'); - if (line.empty()) - break; - - result.ruleNames.push_back(line); - }; - - std::getline(input, line, '\n'); - if (line == "channel names:") { - while (true) { - std::getline(input, line, '\n'); - if (line.empty()) - break; - - result.channels.push_back(line); - }; - - std::getline(input, line, '\n'); - assert(line == "mode names:"); - while (true) { - std::getline(input, line, '\n'); - if (line.empty()) - break; - - result.modes.push_back(line); - }; - } - - std::vector serializedATN; - - std::getline(input, line, '\n'); - assert(line == "atn:"); - std::getline(input, line, '\n'); - std::stringstream tokenizer(line); - std::string value; - while (tokenizer.good()) { - std::getline(tokenizer, value, ','); - unsigned long number; - if (value[0] == '[') - number = std::strtoul(&value[1], nullptr, 10); - else - number = std::strtoul(value.c_str(), nullptr, 10); - serializedATN.push_back(static_cast(number)); - } - - ATNDeserializer deserializer; - result.atn = deserializer.deserialize(serializedATN); - return result; -} diff --git a/src/include/misc/InterpreterDataReader.h b/src/include/misc/InterpreterDataReader.h deleted file mode 100755 index c0cf9880..00000000 --- a/src/include/misc/InterpreterDataReader.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" -#include "atn/ATN.h" -#include "Vocabulary.h" - -namespace antlr4 { -namespace misc { - - struct InterpreterData { - std::unique_ptr atn; - dfa::Vocabulary vocabulary; - std::vector ruleNames; - std::vector channels; // Only valid for lexer grammars. - std::vector modes; // ditto - - InterpreterData() {}; // For invalid content. - InterpreterData(std::vector const& literalNames, std::vector const& symbolicNames); - }; - - // A class to read plain text interpreter data produced by ANTLR. - class ANTLR4CPP_PUBLIC InterpreterDataReader { - public: - static InterpreterData parseFile(std::string const& fileName); - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/misc/Interval.cpp b/src/include/misc/Interval.cpp deleted file mode 100755 index 16eec343..00000000 --- a/src/include/misc/Interval.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/Interval.h" - -using namespace antlr4::misc; - -const Interval Interval::INVALID; - -size_t Interval::hashCode() const { - size_t hash = 23; - hash = hash * 31 + static_cast(a); - hash = hash * 31 + static_cast(b); - return hash; -} - -bool Interval::startsBeforeDisjoint(const Interval &other) const { - return a < other.a && b < other.a; -} - -bool Interval::startsBeforeNonDisjoint(const Interval &other) const { - return a <= other.a && b >= other.a; -} - -bool Interval::startsAfter(const Interval &other) const { - return a > other.a; -} - -bool Interval::startsAfterDisjoint(const Interval &other) const { - return a > other.b; -} - -bool Interval::startsAfterNonDisjoint(const Interval &other) const { - return a > other.a && a <= other.b; // b >= other.b implied -} - -bool Interval::disjoint(const Interval &other) const { - return startsBeforeDisjoint(other) || startsAfterDisjoint(other); -} - -bool Interval::adjacent(const Interval &other) const { - return a == other.b + 1 || b == other.a - 1; -} - -bool Interval::properlyContains(const Interval &other) const { - return other.a >= a && other.b <= b; -} - -Interval Interval::Union(const Interval &other) const { - return Interval(std::min(a, other.a), std::max(b, other.b)); -} - -Interval Interval::intersection(const Interval &other) const { - return Interval(std::max(a, other.a), std::min(b, other.b)); -} - -std::string Interval::toString() const { - return std::to_string(a) + ".." + std::to_string(b); -} diff --git a/src/include/misc/Interval.h b/src/include/misc/Interval.h deleted file mode 100755 index 4ca3cfcd..00000000 --- a/src/include/misc/Interval.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace misc { - - // Helpers to convert certain unsigned symbols (e.g. Token::EOF) to their original numeric value (e.g. -1) - // and vice versa. This is needed mostly for intervals to keep their original order and for toString() - // methods to print the original numeric value (e.g. for tests). - constexpr size_t numericToSymbol(ssize_t v) { return static_cast(v); } - constexpr ssize_t symbolToNumeric(size_t v) { return static_cast(v); } - - /// An immutable inclusive interval a..b - class ANTLR4CPP_PUBLIC Interval final { - public: - static const Interval INVALID; - - // Must stay signed to guarantee the correct sort order. - ssize_t a; - ssize_t b; - - constexpr Interval() : Interval(static_cast(-1), static_cast(-2)) {} - - constexpr explicit Interval(size_t a_, size_t b_) : Interval(symbolToNumeric(a_), symbolToNumeric(b_)) {} - - constexpr Interval(ssize_t a_, ssize_t b_) : a(a_), b(b_) {} - - /// return number of elements between a and b inclusively. x..x is length 1. - /// if b < a, then length is 0. 9..10 has length 2. - constexpr size_t length() const { return b >= a ? static_cast(b - a + 1) : 0; } - - constexpr bool operator==(const Interval &other) const { return a == other.a && b == other.b; } - - size_t hashCode() const; - - /// - /// Does this start completely before other? Disjoint - bool startsBeforeDisjoint(const Interval &other) const; - - /// - /// Does this start at or before other? Nondisjoint - bool startsBeforeNonDisjoint(const Interval &other) const; - - /// - /// Does this.a start after other.b? May or may not be disjoint - bool startsAfter(const Interval &other) const; - - /// - /// Does this start completely after other? Disjoint - bool startsAfterDisjoint(const Interval &other) const; - - /// - /// Does this start after other? NonDisjoint - bool startsAfterNonDisjoint(const Interval &other) const; - - /// - /// Are both ranges disjoint? I.e., no overlap? - bool disjoint(const Interval &other) const; - - /// - /// Are two intervals adjacent such as 0..41 and 42..42? - bool adjacent(const Interval &other) const; - - bool properlyContains(const Interval &other) const; - - /// - /// Return the interval computed from combining this and other - Interval Union(const Interval &other) const; - - /// - /// Return the interval in common between this and o - Interval intersection(const Interval &other) const; - - std::string toString() const; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/misc/IntervalSet.cpp b/src/include/misc/IntervalSet.cpp deleted file mode 100755 index 058d9870..00000000 --- a/src/include/misc/IntervalSet.cpp +++ /dev/null @@ -1,508 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/MurmurHash.h" -#include "Lexer.h" -#include "Exceptions.h" -#include "Vocabulary.h" - -#include "misc/IntervalSet.h" - -using namespace antlr4; -using namespace antlr4::misc; - -IntervalSet const IntervalSet::COMPLETE_CHAR_SET = - IntervalSet::of(Lexer::MIN_CHAR_VALUE, Lexer::MAX_CHAR_VALUE); - -IntervalSet const IntervalSet::EMPTY_SET; - -IntervalSet::IntervalSet() : _intervals() { -} - -IntervalSet::IntervalSet(const IntervalSet &set) : IntervalSet() { - _intervals = set._intervals; -} - -IntervalSet::IntervalSet(IntervalSet&& set) : IntervalSet(std::move(set._intervals)) { -} - -IntervalSet::IntervalSet(std::vector&& intervals) : _intervals(std::move(intervals)) { -} - -IntervalSet& IntervalSet::operator=(const IntervalSet& other) { - _intervals = other._intervals; - return *this; -} - -IntervalSet& IntervalSet::operator=(IntervalSet&& other) { - _intervals = std::move(other._intervals); - return *this; -} - -IntervalSet IntervalSet::of(ssize_t a) { - return IntervalSet({ Interval(a, a) }); -} - -IntervalSet IntervalSet::of(ssize_t a, ssize_t b) { - return IntervalSet({ Interval(a, b) }); -} - -void IntervalSet::clear() { - _intervals.clear(); -} - -void IntervalSet::add(ssize_t el) { - add(el, el); -} - -void IntervalSet::add(ssize_t a, ssize_t b) { - add(Interval(a, b)); -} - -void IntervalSet::add(const Interval &addition) { - if (addition.b < addition.a) { - return; - } - - // find position in list - for (auto iterator = _intervals.begin(); iterator != _intervals.end(); ++iterator) { - Interval r = *iterator; - if (addition == r) { - return; - } - - if (addition.adjacent(r) || !addition.disjoint(r)) { - // next to each other, make a single larger interval - Interval bigger = addition.Union(r); - *iterator = bigger; - - // make sure we didn't just create an interval that - // should be merged with next interval in list - while (iterator + 1 != _intervals.end()) { - Interval next = *++iterator; - if (!bigger.adjacent(next) && bigger.disjoint(next)) { - break; - } - - // if we bump up against or overlap next, merge - iterator = _intervals.erase(iterator);// remove this one - --iterator; // move backwards to what we just set - *iterator = bigger.Union(next); // set to 3 merged ones - // ml: no need to advance iterator, we do that in the next round anyway. ++iterator; // first call to next after previous duplicates the result - } - return; - } - - if (addition.startsBeforeDisjoint(r)) { - // insert before r - //--iterator; - _intervals.insert(iterator, addition); - return; - } - - // if disjoint and after r, a future iteration will handle it - } - - // ok, must be after last interval (and disjoint from last interval) - // just add it - _intervals.push_back(addition); -} - -IntervalSet IntervalSet::Or(const std::vector &sets) { - IntervalSet result; - for (const auto &s : sets) { - result.addAll(s); - } - return result; -} - -IntervalSet& IntervalSet::addAll(const IntervalSet &set) { - // walk set and add each interval - for (auto const& interval : set._intervals) { - add(interval); - } - return *this; -} - -IntervalSet IntervalSet::complement(ssize_t minElement, ssize_t maxElement) const { - return complement(IntervalSet::of(minElement, maxElement)); -} - -IntervalSet IntervalSet::complement(const IntervalSet &vocabulary) const { - return vocabulary.subtract(*this); -} - -IntervalSet IntervalSet::subtract(const IntervalSet &other) const { - return subtract(*this, other); -} - -IntervalSet IntervalSet::subtract(const IntervalSet &left, const IntervalSet &right) { - if (left.isEmpty()) { - return IntervalSet(); - } - - if (right.isEmpty()) { - // right set has no elements; just return the copy of the current set - return left; - } - - IntervalSet result(left); - size_t resultI = 0; - size_t rightI = 0; - while (resultI < result._intervals.size() && rightI < right._intervals.size()) { - Interval &resultInterval = result._intervals[resultI]; - const Interval &rightInterval = right._intervals[rightI]; - - // operation: (resultInterval - rightInterval) and update indexes - - if (rightInterval.b < resultInterval.a) { - rightI++; - continue; - } - - if (rightInterval.a > resultInterval.b) { - resultI++; - continue; - } - - Interval beforeCurrent; - Interval afterCurrent; - if (rightInterval.a > resultInterval.a) { - beforeCurrent = Interval(resultInterval.a, rightInterval.a - 1); - } - - if (rightInterval.b < resultInterval.b) { - afterCurrent = Interval(rightInterval.b + 1, resultInterval.b); - } - - if (beforeCurrent.a > -1) { // -1 is the default value - if (afterCurrent.a > -1) { - // split the current interval into two - result._intervals[resultI] = beforeCurrent; - result._intervals.insert(result._intervals.begin() + resultI + 1, afterCurrent); - resultI++; - rightI++; - } else { - // replace the current interval - result._intervals[resultI] = beforeCurrent; - resultI++; - } - } else { - if (afterCurrent.a > -1) { - // replace the current interval - result._intervals[resultI] = afterCurrent; - rightI++; - } else { - // remove the current interval (thus no need to increment resultI) - result._intervals.erase(result._intervals.begin() + resultI); - } - } - } - - // If rightI reached right.intervals.size(), no more intervals to subtract from result. - // If resultI reached result.intervals.size(), we would be subtracting from an empty set. - // Either way, we are done. - return result; -} - -IntervalSet IntervalSet::Or(const IntervalSet &a) const { - IntervalSet result; - result.addAll(*this); - result.addAll(a); - return result; -} - -IntervalSet IntervalSet::And(const IntervalSet &other) const { - IntervalSet intersection; - size_t i = 0; - size_t j = 0; - - // iterate down both interval lists looking for nondisjoint intervals - while (i < _intervals.size() && j < other._intervals.size()) { - Interval mine = _intervals[i]; - Interval theirs = other._intervals[j]; - - if (mine.startsBeforeDisjoint(theirs)) { - // move this iterator looking for interval that might overlap - i++; - } else if (theirs.startsBeforeDisjoint(mine)) { - // move other iterator looking for interval that might overlap - j++; - } else if (mine.properlyContains(theirs)) { - // overlap, add intersection, get next theirs - intersection.add(mine.intersection(theirs)); - j++; - } else if (theirs.properlyContains(mine)) { - // overlap, add intersection, get next mine - intersection.add(mine.intersection(theirs)); - i++; - } else if (!mine.disjoint(theirs)) { - // overlap, add intersection - intersection.add(mine.intersection(theirs)); - - // Move the iterator of lower range [a..b], but not - // the upper range as it may contain elements that will collide - // with the next iterator. So, if mine=[0..115] and - // theirs=[115..200], then intersection is 115 and move mine - // but not theirs as theirs may collide with the next range - // in thisIter. - // move both iterators to next ranges - if (mine.startsAfterNonDisjoint(theirs)) { - j++; - } else if (theirs.startsAfterNonDisjoint(mine)) { - i++; - } - } - } - - return intersection; -} - -bool IntervalSet::contains(size_t el) const { - return contains(symbolToNumeric(el)); -} - -bool IntervalSet::contains(ssize_t el) const { - if (_intervals.empty() || el < _intervals.front().a || el > _intervals.back().b) { - return false; - } - - return std::binary_search(_intervals.begin(), _intervals.end(), Interval(el, el), [](const Interval &lhs, const Interval &rhs) { - return lhs.b < rhs.a; - }); -} - -bool IntervalSet::isEmpty() const { - return _intervals.empty(); -} - -ssize_t IntervalSet::getSingleElement() const { - if (_intervals.size() == 1) { - if (_intervals[0].a == _intervals[0].b) { - return _intervals[0].a; - } - } - - return Token::INVALID_TYPE; // XXX: this value is 0, but 0 is a valid interval range, how can that work? -} - -ssize_t IntervalSet::getMaxElement() const { - if (_intervals.empty()) { - return Token::INVALID_TYPE; - } - - return _intervals.back().b; -} - -ssize_t IntervalSet::getMinElement() const { - if (_intervals.empty()) { - return Token::INVALID_TYPE; - } - - return _intervals.front().a; -} - -std::vector const& IntervalSet::getIntervals() const { - return _intervals; -} - -size_t IntervalSet::hashCode() const { - size_t hash = MurmurHash::initialize(); - for (const auto &interval : _intervals) { - hash = MurmurHash::update(hash, interval.a); - hash = MurmurHash::update(hash, interval.b); - } - - return MurmurHash::finish(hash, _intervals.size() * 2); -} - -bool IntervalSet::operator == (const IntervalSet &other) const { - if (_intervals.empty() && other._intervals.empty()) - return true; - - if (_intervals.size() != other._intervals.size()) - return false; - - return std::equal(_intervals.begin(), _intervals.end(), other._intervals.begin()); -} - -std::string IntervalSet::toString() const { - return toString(false); -} - -std::string IntervalSet::toString(bool elemAreChar) const { - if (_intervals.empty()) { - return "{}"; - } - - std::stringstream ss; - size_t effectiveSize = size(); - if (effectiveSize > 1) { - ss << "{"; - } - - bool firstEntry = true; - for (const auto &interval : _intervals) { - if (!firstEntry) - ss << ", "; - firstEntry = false; - - ssize_t a = interval.a; - ssize_t b = interval.b; - if (a == b) { - if (a == -1) { - ss << ""; - } else if (elemAreChar) { - ss << "'" << static_cast(a) << "'"; - } else { - ss << a; - } - } else { - if (elemAreChar) { - ss << "'" << static_cast(a) << "'..'" << static_cast(b) << "'"; - } else { - ss << a << ".." << b; - } - } - } - if (effectiveSize > 1) { - ss << "}"; - } - - return ss.str(); -} - -std::string IntervalSet::toString(const dfa::Vocabulary &vocabulary) const { - if (_intervals.empty()) { - return "{}"; - } - - std::stringstream ss; - size_t effectiveSize = size(); - if (effectiveSize > 1) { - ss << "{"; - } - - bool firstEntry = true; - for (const auto &interval : _intervals) { - if (!firstEntry) - ss << ", "; - firstEntry = false; - - ssize_t a = interval.a; - ssize_t b = interval.b; - if (a == b) { - ss << elementName(vocabulary, a); - } else { - for (ssize_t i = a; i <= b; i++) { - if (i > a) { - ss << ", "; - } - ss << elementName(vocabulary, i); - } - } - } - if (effectiveSize > 1) { - ss << "}"; - } - - return ss.str(); -} - -std::string IntervalSet::elementName(const dfa::Vocabulary &vocabulary, ssize_t a) const { - if (a == -1) { - return ""; - } else if (a == -2) { - return ""; - } else { - return vocabulary.getDisplayName(a); - } -} - -size_t IntervalSet::size() const { - size_t result = 0; - for (const auto &interval : _intervals) { - result += size_t(interval.b - interval.a + 1); - } - return result; -} - -std::vector IntervalSet::toList() const { - std::vector result; - for (const auto &interval : _intervals) { - ssize_t a = interval.a; - ssize_t b = interval.b; - for (ssize_t v = a; v <= b; v++) { - result.push_back(v); - } - } - return result; -} - -std::set IntervalSet::toSet() const { - std::set result; - for (const auto &interval : _intervals) { - ssize_t a = interval.a; - ssize_t b = interval.b; - for (ssize_t v = a; v <= b; v++) { - result.insert(v); - } - } - return result; -} - -ssize_t IntervalSet::get(size_t i) const { - size_t index = 0; - for (const auto &interval : _intervals) { - ssize_t a = interval.a; - ssize_t b = interval.b; - for (ssize_t v = a; v <= b; v++) { - if (index == i) { - return v; - } - index++; - } - } - return -1; -} - -void IntervalSet::remove(size_t el) { - remove(symbolToNumeric(el)); -} - -void IntervalSet::remove(ssize_t el) { - for (size_t i = 0; i < _intervals.size(); ++i) { - Interval &interval = _intervals[i]; - ssize_t a = interval.a; - ssize_t b = interval.b; - if (el < a) { - break; // list is sorted and el is before this interval; not here - } - - // if whole interval x..x, rm - if (el == a && el == b) { - _intervals.erase(_intervals.begin() + (long)i); - break; - } - // if on left edge x..b, adjust left - if (el == a) { - interval.a++; - break; - } - // if on right edge a..x, adjust right - if (el == b) { - interval.b--; - break; - } - // if in middle a..x..b, split interval - if (el > a && el < b) { // found in this interval - ssize_t oldb = interval.b; - interval.b = el - 1; // [a..x-1] - add(el + 1, oldb); // add [x+1..b] - - break; // ml: not in the Java code but I believe we also should stop searching here, as we found x. - } - } -} diff --git a/src/include/misc/IntervalSet.h b/src/include/misc/IntervalSet.h deleted file mode 100755 index 7f24b781..00000000 --- a/src/include/misc/IntervalSet.h +++ /dev/null @@ -1,190 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "misc/Interval.h" -#include "Exceptions.h" - -namespace antlr4 { -namespace misc { - - /** - * This class implements the {@link IntSet} backed by a sorted array of - * non-overlapping intervals. It is particularly efficient for representing - * large collections of numbers, where the majority of elements appear as part - * of a sequential range of numbers that are all part of the set. For example, - * the set { 1, 2, 3, 4, 7, 8 } may be represented as { [1, 4], [7, 8] }. - * - *

- * This class is able to represent sets containing any combination of values in - * the range {@link Integer#MIN_VALUE} to {@link Integer#MAX_VALUE} - * (inclusive).

- */ - class ANTLR4CPP_PUBLIC IntervalSet final { - public: - static IntervalSet const COMPLETE_CHAR_SET; - static IntervalSet const EMPTY_SET; - - private: - /// The list of sorted, disjoint intervals. - std::vector _intervals; - - explicit IntervalSet(std::vector&& intervals); - - public: - IntervalSet(); - IntervalSet(IntervalSet const& set); - IntervalSet(IntervalSet&& set); - - template - IntervalSet(int, T1 t1, T_NEXT&&... next) : IntervalSet() { - // The first int argument is an ignored count for compatibility - // with the previous varargs based interface. - addItems(t1, std::forward(next)...); - } - - IntervalSet& operator=(IntervalSet const& set); - IntervalSet& operator=(IntervalSet&& set); - - /// Create a set with a single element, el. - static IntervalSet of(ssize_t a); - - /// Create a set with all ints within range [a..b] (inclusive) - static IntervalSet of(ssize_t a, ssize_t b); - - void clear(); - - /// Add a single element to the set. An isolated element is stored - /// as a range el..el. - void add(ssize_t el); - - /// Add interval; i.e., add all integers from a to b to set. - /// If b &sets); - - // Copy on write so we can cache a..a intervals and sets of that. - void add(const Interval &addition); - IntervalSet& addAll(const IntervalSet &set); - - template - void addItems(T1 t1, T_NEXT&&... next) { - add(t1); - addItems(std::forward(next)...); - } - - IntervalSet complement(ssize_t minElement, ssize_t maxElement) const; - - /// Given the set of possible values (rather than, say UNICODE or MAXINT), - /// return a new set containing all elements in vocabulary, but not in - /// this. The computation is (vocabulary - this). - /// - /// 'this' is assumed to be either a subset or equal to vocabulary. - IntervalSet complement(const IntervalSet &vocabulary) const; - - /// Compute this-other via this&~other. - /// Return a new set containing all elements in this but not in other. - /// other is assumed to be a subset of this; - /// anything that is in other but not in this will be ignored. - IntervalSet subtract(const IntervalSet &other) const; - - /** - * Compute the set difference between two interval sets. The specific - * operation is {@code left - right}. If either of the input sets is - * {@code null}, it is treated as though it was an empty set. - */ - static IntervalSet subtract(const IntervalSet &left, const IntervalSet &right); - - IntervalSet Or(const IntervalSet &a) const; - - /// Return a new set with the intersection of this set with other. Because - /// the intervals are sorted, we can use an iterator for each list and - /// just walk them together. This is roughly O(min(n,m)) for interval - /// list lengths n and m. - IntervalSet And(const IntervalSet &other) const; - - /// Is el in any range of this set? - bool contains(size_t el) const; // For mapping of e.g. Token::EOF to -1 etc. - bool contains(ssize_t el) const; - - /// return true if this set has no members - bool isEmpty() const; - - /// If this set is a single integer, return it otherwise Token.INVALID_TYPE. - ssize_t getSingleElement() const; - - /** - * Returns the maximum value contained in the set. - * - * @return the maximum value contained in the set. If the set is empty, this - * method returns {@link Token#INVALID_TYPE}. - */ - ssize_t getMaxElement() const; - - /** - * Returns the minimum value contained in the set. - * - * @return the minimum value contained in the set. If the set is empty, this - * method returns {@link Token#INVALID_TYPE}. - */ - ssize_t getMinElement() const; - - /// - /// Return a list of Interval objects. - std::vector const& getIntervals() const; - - size_t hashCode() const; - - /// Are two IntervalSets equal? Because all intervals are sorted - /// and disjoint, equals is a simple linear walk over both lists - /// to make sure they are the same. - bool operator == (const IntervalSet &other) const; - std::string toString() const; - std::string toString(bool elemAreChar) const; - - std::string toString(const dfa::Vocabulary &vocabulary) const; - - protected: - std::string elementName(const dfa::Vocabulary &vocabulary, ssize_t a) const; - - public: - size_t size() const; - std::vector toList() const; - std::set toSet() const; - - /// Get the ith element of ordered set. Used only by RandomPhrase so - /// don't bother to implement if you're not doing that for a new - /// ANTLR code gen target. - ssize_t get(size_t i) const; - void remove(size_t el); // For mapping of e.g. Token::EOF to -1 etc. - void remove(ssize_t el); - - private: - void addItems() { /* No-op */ } - }; - -} // namespace atn -} // namespace antlr4 - -// Hash function for IntervalSet. - -namespace std { - using antlr4::misc::IntervalSet; - - template <> struct hash - { - size_t operator() (const IntervalSet &x) const - { - return x.hashCode(); - } - }; -} diff --git a/src/include/misc/MurmurHash.cpp b/src/include/misc/MurmurHash.cpp deleted file mode 100755 index 09072c9f..00000000 --- a/src/include/misc/MurmurHash.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include -#include -#include - -#include "misc/MurmurHash.h" - -using namespace antlr4::misc; - -// A variation of the MurmurHash3 implementation (https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp) -// Here we unrolled the loop used there into individual calls to update(), as we usually hash object fields -// instead of entire buffers. - -// Platform-specific functions and macros - -// Microsoft Visual Studio - -#if defined(_MSC_VER) - -#include - -#define ROTL32(x,y) _rotl(x,y) -#define ROTL64(x,y) _rotl64(x,y) - -#elif ANTLR4CPP_HAVE_BUILTIN(__builtin_rotateleft32) && ANTLR4CPP_HAVE_BUILTIN(__builtin_rotateleft64) - -#define ROTL32(x, y) __builtin_rotateleft32(x, y) -#define ROTL64(x, y) __builtin_rotateleft64(x, y) - -#else // defined(_MSC_VER) - -// Other compilers - -namespace { - -constexpr uint32_t ROTL32(uint32_t x, int r) { - return (x << r) | (x >> (32 - r)); -} -constexpr uint64_t ROTL64(uint64_t x, int r) { - return (x << r) | (x >> (64 - r)); -} - -} - -#endif // !defined(_MSC_VER) - -#if SIZE_MAX == UINT64_MAX - -size_t MurmurHash::update(size_t hash, size_t value) { - size_t k1 = value; - k1 *= UINT64_C(0x87c37b91114253d5); - k1 = ROTL64(k1, 31); - k1 *= UINT64_C(0x4cf5ad432745937f); - - hash ^= k1; - hash = ROTL64(hash, 27); - hash = hash * 5 + UINT64_C(0x52dce729); - - return hash; -} - -size_t MurmurHash::finish(size_t hash, size_t entryCount) { - hash ^= entryCount * 8; - hash ^= hash >> 33; - hash *= UINT64_C(0xff51afd7ed558ccd); - hash ^= hash >> 33; - hash *= UINT64_C(0xc4ceb9fe1a85ec53); - hash ^= hash >> 33; - return hash; -} - -#elif SIZE_MAX == UINT32_MAX - -size_t MurmurHash::update(size_t hash, size_t value) { - size_t k1 = value; - k1 *= UINT32_C(0xCC9E2D51); - k1 = ROTL32(k1, 15); - k1 *= UINT32_C(0x1B873593); - - hash ^= k1; - hash = ROTL32(hash, 13); - hash = hash * 5 + UINT32_C(0xE6546B64); - - return hash; -} - -size_t MurmurHash::finish(size_t hash, size_t entryCount) { - hash ^= entryCount * 4; - hash ^= hash >> 16; - hash *= UINT32_C(0x85EBCA6B); - hash ^= hash >> 13; - hash *= UINT32_C(0xC2B2AE35); - hash ^= hash >> 16; - return hash; -} - -#else -#error "Expected sizeof(size_t) to be 4 or 8." -#endif - -size_t MurmurHash::update(size_t hash, const void *data, size_t size) { - size_t value; - const uint8_t *bytes = static_cast(data); - while (size >= sizeof(size_t)) { - std::memcpy(&value, bytes, sizeof(size_t)); - hash = update(hash, value); - bytes += sizeof(size_t); - size -= sizeof(size_t); - } - if (size != 0) { - value = 0; - std::memcpy(&value, bytes, size); - hash = update(hash, value); - } - return hash; -} diff --git a/src/include/misc/MurmurHash.h b/src/include/misc/MurmurHash.h deleted file mode 100755 index 940ee671..00000000 --- a/src/include/misc/MurmurHash.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include -#include - -#include "antlr4-common.h" - -namespace antlr4 { -namespace misc { - - class ANTLR4CPP_PUBLIC MurmurHash final { - private: - static constexpr size_t DEFAULT_SEED = 0; - - /// Initialize the hash using the default seed value. - /// Returns the intermediate hash value. - public: - static size_t initialize() { return initialize(DEFAULT_SEED); } - - /// Initialize the hash using the specified seed. - static size_t initialize(size_t seed) { return seed; } - - /// Update the intermediate hash value for the next input {@code value}. - /// the intermediate hash value - /// the value to add to the current hash - /// Returns the updated intermediate hash value. - static size_t update(size_t hash, size_t value); - - /** - * Update the intermediate hash value for the next input {@code value}. - * - * @param hash the intermediate hash value - * @param value the value to add to the current hash - * @return the updated intermediate hash value - */ - template - static size_t update(size_t hash, Ref const& value) { - return update(hash, value != nullptr ? value->hashCode() : 0); - } - - template - static size_t update(size_t hash, T *value) { - return update(hash, value != nullptr ? value->hashCode() : 0); - } - - static size_t update(size_t hash, const void *data, size_t size); - - template - static size_t update(size_t hash, const T *data, size_t size) { - return update(hash, static_cast(data), size * sizeof(std::remove_reference_t)); - } - - /// - /// Apply the final computation steps to the intermediate value {@code hash} - /// to form the final result of the MurmurHash 3 hash function. - /// - /// the intermediate hash value - /// the number of calls to update() before calling finish() - /// the final hash result - static size_t finish(size_t hash, size_t entryCount); - - /// Utility function to compute the hash code of an array using the MurmurHash3 algorithm. - /// - /// @param the array element type - /// the array data - /// the seed for the MurmurHash algorithm - /// the hash code of the data - template // where T is C array type - static size_t hashCode(const std::vector> &data, size_t seed = DEFAULT_SEED) { - size_t hash = initialize(seed); - for (auto &entry : data) { - hash = update(hash, entry); - } - return finish(hash, data.size()); - } - - static size_t hashCode(const void *data, size_t size, size_t seed = DEFAULT_SEED) { - size_t hash = initialize(seed); - hash = update(hash, data, size); - return finish(hash, size); - } - - template - static size_t hashCode(const T *data, size_t size, size_t seed = DEFAULT_SEED) { - return hashCode(static_cast(data), size * sizeof(std::remove_reference_t), seed); - } - - private: - MurmurHash() = delete; - - MurmurHash(const MurmurHash&) = delete; - - MurmurHash& operator=(const MurmurHash&) = delete; - }; - -} // namespace atn -} // namespace antlr4 diff --git a/src/include/misc/Predicate.cpp b/src/include/misc/Predicate.cpp deleted file mode 100644 index c35f1921..00000000 --- a/src/include/misc/Predicate.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "misc/Predicate.h" - -antlr4::misc::Predicate::~Predicate() { -} diff --git a/src/include/misc/Predicate.h b/src/include/misc/Predicate.h deleted file mode 100755 index 1032d53f..00000000 --- a/src/include/misc/Predicate.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace misc { - - class ANTLR4CPP_PUBLIC Predicate { - public: - virtual ~Predicate(); - - virtual bool test(tree::ParseTree *t) = 0; - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/support/Any.cpp b/src/include/support/Any.cpp deleted file mode 100644 index a1ed50d4..00000000 --- a/src/include/support/Any.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "Any.h" - -using namespace antlrcpp; diff --git a/src/include/support/Any.h b/src/include/support/Any.h deleted file mode 100644 index fa5df589..00000000 --- a/src/include/support/Any.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -// A standard C++ class loosely modeled after boost::Any. - -#pragma once - -#include "antlr4-common.h" - -namespace antlrcpp { - - using Any = std::any; - -} // namespace antlrcpp diff --git a/src/include/support/Arrays.cpp b/src/include/support/Arrays.cpp deleted file mode 100644 index b3c4f94f..00000000 --- a/src/include/support/Arrays.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/ParseTree.h" -#include "Exceptions.h" - -#include "support/Arrays.h" - -using namespace antlrcpp; - -std::string Arrays::listToString(const std::vector &list, const std::string &separator) -{ - std::stringstream ss; - bool firstEntry = true; - - ss << '['; - for (const auto &entry : list) { - ss << entry; - if (firstEntry) { - ss << separator; - firstEntry = false; - } - } - - ss << ']'; - return ss.str(); -} - -template <> -std::string Arrays::toString(const std::vector &source) { - std::string result = "["; - bool firstEntry = true; - for (auto *value : source) { - result += value->toStringTree(); - if (firstEntry) { - result += ", "; - firstEntry = false; - } - } - return result + "]"; -} diff --git a/src/include/support/Arrays.h b/src/include/support/Arrays.h deleted file mode 100644 index 04b852d9..00000000 --- a/src/include/support/Arrays.h +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlrcpp { - - class ANTLR4CPP_PUBLIC Arrays { - public: - - static std::string listToString(const std::vector &list, const std::string &separator); - - template - static bool equals(const std::vector &a, const std::vector &b) { - if (a.size() != b.size()) - return false; - - for (size_t i = 0; i < a.size(); ++i) - if (!(a[i] == b[i])) - return false; - - return true; - } - - template - static bool equals(const std::vector &a, const std::vector &b) { - if (a.size() != b.size()) - return false; - - for (size_t i = 0; i < a.size(); ++i) { - if (!a[i] && !b[i]) - continue; - if (!a[i] || !b[i]) - return false; - if (a[i] == b[i]) - continue; - - if (!(*a[i] == *b[i])) - return false; - } - - return true; - } - - template - static bool equals(const std::vector> &a, const std::vector> &b) { - if (a.size() != b.size()) - return false; - - for (size_t i = 0; i < a.size(); ++i) { - if (!a[i] && !b[i]) - continue; - if (!a[i] || !b[i]) - return false; - if (a[i] == b[i]) - continue; - - if (!(*a[i] == *b[i])) - return false; - } - - return true; - } - - template - static bool equals(const std::vector> &a, const std::vector> &b) { - if (a.size() != b.size()) - return false; - - for (size_t i = 0; i < a.size(); ++i) { - if (!a[i] && !b[i]) - continue; - if (!a[i] || !b[i]) - return false; - if (a[i] == b[i]) - continue; - - if (!(*a[i] == *b[i])) - return false; - } - - return true; - } - - template - static std::string toString(const std::vector &source) { - std::string result = "["; - bool firstEntry = true; - for (auto &value : source) { - result += value.toString(); - if (firstEntry) { - result += ", "; - firstEntry = false; - } - } - return result + "]"; - } - - template - static std::string toString(const std::vector> &source) { - std::string result = "["; - bool firstEntry = true; - for (auto &value : source) { - result += value->toString(); - if (firstEntry) { - result += ", "; - firstEntry = false; - } - } - return result + "]"; - } - - template - static std::string toString(const std::vector> &source) { - std::string result = "["; - bool firstEntry = true; - for (auto &value : source) { - result += value->toString(); - if (firstEntry) { - result += ", "; - firstEntry = false; - } - } - return result + "]"; - } - - template - static std::string toString(const std::vector &source) { - std::string result = "["; - bool firstEntry = true; - for (auto value : source) { - result += value->toString(); - if (firstEntry) { - result += ", "; - firstEntry = false; - } - } - return result + "]"; - } - - }; - - template <> - std::string Arrays::toString(const std::vector &source); -} diff --git a/src/include/support/BitSet.h b/src/include/support/BitSet.h deleted file mode 100644 index bb30364b..00000000 --- a/src/include/support/BitSet.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlrcpp { - - class ANTLR4CPP_PUBLIC BitSet : public std::bitset<2048> { - public: - size_t nextSetBit(size_t pos) const { - for (size_t i = pos; i < size(); i++){ - if (test(i)) { - return i; - } - } - - return INVALID_INDEX; - } - - // 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 << "{"; - size_t total = obj.count(); - for (size_t i = 0; i < obj.size(); i++){ - if (obj.test(i)){ - os << i; - --total; - if (total > 1){ - os << ", "; - } - } - } - - os << "}"; - return os; - } - - static std::string subStringRepresentation(const std::vector::iterator &begin, - const std::vector::iterator &end) { - std::string result; - std::vector::iterator vectorIterator; - - for (vectorIterator = begin; vectorIterator != end; vectorIterator++) { - result += vectorIterator->toString(); - } - // Grab the end - result += end->toString(); - - return result; - } - - std::string toString() const { - std::stringstream stream; - stream << "{"; - bool valueAdded = false; - for (size_t i = 0; i < size(); ++i){ - if (test(i)){ - if (valueAdded) { - stream << ", "; - } - stream << i; - valueAdded = true; - } - } - - stream << "}"; - return stream.str(); - } - - }; -} diff --git a/src/include/support/CPPUtils.cpp b/src/include/support/CPPUtils.cpp deleted file mode 100755 index 95321b3d..00000000 --- a/src/include/support/CPPUtils.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "support/CPPUtils.h" - -namespace antlrcpp { - - std::string join(const std::vector &strings, const std::string &separator) { - std::string str; - bool firstItem = true; - for (const std::string &s : strings) { - if (!firstItem) { - str.append(separator); - } - firstItem = false; - str.append(s); - } - return str; - } - - std::map toMap(const std::vector &keys) { - std::map result; - for (size_t i = 0; i < keys.size(); ++i) { - result.insert({ keys[i], i }); - } - return result; - } - - std::string escapeWhitespace(std::string str, bool escapeSpaces) { - std::string result; - for (auto c : str) { - switch (c) { - case '\n': - result += "\\n"; - break; - - case '\r': - result += "\\r"; - break; - - case '\t': - result += "\\t"; - break; - - case ' ': - if (escapeSpaces) { - result += "\u00B7"; - break; - } - result += c; - break; - - default: - result += c; - break; - } - } - - return result; - } - - std::string toHexString(const int t) { - std::stringstream stream; - stream << std::uppercase << std::hex << t; - return stream.str(); - } - - std::string arrayToString(const std::vector &data) { - std::string answer; - size_t toReserve = 0; - for (const auto &sub : data) { - toReserve += sub.size(); - } - answer.reserve(toReserve); - for (const auto &sub: data) { - answer.append(sub); - } - return answer; - } - - std::string replaceString(const std::string &s, const std::string &from, const std::string &to) { - std::string::size_type p; - std::string ss, res; - - ss = s; - p = ss.find(from); - while (p != std::string::npos) { - if (p > 0) - res.append(ss.substr(0, p)).append(to); - else - res.append(to); - ss = ss.substr(p + from.size()); - p = ss.find(from); - } - res.append(ss); - - return res; - } - - std::vector split(const std::string &s, const std::string &sep, int count) { - std::vector parts; - std::string ss = s; - - std::string::size_type p; - - if (s.empty()) - return parts; - - if (count == 0) - count= -1; - - p = ss.find(sep); - while (!ss.empty() && p != std::string::npos && (count < 0 || count > 0)) { - parts.push_back(ss.substr(0, p)); - ss = ss.substr(p+sep.size()); - - --count; - p = ss.find(sep); - } - parts.push_back(ss); - - return parts; - } - - //-------------------------------------------------------------------------------------------------- - - // Debugging helper. Adds indentation to all lines in the given string. - std::string indent(const std::string &s, const std::string &indentation, bool includingFirst) { - std::vector parts = split(s, "\n", -1); - for (size_t i = 0; i < parts.size(); ++i) { - if (i == 0 && !includingFirst) - continue; - parts[i].insert(0, indentation); - } - - return join(parts, "\n"); - } - - //-------------------------------------------------------------------------------------------------- - - // Recursively get the error from a, possibly nested, exception. -#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026 - // No nested exceptions before VS 2015. - template - std::exception_ptr get_nested(const T &/*e*/) { - try { - return nullptr; - } - catch (const std::bad_cast &) { - return nullptr; - } - } -#else - template - std::exception_ptr get_nested(const T &e) { - try { - auto nested = dynamic_cast(e); - return nested.nested_ptr(); - } - catch (const std::bad_cast &) { - return nullptr; - } - } -#endif - - std::string what(std::exception_ptr eptr) { - if (!eptr) { - throw std::bad_exception(); - } - - std::string result; - std::size_t nestCount = 0; - - next: { - try { - std::exception_ptr yeptr; - std::swap(eptr, yeptr); - std::rethrow_exception(yeptr); - } - catch (const std::exception &e) { - result += e.what(); - eptr = get_nested(e); - } - catch (const std::string &e) { - result += e; - } - catch (const char *e) { - result += e; - } - catch (...) { - result += "cannot be determined"; - } - - if (eptr) { - result += " ("; - ++nestCount; - goto next; - } - } - - result += std::string(nestCount, ')'); - return result; - } - -} // namespace antlrcpp diff --git a/src/include/support/CPPUtils.h b/src/include/support/CPPUtils.h deleted file mode 100644 index 2eb1a360..00000000 --- a/src/include/support/CPPUtils.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlrcpp { - - ANTLR4CPP_PUBLIC std::string join(const std::vector &strings, const std::string &separator); - ANTLR4CPP_PUBLIC std::map toMap(const std::vector &keys); - ANTLR4CPP_PUBLIC std::string escapeWhitespace(std::string str, bool escapeSpaces); - ANTLR4CPP_PUBLIC std::string toHexString(const int t); - ANTLR4CPP_PUBLIC std::string arrayToString(const std::vector &data); - ANTLR4CPP_PUBLIC std::string replaceString(const std::string &s, const std::string &from, const std::string &to); - ANTLR4CPP_PUBLIC std::vector split(const std::string &s, const std::string &sep, int count); - ANTLR4CPP_PUBLIC std::string indent(const std::string &s, const std::string &indentation, bool includingFirst = true); - - // Using RAII + a lambda to implement a "finally" replacement. - template - struct FinalAction { - FinalAction(OnEnd f) : _cleanUp { std::move(f) } {} - FinalAction(FinalAction &&other) : - _cleanUp(std::move(other._cleanUp)), _enabled(other._enabled) { - other._enabled = false; // Don't trigger the lambda after ownership has moved. - } - ~FinalAction() { if (_enabled) _cleanUp(); } - - void disable() { _enabled = false; } - private: - OnEnd _cleanUp; - bool _enabled {true}; - }; - - template - FinalAction finally(OnEnd f) { - return FinalAction(std::move(f)); - } - - // Convenience functions to avoid lengthy dynamic_cast() != nullptr checks in many places. - template - inline bool is(T2 *obj) { // For pointer types. - return dynamic_cast::type>(obj) != nullptr; - } - - template - inline bool is(Ref const& obj) { // For shared pointers. - return dynamic_cast(obj.get()) != nullptr; - } - - template - std::string toString(const T &o) { - std::stringstream ss; - // typeid gives the mangled class name, but that's all what's possible - // in a portable way. - ss << typeid(o).name() << "@" << std::hex << reinterpret_cast(&o); - return ss.str(); - } - - // Get the error text from an exception pointer or the current exception. - ANTLR4CPP_PUBLIC std::string what(std::exception_ptr eptr = std::current_exception()); - -} // namespace antlrcpp diff --git a/src/include/support/Casts.h b/src/include/support/Casts.h deleted file mode 100644 index 2ded955d..00000000 --- a/src/include/support/Casts.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 2012-2021 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include -#include -#include - -namespace antlrcpp { - - template - To downCast(From* from) { - static_assert(std::is_pointer_v, "Target type not a pointer."); - static_assert(std::is_base_of_v>, "Target type not derived from source type."); - #if !defined(__GNUC__) || defined(__GXX_RTTI) - assert(from == nullptr || dynamic_cast(from) != nullptr); - #endif - return static_cast(from); - } - - template - To downCast(From& from) { - static_assert(std::is_lvalue_reference_v, "Target type not a lvalue reference."); - static_assert(std::is_base_of_v>, "Target type not derived from source type."); - #if !defined(__GNUC__) || defined(__GXX_RTTI) - assert(dynamic_cast>>(std::addressof(from)) != nullptr); - #endif - return static_cast(from); - } - -} diff --git a/src/include/support/Declarations.h b/src/include/support/Declarations.h deleted file mode 100644 index 8e960676..00000000 --- a/src/include/support/Declarations.h +++ /dev/null @@ -1,161 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -namespace antlr4 { - class ANTLRErrorListener; - class ANTLRErrorStrategy; - class ANTLRFileStream; - class ANTLRInputStream; - class BailErrorStrategy; - class BaseErrorListener; - class BufferedTokenStream; - class CharStream; - class CommonToken; - class CommonTokenFactory; - class CommonTokenStream; - class ConsoleErrorListener; - class DefaultErrorStrategy; - class DiagnosticErrorListener; - class EmptyStackException; - class FailedPredicateException; - class IllegalArgumentException; - class IllegalStateException; - class InputMismatchException; - class IntStream; - class InterpreterRuleContext; - class Lexer; - class LexerInterpreter; - class LexerNoViableAltException; - class ListTokenSource; - class NoSuchElementException; - class NoViableAltException; - class NullPointerException; - class ParseCancellationException; - class Parser; - class ParserInterpreter; - class ParserRuleContext; - class ProxyErrorListener; - class RecognitionException; - class Recognizer; - class RuleContext; - class Token; - template class TokenFactory; - class TokenSource; - class TokenStream; - class TokenStreamRewriter; - class UnbufferedCharStream; - class UnbufferedTokenStream; - class WritableToken; - - namespace misc { - class InterpreterDataReader; - class Interval; - class IntervalSet; - class MurmurHash; - class Utils; - class Predicate; - } - namespace atn { - class ATN; - class ATNConfig; - class ATNConfigSet; - class ATNDeserializationOptions; - class ATNDeserializer; - class ATNSerializer; - class ATNSimulator; - class ATNState; - enum class ATNType; - class ActionTransition; - class ArrayPredictionContext; - class AtomTransition; - class BasicBlockStartState; - class BasicState; - class BlockEndState; - class BlockStartState; - class DecisionState; - class EpsilonTransition; - class LL1Analyzer; - class LexerAction; - class LexerActionExecutor; - class LexerATNConfig; - class LexerATNSimulator; - class LexerMoreAction; - class LexerPopModeAction; - class LexerSkipAction; - class LookaheadEventInfo; - class LoopEndState; - class NotSetTransition; - class OrderedATNConfigSet; - class ParseInfo; - class ParserATNSimulator; - class PlusBlockStartState; - class PlusLoopbackState; - class PrecedencePredicateTransition; - class PredicateTransition; - class PredictionContext; - enum class PredictionMode; - class PredictionModeClass; - class RangeTransition; - class RuleStartState; - class RuleStopState; - class RuleTransition; - class SemanticContext; - class SetTransition; - class SingletonPredictionContext; - class StarBlockStartState; - class StarLoopEntryState; - class StarLoopbackState; - class TokensStartState; - class Transition; - class WildcardTransition; - } - namespace dfa { - class DFA; - class DFASerializer; - class DFAState; - class LexerDFASerializer; - class Vocabulary; - } - namespace tree { - class AbstractParseTreeVisitor; - class ErrorNode; - class ErrorNodeImpl; - class ParseTree; - class ParseTreeListener; - template class ParseTreeProperty; - class ParseTreeVisitor; - class ParseTreeWalker; - class SyntaxTree; - class TerminalNode; - class TerminalNodeImpl; - class Tree; - class Trees; - - namespace pattern { - class Chunk; - class ParseTreeMatch; - class ParseTreePattern; - class ParseTreePatternMatcher; - class RuleTagToken; - class TagChunk; - class TextChunk; - class TokenTagToken; - } - - namespace xpath { - class XPath; - class XPathElement; - class XPathLexerErrorListener; - class XPathRuleAnywhereElement; - class XPathRuleElement; - class XPathTokenAnywhereElement; - class XPathTokenElement; - class XPathWildcardAnywhereElement; - class XPathWildcardElement; - } - } -} diff --git a/src/include/support/StringUtils.cpp b/src/include/support/StringUtils.cpp deleted file mode 100644 index 9ee274c8..00000000 --- a/src/include/support/StringUtils.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "support/StringUtils.h" - -namespace antlrcpp { - - std::string escapeWhitespace(std::string_view in) { - std::string out; - escapeWhitespace(out, in); - out.shrink_to_fit(); - return out; - } - - std::string& escapeWhitespace(std::string& out, std::string_view in) { - out.reserve(in.size()); // Best case, no escaping. - for (const auto &c : in) { - switch (c) { - case '\t': - out.append("\\t"); - break; - case '\r': - out.append("\\r"); - break; - case '\n': - out.append("\\n"); - break; - default: - out.push_back(c); - break; - } - } - return out; - } - -} // namespace antrlcpp diff --git a/src/include/support/StringUtils.h b/src/include/support/StringUtils.h deleted file mode 100644 index aee0d46d..00000000 --- a/src/include/support/StringUtils.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlrcpp { - - ANTLR4CPP_PUBLIC std::string escapeWhitespace(std::string_view in); - - ANTLR4CPP_PUBLIC std::string& escapeWhitespace(std::string& out, std::string_view in); - -} diff --git a/src/include/support/Unicode.h b/src/include/support/Unicode.h deleted file mode 100644 index f0f84375..00000000 --- a/src/include/support/Unicode.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 2021 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlrcpp { - - class ANTLR4CPP_PUBLIC Unicode final { - public: - static constexpr char32_t REPLACEMENT_CHARACTER = 0xfffd; - - static constexpr bool isValid(char32_t codePoint) { - return codePoint < 0xd800 || (codePoint > 0xdfff && codePoint <= 0x10ffff); - } - - private: - Unicode() = delete; - Unicode(const Unicode&) = delete; - Unicode(Unicode&&) = delete; - Unicode& operator=(const Unicode&) = delete; - Unicode& operator=(Unicode&&) = delete; - }; - -} diff --git a/src/include/support/Utf8.cpp b/src/include/support/Utf8.cpp deleted file mode 100644 index 294e9f1b..00000000 --- a/src/include/support/Utf8.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* Copyright (c) 2021 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include -#include - -#include "support/Utf8.h" -#include "support/Unicode.h" - -// The below implementation is based off of https://github.com/google/cel-cpp/internal/utf8.cc, -// which is itself based off of https://go.googlesource.com/go/+/refs/heads/master/src/unicode/utf8/utf8.go. -// If for some reason you feel the need to copy this implementation, please retain a comment -// referencing the two source files and giving credit, as well as maintaining any and all -// obligations required by the BSD 3-clause license that governs this file. - -namespace antlrcpp { - -namespace { - -#undef SELF - constexpr uint8_t SELF = 0x80; - -#undef LOW - constexpr uint8_t LOW = 0x80; -#undef HIGH - constexpr uint8_t HIGH = 0xbf; - -#undef MASKX - constexpr uint8_t MASKX = 0x3f; -#undef MASK2 - constexpr uint8_t MASK2 = 0x1f; -#undef MASK3 - constexpr uint8_t MASK3 = 0xf; -#undef MASK4 - constexpr uint8_t MASK4 = 0x7; - -#undef TX - constexpr uint8_t TX = 0x80; -#undef T2 - constexpr uint8_t T2 = 0xc0; -#undef T3 - constexpr uint8_t T3 = 0xe0; -#undef T4 - constexpr uint8_t T4 = 0xf0; - -#undef XX - constexpr uint8_t XX = 0xf1; -#undef AS - constexpr uint8_t AS = 0xf0; -#undef S1 - constexpr uint8_t S1 = 0x02; -#undef S2 - constexpr uint8_t S2 = 0x13; -#undef S3 - constexpr uint8_t S3 = 0x03; -#undef S4 - constexpr uint8_t S4 = 0x23; -#undef S5 - constexpr uint8_t S5 = 0x34; -#undef S6 - constexpr uint8_t S6 = 0x04; -#undef S7 - constexpr uint8_t S7 = 0x44; - - // NOLINTBEGIN - // clang-format off -#undef LEADING - constexpr uint8_t LEADING[256] = { - // 1 2 3 4 5 6 7 8 9 A B C D E F - AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, // 0x00-0x0F - AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, // 0x10-0x1F - AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, // 0x20-0x2F - AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, // 0x30-0x3F - AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, // 0x40-0x4F - AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, // 0x50-0x5F - AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, // 0x60-0x6F - AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, AS, // 0x70-0x7F - // 1 2 3 4 5 6 7 8 9 A B C D E F - XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, // 0x80-0x8F - XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, // 0x90-0x9F - XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, // 0xA0-0xAF - XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, // 0xB0-0xBF - XX, XX, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, // 0xC0-0xCF - S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, S1, // 0xD0-0xDF - S2, S3, S3, S3, S3, S3, S3, S3, S3, S3, S3, S3, S3, S4, S3, S3, // 0xE0-0xEF - S5, S6, S6, S6, S7, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, // 0xF0-0xFF - }; - // clang-format on - // NOLINTEND - -#undef ACCEPT - constexpr std::pair ACCEPT[16] = { - {LOW, HIGH}, {0xa0, HIGH}, {LOW, 0x9f}, {0x90, HIGH}, - {LOW, 0x8f}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, - {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, - {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, - }; - -} // namespace - - std::pair Utf8::decode(std::string_view input) { - assert(!input.empty()); - const auto b = static_cast(input.front()); - input.remove_prefix(1); - if (b < SELF) { - return {static_cast(b), 1}; - } - const auto leading = LEADING[b]; - if (leading == XX) { - return {Unicode::REPLACEMENT_CHARACTER, 1}; - } - auto size = static_cast(leading & 7) - 1; - if (size > input.size()) { - return {Unicode::REPLACEMENT_CHARACTER, 1}; - } - const auto& accept = ACCEPT[leading >> 4]; - const auto b1 = static_cast(input.front()); - input.remove_prefix(1); - if (b1 < accept.first || b1 > accept.second) { - return {Unicode::REPLACEMENT_CHARACTER, 1}; - } - if (size <= 1) { - return {(static_cast(b & MASK2) << 6) | - static_cast(b1 & MASKX), - 2}; - } - const auto b2 = static_cast(input.front()); - input.remove_prefix(1); - if (b2 < LOW || b2 > HIGH) { - return {Unicode::REPLACEMENT_CHARACTER, 1}; - } - if (size <= 2) { - return {(static_cast(b & MASK3) << 12) | - (static_cast(b1 & MASKX) << 6) | - static_cast(b2 & MASKX), - 3}; - } - const auto b3 = static_cast(input.front()); - input.remove_prefix(1); - if (b3 < LOW || b3 > HIGH) { - return {Unicode::REPLACEMENT_CHARACTER, 1}; - } - return {(static_cast(b & MASK4) << 18) | - (static_cast(b1 & MASKX) << 12) | - (static_cast(b2 & MASKX) << 6) | - static_cast(b3 & MASKX), - 4}; - } - - std::optional Utf8::strictDecode(std::string_view input) { - std::u32string output; - char32_t codePoint; - size_t codeUnits; - output.reserve(input.size()); // Worst case is each byte is a single Unicode code point. - for (size_t index = 0; index < input.size(); index += codeUnits) { - std::tie(codePoint, codeUnits) = Utf8::decode(input.substr(index)); - if (codePoint == Unicode::REPLACEMENT_CHARACTER && codeUnits == 1) { - // Condition is only met when an illegal byte sequence is encountered. See Utf8::decode. - return std::nullopt; - } - output.push_back(codePoint); - } - output.shrink_to_fit(); - return output; - } - - std::u32string Utf8::lenientDecode(std::string_view input) { - std::u32string output; - char32_t codePoint; - size_t codeUnits; - output.reserve(input.size()); // Worst case is each byte is a single Unicode code point. - for (size_t index = 0; index < input.size(); index += codeUnits) { - std::tie(codePoint, codeUnits) = Utf8::decode(input.substr(index)); - output.push_back(codePoint); - } - output.shrink_to_fit(); - return output; - } - - std::string& Utf8::encode(std::string* buffer, char32_t codePoint) { - assert(buffer != nullptr); - if (!Unicode::isValid(codePoint)) { - codePoint = Unicode::REPLACEMENT_CHARACTER; - } - if (codePoint <= 0x7f) { - buffer->push_back(static_cast(static_cast(codePoint))); - } else if (codePoint <= 0x7ff) { - buffer->push_back( - static_cast(T2 | static_cast(codePoint >> 6))); - buffer->push_back( - static_cast(TX | (static_cast(codePoint) & MASKX))); - } else if (codePoint <= 0xffff) { - buffer->push_back( - static_cast(T3 | static_cast(codePoint >> 12))); - buffer->push_back(static_cast( - TX | (static_cast(codePoint >> 6) & MASKX))); - buffer->push_back( - static_cast(TX | (static_cast(codePoint) & MASKX))); - } else { - buffer->push_back( - static_cast(T4 | static_cast(codePoint >> 18))); - buffer->push_back(static_cast( - TX | (static_cast(codePoint >> 12) & MASKX))); - buffer->push_back(static_cast( - TX | (static_cast(codePoint >> 6) & MASKX))); - buffer->push_back( - static_cast(TX | (static_cast(codePoint) & MASKX))); - } - return *buffer; - } - - std::optional Utf8::strictEncode(std::u32string_view input) { - std::string output; - output.reserve(input.size() * 4); // Worst case is each Unicode code point encodes to 4 bytes. - for (size_t index = 0; index < input.size(); index++) { - char32_t codePoint = input[index]; - if (!Unicode::isValid(codePoint)) { - return std::nullopt; - } - Utf8::encode(&output, codePoint); - } - output.shrink_to_fit(); - return output; - } - - std::string Utf8::lenientEncode(std::u32string_view input) { - std::string output; - output.reserve(input.size() * 4); // Worst case is each Unicode code point encodes to 4 bytes. - for (size_t index = 0; index < input.size(); index++) { - char32_t codePoint = input[index]; - if (!Unicode::isValid(codePoint)) { - codePoint = Unicode::REPLACEMENT_CHARACTER; - } - Utf8::encode(&output, codePoint); - } - output.shrink_to_fit(); - return output; - } - -} diff --git a/src/include/support/Utf8.h b/src/include/support/Utf8.h deleted file mode 100644 index e4828441..00000000 --- a/src/include/support/Utf8.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2021 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include -#include -#include -#include - -#include "antlr4-common.h" - -namespace antlrcpp { - - class ANTLR4CPP_PUBLIC Utf8 final { - public: - // Decodes the next code point, returning the decoded code point and the number - // of code units (a.k.a. bytes) consumed. In the event that an invalid code unit - // sequence is returned the replacement character, U+FFFD, is returned with a - // code unit count of 1. As U+FFFD requires 3 code units when encoded, this can - // be used to differentiate valid input from malformed input. - static std::pair decode(std::string_view input); - - // Decodes the given UTF-8 encoded input into a string of code points. - static std::optional strictDecode(std::string_view input); - - // Decodes the given UTF-8 encoded input into a string of code points. Unlike strictDecode(), - // each byte in an illegal byte sequence is replaced with the Unicode replacement character, - // U+FFFD. - static std::u32string lenientDecode(std::string_view input); - - // Encodes the given code point and appends it to the buffer. If the code point - // is an unpaired surrogate or outside of the valid Unicode range it is replaced - // with the replacement character, U+FFFD. - static std::string& encode(std::string *buffer, char32_t codePoint); - - // Encodes the given Unicode code point string as UTF-8. - static std::optional strictEncode(std::u32string_view input); - - // Encodes the given Unicode code point string as UTF-8. Unlike strictEncode(), - // each invalid Unicode code point is replaced with the Unicode replacement character, U+FFFD. - static std::string lenientEncode(std::u32string_view input); - - private: - Utf8() = delete; - Utf8(const Utf8&) = delete; - Utf8(Utf8&&) = delete; - Utf8& operator=(const Utf8&) = delete; - Utf8& operator=(Utf8&&) = delete; - }; - -} diff --git a/src/include/tree/AbstractParseTreeVisitor.h b/src/include/tree/AbstractParseTreeVisitor.h deleted file mode 100755 index 37b80b3f..00000000 --- a/src/include/tree/AbstractParseTreeVisitor.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "tree/ParseTree.h" -#include "tree/ParseTreeVisitor.h" - -namespace antlr4 { -namespace tree { - - class ANTLR4CPP_PUBLIC AbstractParseTreeVisitor : public ParseTreeVisitor { - public: - /// The default implementation calls on the - /// specified tree. - virtual std::any visit(ParseTree *tree) override { - return tree->accept(this); - } - - /** - *

The default implementation initializes the aggregate result to - * {@link #defaultResult defaultResult()}. Before visiting each child, it - * calls {@link #shouldVisitNextChild shouldVisitNextChild}; if the result - * is {@code false} no more children are visited and the current aggregate - * result is returned. After visiting a child, the aggregate result is - * updated by calling {@link #aggregateResult aggregateResult} with the - * previous aggregate result and the result of visiting the child.

- * - *

The default implementation is not safe for use in visitors that modify - * the tree structure. Visitors that modify the tree should override this - * method to behave properly in respect to the specific algorithm in use.

- */ - virtual std::any visitChildren(ParseTree *node) override { - std::any result = defaultResult(); - size_t n = node->children.size(); - for (size_t i = 0; i < n; i++) { - if (!shouldVisitNextChild(node, result)) { - break; - } - - std::any childResult = node->children[i]->accept(this); - result = aggregateResult(std::move(result), std::move(childResult)); - } - - return result; - } - - /// The default implementation returns the result of - /// . - virtual std::any visitTerminal(TerminalNode * /*node*/) override { - return defaultResult(); - } - - /// The default implementation returns the result of - /// . - virtual std::any visitErrorNode(ErrorNode * /*node*/) override { - return defaultResult(); - } - - protected: - /// - /// Gets the default value returned by visitor methods. This value is - /// returned by the default implementations of - /// , . - /// The default implementation of - /// initializes its aggregate result to this value. - ///

- /// The base implementation returns {@code std::any()}. - ///

- /// The default value returned by visitor methods. - virtual std::any defaultResult() { - return std::any(); - } - - /// - /// Aggregates the results of visiting multiple children of a node. After - /// either all children are visited or returns - /// {@code false}, the aggregate value is returned as the result of - /// . - ///

- /// The default implementation returns {@code nextResult}, meaning - /// will return the result of the last child visited - /// (or return the initial value if the node has no children). - ///

- /// The previous aggregate value. In the default - /// implementation, the aggregate value is initialized to - /// , which is passed as the {@code aggregate} argument - /// to this method after the first child node is visited. - /// The result of the immediately preceeding call to visit - /// a child node. - /// - /// The updated aggregate result. - virtual std::any aggregateResult(std::any /*aggregate*/, std::any nextResult) { - return nextResult; - } - - /// - /// This method is called after visiting each child in - /// . This method is first called before the first - /// child is visited; at that point {@code currentResult} will be the initial - /// value (in the default implementation, the initial value is returned by a - /// call to . This method is not called after the last - /// child is visited. - ///

- /// The default implementation always returns {@code true}, indicating that - /// {@code visitChildren} should only return after all children are visited. - /// One reason to override this method is to provide a "short circuit" - /// evaluation option for situations where the result of visiting a single - /// child has the potential to determine the result of the visit operation as - /// a whole. - ///

- /// The whose children are currently being - /// visited. - /// The current aggregate result of the children visited - /// to the current point. - /// - /// {@code true} to continue visiting children. Otherwise return - /// {@code false} to stop visiting children and immediately return the - /// current aggregate result from . - virtual bool shouldVisitNextChild(ParseTree * /*node*/, const std::any &/*currentResult*/) { - return true; - } - - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/ErrorNode.h b/src/include/tree/ErrorNode.h deleted file mode 100755 index c77a5a24..00000000 --- a/src/include/tree/ErrorNode.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "tree/TerminalNode.h" - -namespace antlr4 { -namespace tree { - - class ANTLR4CPP_PUBLIC ErrorNode : public TerminalNode { - public: - static bool is(const tree::ParseTree &parseTree) { return parseTree.getTreeType() == tree::ParseTreeType::ERROR; } - - static bool is(const tree::ParseTree *parseTree) { return parseTree != nullptr && is(*parseTree); } - - protected: - using TerminalNode::TerminalNode; - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/ErrorNodeImpl.cpp b/src/include/tree/ErrorNodeImpl.cpp deleted file mode 100755 index f13833fa..00000000 --- a/src/include/tree/ErrorNodeImpl.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/Interval.h" -#include "Token.h" -#include "RuleContext.h" -#include "tree/ParseTreeVisitor.h" - -#include "tree/ErrorNodeImpl.h" - -using namespace antlr4; -using namespace antlr4::tree; - -Token* ErrorNodeImpl::getSymbol() const { - return symbol; -} - -void ErrorNodeImpl::setParent(RuleContext *parent_) { - this->parent = parent_; -} - -misc::Interval ErrorNodeImpl::getSourceInterval() { - if (symbol == nullptr) { - return misc::Interval::INVALID; - } - - size_t tokenIndex = symbol->getTokenIndex(); - return misc::Interval(tokenIndex, tokenIndex); -} - -std::any ErrorNodeImpl::accept(ParseTreeVisitor *visitor) { - return visitor->visitErrorNode(this); -} - -std::string ErrorNodeImpl::getText() { - return symbol->getText(); -} - -std::string ErrorNodeImpl::toStringTree(Parser * /*parser*/, bool /*pretty*/) { - return toString(); -} - -std::string ErrorNodeImpl::toString() { - if (symbol->getType() == Token::EOF) { - return ""; - } - return symbol->getText(); -} - -std::string ErrorNodeImpl::toStringTree(bool /*pretty*/) { - return toString(); -} diff --git a/src/include/tree/ErrorNodeImpl.h b/src/include/tree/ErrorNodeImpl.h deleted file mode 100755 index dc9bd105..00000000 --- a/src/include/tree/ErrorNodeImpl.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "tree/ErrorNode.h" -#include "tree/TerminalNodeImpl.h" -#include "misc/Interval.h" - -#include "support/Any.h" - -namespace antlr4 { -namespace tree { - - /// - /// Represents a token that was consumed during resynchronization - /// rather than during a valid match operation. For example, - /// we will create this kind of a node during single token insertion - /// and deletion as well as during "consume until error recovery set" - /// upon no viable alternative exceptions. - /// - class ANTLR4CPP_PUBLIC ErrorNodeImpl : public ErrorNode { - public: - Token *symbol; - - explicit ErrorNodeImpl(Token *symbol) : ErrorNode(ParseTreeType::ERROR), symbol(symbol) {} - - virtual Token* getSymbol() const override; - virtual void setParent(RuleContext *parent) override; - virtual misc::Interval getSourceInterval() override; - - virtual std::any accept(ParseTreeVisitor *visitor) override; - - virtual std::string getText() override; - virtual std::string toStringTree(Parser *parser, bool pretty = false) override; - virtual std::string toString() override; - virtual std::string toStringTree(bool pretty = false) override; - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/IterativeParseTreeWalker.cpp b/src/include/tree/IterativeParseTreeWalker.cpp deleted file mode 100644 index 83e63395..00000000 --- a/src/include/tree/IterativeParseTreeWalker.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "support/CPPUtils.h" -#include "support/Casts.h" - -#include "tree/ParseTreeListener.h" -#include "tree/ParseTree.h" -#include "tree/ErrorNode.h" - -#include "IterativeParseTreeWalker.h" - -using namespace antlr4::tree; -using namespace antlrcpp; - -void IterativeParseTreeWalker::walk(ParseTreeListener *listener, ParseTree *t) const { - std::vector> stack; - ParseTree *currentNode = t; - size_t currentIndex = 0; - - while (currentNode != nullptr) { - // pre-order visit - if (ErrorNode::is(*currentNode)) { - listener->visitErrorNode(downCast(currentNode)); - } else if (TerminalNode::is(*currentNode)) { - listener->visitTerminal(downCast(currentNode)); - } else { - enterRule(listener, currentNode); - } - - // Move down to first child, if it exists. - if (!currentNode->children.empty()) { - stack.push_back(std::make_pair(currentNode, currentIndex)); - currentIndex = 0; - currentNode = currentNode->children[0]; - continue; - } - - // No child nodes, so walk tree. - do { - // post-order visit - if (!TerminalNode::is(*currentNode)) { - exitRule(listener, currentNode); - } - - // No parent, so no siblings. - if (stack.empty()) { - currentNode = nullptr; - currentIndex = 0; - break; - } - - // Move to next sibling if possible. - if (stack.back().first->children.size() > ++currentIndex) { - currentNode = stack.back().first->children[currentIndex]; - break; - } - - // No next sibling, so move up. - std::tie(currentNode, currentIndex) = stack.back(); - stack.pop_back(); - } while (currentNode != nullptr); - } -} diff --git a/src/include/tree/IterativeParseTreeWalker.h b/src/include/tree/IterativeParseTreeWalker.h deleted file mode 100644 index 8957d87e..00000000 --- a/src/include/tree/IterativeParseTreeWalker.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * [The "BSD license"] - * Copyright (c) 2012 Terence Parr - * Copyright (c) 2012 Sam Harwell - * 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 - -#include "antlr4-common.h" - -#include "tree/ParseTreeWalker.h" - -namespace antlr4 { -namespace tree { - - class ParseTreeListener; - - /** - * An iterative (read: non-recursive) pre-order and post-order tree walker that - * doesn't use the thread stack but heap-based stacks. Makes it possible to - * process deeply nested parse trees. - */ - class ANTLR4CPP_PUBLIC IterativeParseTreeWalker : public ParseTreeWalker { - public: - virtual void walk(ParseTreeListener *listener, ParseTree *t) const override; - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/ParseTree.cpp b/src/include/tree/ParseTree.cpp deleted file mode 100755 index 2d529cb0..00000000 --- a/src/include/tree/ParseTree.cpp +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/ParseTree.h" - -using namespace antlr4::tree; - -bool ParseTree::operator == (const ParseTree &other) const { - return &other == this; -} diff --git a/src/include/tree/ParseTree.h b/src/include/tree/ParseTree.h deleted file mode 100755 index 25df4890..00000000 --- a/src/include/tree/ParseTree.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "support/Any.h" -#include "tree/ParseTreeType.h" - -namespace antlr4 { -namespace tree { - - /// An interface to access the tree of objects created - /// during a parse that makes the data structure look like a simple parse tree. - /// This node represents both internal nodes, rule invocations, - /// and leaf nodes, token matches. - /// - /// The payload is either a or a object. - // ml: This class unites 4 Java classes: RuleNode, ParseTree, SyntaxTree and Tree. - class ANTLR4CPP_PUBLIC ParseTree { - public: - ParseTree(ParseTree const&) = delete; - - virtual ~ParseTree() = default; - - ParseTree& operator=(ParseTree const&) = delete; - - /// The parent of this node. If the return value is null, then this - /// node is the root of the tree. - ParseTree *parent = nullptr; - - /// If we are debugging or building a parse tree for a visitor, - /// we need to track all of the tokens and rule invocations associated - /// with this rule's context. This is empty for parsing w/o tree constr. - /// operation because we don't the need to track the details about - /// how we parse this rule. - // ml: memory is not managed here, but by the owning class. This is just for the structure. - std::vector children; - - /// Print out a whole tree, not just a node, in LISP format - /// {@code (root child1 .. childN)}. Print just a node if this is a leaf. - virtual std::string toStringTree(bool pretty = false) = 0; - virtual std::string toString() = 0; - - /// Specialize toStringTree so that it can print out more information - /// based upon the parser. - virtual std::string toStringTree(Parser *parser, bool pretty = false) = 0; - - virtual bool operator == (const ParseTree &other) const; - - /// The needs a double dispatch method. - // ml: This has been changed to use Any instead of a template parameter, to avoid the need of a virtual template function. - virtual std::any accept(ParseTreeVisitor *visitor) = 0; - - /// Return the combined text of all leaf nodes. Does not get any - /// off-channel tokens (if any) so won't return whitespace and - /// comments if they are sent to parser on hidden channel. - virtual std::string getText() = 0; - - /** - * Return an {@link Interval} indicating the index in the - * {@link TokenStream} of the first and last token associated with this - * subtree. If this node is a leaf, then the interval represents a single - * token and has interval i..i for token index i. - * - *

An interval of i..i-1 indicates an empty interval at position - * i in the input stream, where 0 <= i <= the size of the input - * token stream. Currently, the code base can only have i=0..n-1 but - * in concept one could have an empty interval after EOF.

- * - *

If source interval is unknown, this returns {@link Interval#INVALID}.

- * - *

As a weird special case, the source interval for rules matched after - * EOF is unspecified.

- */ - virtual misc::Interval getSourceInterval() = 0; - - ParseTreeType getTreeType() const { return _treeType; } - - protected: - explicit ParseTree(ParseTreeType treeType) : _treeType(treeType) {} - - private: - const ParseTreeType _treeType; - }; - - // A class to help managing ParseTree instances without the need of a shared_ptr. - class ANTLR4CPP_PUBLIC ParseTreeTracker { - public: - template - T* createInstance(Args&& ... args) { - static_assert(std::is_base_of::value, "Argument must be a parse tree type"); - T* result = new T(args...); - _allocated.push_back(result); - return result; - } - - void reset() { - for (auto * entry : _allocated) - delete entry; - _allocated.clear(); - } - - private: - std::vector _allocated; - }; - - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/ParseTreeListener.cpp b/src/include/tree/ParseTreeListener.cpp deleted file mode 100644 index ce122975..00000000 --- a/src/include/tree/ParseTreeListener.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "ParseTreeListener.h" - -antlr4::tree::ParseTreeListener::~ParseTreeListener() { -} diff --git a/src/include/tree/ParseTreeListener.h b/src/include/tree/ParseTreeListener.h deleted file mode 100755 index 6a7f96a1..00000000 --- a/src/include/tree/ParseTreeListener.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace tree { - - /** This interface describes the minimal core of methods triggered - * by {@link ParseTreeWalker}. E.g., - * - * ParseTreeWalker walker = new ParseTreeWalker(); - * walker.walk(myParseTreeListener, myParseTree); <-- triggers events in your listener - * - * If you want to trigger events in multiple listeners during a single - * tree walk, you can use the ParseTreeDispatcher object available at - * - * https://github.com/antlr/antlr4/issues/841 - */ - class ANTLR4CPP_PUBLIC ParseTreeListener { - public: - virtual ~ParseTreeListener(); - - virtual void visitTerminal(TerminalNode *node) = 0; - virtual void visitErrorNode(ErrorNode *node) = 0; - virtual void enterEveryRule(ParserRuleContext *ctx) = 0; - virtual void exitEveryRule(ParserRuleContext *ctx) = 0; - - bool operator == (const ParseTreeListener &other) { - return this == &other; - } - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/ParseTreeProperty.h b/src/include/tree/ParseTreeProperty.h deleted file mode 100755 index 8669a104..00000000 --- a/src/include/tree/ParseTreeProperty.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace tree { - - /// - /// Associate a property with a parse tree node. Useful with parse tree listeners - /// that need to associate values with particular tree nodes, kind of like - /// specifying a return value for the listener event method that visited a - /// particular node. Example: - /// - ///
-  /// ParseTreeProperty<Integer> values = new ParseTreeProperty<Integer>();
-  /// values.put(tree, 36);
-  /// int x = values.get(tree);
-  /// values.removeFrom(tree);
-  /// 
- /// - /// You would make one decl (values here) in the listener and use lots of times - /// in your event methods. - ///
- template - class ANTLR4CPP_PUBLIC ParseTreeProperty { - public: - virtual ~ParseTreeProperty() {} - virtual V get(ParseTree *node) { - return _annotations[node]; - } - virtual void put(ParseTree *node, V value) { - _annotations[node] = value; - } - virtual V removeFrom(ParseTree *node) { - auto value = _annotations[node]; - _annotations.erase(node); - return value; - } - - protected: - std::map _annotations; - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/ParseTreeType.h b/src/include/tree/ParseTreeType.h deleted file mode 100644 index 17e0512b..00000000 --- a/src/include/tree/ParseTreeType.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include - -#include "antlr4-common.h" - -namespace antlr4 { -namespace tree { - - enum class ParseTreeType : size_t { - TERMINAL = 1, - ERROR = 2, - RULE = 3, - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/ParseTreeVisitor.cpp b/src/include/tree/ParseTreeVisitor.cpp deleted file mode 100644 index a329919c..00000000 --- a/src/include/tree/ParseTreeVisitor.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "ParseTreeVisitor.h" - -antlr4::tree::ParseTreeVisitor::~ParseTreeVisitor() { -} diff --git a/src/include/tree/ParseTreeVisitor.h b/src/include/tree/ParseTreeVisitor.h deleted file mode 100755 index d68311ba..00000000 --- a/src/include/tree/ParseTreeVisitor.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "support/Any.h" - -namespace antlr4 { -namespace tree { - - /// - /// This interface defines the basic notion of a parse tree visitor. Generated - /// visitors implement this interface and the {@code XVisitor} interface for - /// grammar {@code X}. - /// - /// @param The return type of the visit operation. Use for - /// operations with no return type. - // ml: no template parameter here, to avoid the need for virtual template functions. Instead we have our Any class. - class ANTLR4CPP_PUBLIC ParseTreeVisitor { - public: - virtual ~ParseTreeVisitor(); - - /// - /// Visit a parse tree, and return a user-defined result of the operation. - /// - /// The to visit. - /// The result of visiting the parse tree. - virtual std::any visit(ParseTree *tree) = 0; - - /// - /// Visit the children of a node, and return a user-defined result of the - /// operation. - /// - /// The whose children should be visited. - /// The result of visiting the children of the node. - virtual std::any visitChildren(ParseTree *node) = 0; - - /// - /// Visit a terminal node, and return a user-defined result of the operation. - /// - /// The to visit. - /// The result of visiting the node. - virtual std::any visitTerminal(TerminalNode *node) = 0; - - /// - /// Visit an error node, and return a user-defined result of the operation. - /// - /// The to visit. - /// The result of visiting the node. - virtual std::any visitErrorNode(ErrorNode *node) = 0; - - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/ParseTreeWalker.cpp b/src/include/tree/ParseTreeWalker.cpp deleted file mode 100755 index 1eeabff8..00000000 --- a/src/include/tree/ParseTreeWalker.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/ErrorNode.h" -#include "ParserRuleContext.h" -#include "tree/ParseTreeListener.h" -#include "support/CPPUtils.h" -#include "support/Casts.h" - -#include "tree/IterativeParseTreeWalker.h" -#include "tree/ParseTreeWalker.h" - -using namespace antlr4::tree; -using namespace antlrcpp; - -static IterativeParseTreeWalker defaultWalker; -ParseTreeWalker &ParseTreeWalker::DEFAULT = defaultWalker; - -void ParseTreeWalker::walk(ParseTreeListener *listener, ParseTree *t) const { - if (ErrorNode::is(*t)) { - listener->visitErrorNode(downCast(t)); - return; - } - if (TerminalNode::is(*t)) { - listener->visitTerminal(downCast(t)); - return; - } - - enterRule(listener, t); - for (auto &child : t->children) { - walk(listener, child); - } - exitRule(listener, t); -} - -void ParseTreeWalker::enterRule(ParseTreeListener *listener, ParseTree *r) const { - auto *ctx = downCast(r); - listener->enterEveryRule(ctx); - ctx->enterRule(listener); -} - -void ParseTreeWalker::exitRule(ParseTreeListener *listener, ParseTree *r) const { - auto *ctx = downCast(r); - ctx->exitRule(listener); - listener->exitEveryRule(ctx); -} diff --git a/src/include/tree/ParseTreeWalker.h b/src/include/tree/ParseTreeWalker.h deleted file mode 100755 index 375e6597..00000000 --- a/src/include/tree/ParseTreeWalker.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace tree { - - class ANTLR4CPP_PUBLIC ParseTreeWalker { - public: - static ParseTreeWalker &DEFAULT; - - virtual ~ParseTreeWalker() = default; - - /** - * - * Performs a walk on the given parse tree starting at the root and going down recursively - * with depth-first search. On each node, is called before - * recursively walking down into child nodes, then - * is called after the recursive call to wind up. - * - * The listener used by the walker to process grammar rules - * The parse tree to be walked on - */ - virtual void walk(ParseTreeListener *listener, ParseTree *t) const; - - protected: - - /** - * - * Enters a grammar rule by first triggering the generic event - * then by triggering the event specific to the given parse tree node - * - * The listener responding to the trigger events - * The grammar rule containing the rule context - */ - virtual void enterRule(ParseTreeListener *listener, ParseTree *r) const; - - /** - * - * Exits a grammar rule by first triggering the event specific to the given parse tree node - * then by triggering the generic event - * - * The listener responding to the trigger events - * The grammar rule containing the rule context - */ - virtual void exitRule(ParseTreeListener *listener, ParseTree *r) const; - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/TerminalNode.h b/src/include/tree/TerminalNode.h deleted file mode 100755 index 421e7ad7..00000000 --- a/src/include/tree/TerminalNode.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "tree/ParseTree.h" - -namespace antlr4 { -namespace tree { - - class ANTLR4CPP_PUBLIC TerminalNode : public ParseTree { - public: - static bool is(const tree::ParseTree &parseTree) { - const auto treeType = parseTree.getTreeType(); - return treeType == ParseTreeType::TERMINAL || treeType == ParseTreeType::ERROR; - } - - static bool is(const tree::ParseTree *parseTree) { return parseTree != nullptr && is(*parseTree); } - - virtual Token* getSymbol() const = 0; - - /** Set the parent for this leaf node. - * - * Technically, this is not backward compatible as it changes - * the interface but no one was able to create custom - * TerminalNodes anyway so I'm adding as it improves internal - * code quality. - * - * @since 4.7 - */ - virtual void setParent(RuleContext *parent) = 0; - - protected: - using ParseTree::ParseTree; - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/TerminalNodeImpl.cpp b/src/include/tree/TerminalNodeImpl.cpp deleted file mode 100755 index 573b1faf..00000000 --- a/src/include/tree/TerminalNodeImpl.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "misc/Interval.h" -#include "Token.h" -#include "RuleContext.h" -#include "tree/ParseTreeVisitor.h" - -#include "tree/TerminalNodeImpl.h" - -using namespace antlr4; -using namespace antlr4::tree; - -Token* TerminalNodeImpl::getSymbol() const { - return symbol; -} - -void TerminalNodeImpl::setParent(RuleContext *parent_) { - this->parent = parent_; -} - -misc::Interval TerminalNodeImpl::getSourceInterval() { - if (symbol == nullptr) { - return misc::Interval::INVALID; - } - - size_t tokenIndex = symbol->getTokenIndex(); - return misc::Interval(tokenIndex, tokenIndex); -} - -std::any TerminalNodeImpl::accept(ParseTreeVisitor *visitor) { - return visitor->visitTerminal(this); -} - -std::string TerminalNodeImpl::getText() { - return symbol->getText(); -} - -std::string TerminalNodeImpl::toStringTree(Parser * /*parser*/, bool /*pretty*/) { - return toString(); -} - -std::string TerminalNodeImpl::toString() { - if (symbol->getType() == Token::EOF) { - return ""; - } - return symbol->getText(); -} - -std::string TerminalNodeImpl::toStringTree(bool /*pretty*/) { - return toString(); -} diff --git a/src/include/tree/TerminalNodeImpl.h b/src/include/tree/TerminalNodeImpl.h deleted file mode 100755 index ddd8f128..00000000 --- a/src/include/tree/TerminalNodeImpl.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "tree/TerminalNode.h" - -namespace antlr4 { -namespace tree { - - class ANTLR4CPP_PUBLIC TerminalNodeImpl : public TerminalNode { - public: - Token *symbol; - - explicit TerminalNodeImpl(Token *symbol) : TerminalNode(ParseTreeType::TERMINAL), symbol(symbol) {} - - virtual Token* getSymbol() const override; - virtual void setParent(RuleContext *parent) override; - virtual misc::Interval getSourceInterval() override; - - virtual std::any accept(ParseTreeVisitor *visitor) override; - - virtual std::string getText() override; - virtual std::string toStringTree(Parser *parser, bool pretty = false) override; - virtual std::string toString() override; - virtual std::string toStringTree(bool pretty = false) override; - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/Trees.cpp b/src/include/tree/Trees.cpp deleted file mode 100755 index 34cfb74d..00000000 --- a/src/include/tree/Trees.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/ErrorNode.h" -#include "Parser.h" -#include "ParserRuleContext.h" -#include "support/CPPUtils.h" -#include "tree/TerminalNodeImpl.h" -#include "atn/ATN.h" -#include "misc/Interval.h" -#include "Token.h" -#include "CommonToken.h" -#include "misc/Predicate.h" - -#include "tree/Trees.h" - -using namespace antlr4; -using namespace antlr4::misc; -using namespace antlr4::tree; - -using namespace antlrcpp; - -Trees::Trees() { -} - -std::string Trees::toStringTree(ParseTree *t, bool pretty) { - return toStringTree(t, nullptr, pretty); -} - -std::string Trees::toStringTree(ParseTree *t, Parser *recog, bool pretty) { - if (recog == nullptr) - return toStringTree(t, std::vector(), pretty); - return toStringTree(t, recog->getRuleNames(), pretty); -} - -std::string Trees::toStringTree(ParseTree *t, const std::vector &ruleNames, bool pretty) { - std::string temp = antlrcpp::escapeWhitespace(Trees::getNodeText(t, ruleNames), false); - if (t->children.empty()) { - return temp; - } - - std::stringstream ss; - ss << "(" << temp << ' '; - - // Implement the recursive walk as iteration to avoid trouble with deep nesting. - std::stack stack; - size_t childIndex = 0; - ParseTree *run = t; - size_t indentationLevel = 1; - while (childIndex < run->children.size()) { - if (childIndex > 0) { - ss << ' '; - } - ParseTree *child = run->children[childIndex]; - temp = antlrcpp::escapeWhitespace(Trees::getNodeText(child, ruleNames), false); - if (!child->children.empty()) { - // Go deeper one level. - stack.push(childIndex); - run = child; - childIndex = 0; - if (pretty) { - ++indentationLevel; - ss << std::endl; - for (size_t i = 0; i < indentationLevel; ++i) { - ss << " "; - } - } - ss << "(" << temp << " "; - } else { - ss << temp; - while (++childIndex == run->children.size()) { - if (stack.size() > 0) { - // Reached the end of the current level. See if we can step up from here. - childIndex = stack.top(); - stack.pop(); - run = run->parent; - if (pretty) { - --indentationLevel; - } - ss << ")"; - } else { - break; - } - } - } - } - - ss << ")"; - return ss.str(); -} - -std::string Trees::getNodeText(ParseTree *t, Parser *recog) { - return getNodeText(t, recog->getRuleNames()); -} - -std::string Trees::getNodeText(ParseTree *t, const std::vector &ruleNames) { - if (ruleNames.size() > 0) { - if (is(t)) { - size_t ruleIndex = dynamic_cast(t)->getRuleIndex(); - std::string ruleName = ruleNames[ruleIndex]; - size_t altNumber = dynamic_cast(t)->getAltNumber(); - if (altNumber != atn::ATN::INVALID_ALT_NUMBER) { - return ruleName + ":" + std::to_string(altNumber); - } - return ruleName; - } else if (is(t)) { - return t->toString(); - } else if (is(t)) { - Token *symbol = dynamic_cast(t)->getSymbol(); - if (symbol != nullptr) { - std::string s = symbol->getText(); - return s; - } - } - } - // no recog for rule names - if (is(t)) { - return dynamic_cast(t)->getText(); - } - - if (is(t)) { - return dynamic_cast(t)->getSymbol()->getText(); - } - - return ""; -} - -std::vector Trees::getAncestors(ParseTree *t) { - std::vector ancestors; - ParseTree *parent = t->parent; - while (parent != nullptr) { - ancestors.insert(ancestors.begin(), parent); // insert at start - parent = parent->parent; - } - return ancestors; -} - -template -static void _findAllNodes(ParseTree *t, size_t index, bool findTokens, std::vector &nodes) { - // check this node (the root) first - if (findTokens && is(t)) { - TerminalNode *tnode = dynamic_cast(t); - if (tnode->getSymbol()->getType() == index) { - nodes.push_back(t); - } - } else if (!findTokens && is(t)) { - ParserRuleContext *ctx = dynamic_cast(t); - if (ctx->getRuleIndex() == index) { - nodes.push_back(t); - } - } - // check children - for (size_t i = 0; i < t->children.size(); i++) { - _findAllNodes(t->children[i], index, findTokens, nodes); - } -} - -bool Trees::isAncestorOf(ParseTree *t, ParseTree *u) { - if (t == nullptr || u == nullptr || t->parent == nullptr) { - return false; - } - - ParseTree *p = u->parent; - while (p != nullptr) { - if (t == p) { - return true; - } - p = p->parent; - } - return false; -} - -std::vector Trees::findAllTokenNodes(ParseTree *t, size_t ttype) { - return findAllNodes(t, ttype, true); -} - -std::vector Trees::findAllRuleNodes(ParseTree *t, size_t ruleIndex) { - return findAllNodes(t, ruleIndex, false); -} - -std::vector Trees::findAllNodes(ParseTree *t, size_t index, bool findTokens) { - std::vector nodes; - _findAllNodes(t, index, findTokens, nodes); - return nodes; -} - -std::vector Trees::getDescendants(ParseTree *t) { - std::vector nodes; - nodes.push_back(t); - std::size_t n = t->children.size(); - for (size_t i = 0 ; i < n ; i++) { - auto descentants = getDescendants(t->children[i]); - for (auto *entry: descentants) { - nodes.push_back(entry); - } - } - return nodes; -} - -std::vector Trees::descendants(ParseTree *t) { - return getDescendants(t); -} - -ParserRuleContext* Trees::getRootOfSubtreeEnclosingRegion(ParseTree *t, size_t startTokenIndex, size_t stopTokenIndex) { - size_t n = t->children.size(); - for (size_t i = 0; i < n; i++) { - ParserRuleContext *r = getRootOfSubtreeEnclosingRegion(t->children[i], startTokenIndex, stopTokenIndex); - if (r != nullptr) { - return r; - } - } - - if (is(t)) { - ParserRuleContext *r = dynamic_cast(t); - if (startTokenIndex >= r->getStart()->getTokenIndex() && // is range fully contained in t? - (r->getStop() == nullptr || stopTokenIndex <= r->getStop()->getTokenIndex())) { - // note: r.getStop()==null likely implies that we bailed out of parser and there's nothing to the right - return r; - } - } - return nullptr; -} - -ParseTree * Trees::findNodeSuchThat(ParseTree *t, Ref const& pred) { - if (pred->test(t)) { - return t; - } - - size_t n = t->children.size(); - for (size_t i = 0 ; i < n ; ++i) { - ParseTree *u = findNodeSuchThat(t->children[i], pred); - if (u != nullptr) { - return u; - } - } - - return nullptr; -} - diff --git a/src/include/tree/Trees.h b/src/include/tree/Trees.h deleted file mode 100755 index d9d04624..00000000 --- a/src/include/tree/Trees.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "tree/TerminalNode.h" -#include "ParserRuleContext.h" -#include "Recognizer.h" - -namespace antlr4 { -namespace tree { - - /// A set of utility routines useful for all kinds of ANTLR trees. - class ANTLR4CPP_PUBLIC Trees { - public: - /// 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::string toStringTree(ParseTree *t, bool pretty = false); - - /// 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::string toStringTree(ParseTree *t, Parser *recog, bool pretty = false); - - /// 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::string toStringTree(ParseTree *t, const std::vector &ruleNames, bool pretty = false); - static std::string getNodeText(ParseTree *t, Parser *recog); - static std::string getNodeText(ParseTree *t, const std::vector &ruleNames); - - /// 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 getAncestors(ParseTree *t); - - /** Return true if t is u's parent or a node on path to root from u. - * Use == not equals(). - * - * @since 4.5.1 - */ - static bool isAncestorOf(ParseTree *t, ParseTree *u); - static std::vector findAllTokenNodes(ParseTree *t, size_t ttype); - static std::vector findAllRuleNodes(ParseTree *t, size_t ruleIndex); - static std::vector findAllNodes(ParseTree *t, size_t index, bool findTokens); - - /** Get all descendents; includes t itself. - * - * @since 4.5.1 - */ - static std::vector getDescendants(ParseTree *t); - - /** @deprecated */ - static std::vector descendants(ParseTree *t); - - /** Find smallest subtree of t enclosing range startTokenIndex..stopTokenIndex - * inclusively using postorder traversal. Recursive depth-first-search. - * - * @since 4.5.1 - */ - static ParserRuleContext* getRootOfSubtreeEnclosingRegion(ParseTree *t, - size_t startTokenIndex, // inclusive - size_t stopTokenIndex); // inclusive - - /** Return first node satisfying the pred - * - * @since 4.5.1 - */ - static ParseTree* findNodeSuchThat(ParseTree *t, Ref const& pred); - - private: - Trees(); - }; - -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/pattern/Chunk.cpp b/src/include/tree/pattern/Chunk.cpp deleted file mode 100644 index 5320f910..00000000 --- a/src/include/tree/pattern/Chunk.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/pattern/Chunk.h" - -antlr4::tree::pattern::Chunk::~Chunk() { -} diff --git a/src/include/tree/pattern/Chunk.h b/src/include/tree/pattern/Chunk.h deleted file mode 100755 index 42e7838d..00000000 --- a/src/include/tree/pattern/Chunk.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace tree { -namespace pattern { - - /// - /// A chunk is either a token tag, a rule tag, or a span of literal text within a - /// tree pattern. - ///

- /// The method returns a list of - /// chunks in preparation for creating a token stream by - /// . From there, we get a parse - /// tree from with . These - /// chunks are converted to , , or the - /// regular tokens of the text surrounding the tags. - ///

- class ANTLR4CPP_PUBLIC Chunk { - public: - Chunk() = default; - Chunk(Chunk const&) = default; - virtual ~Chunk(); - - Chunk& operator=(Chunk const&) = default; - - /// This method returns a text representation of the tag chunk. Labeled tags - /// are returned in the form {@code label:tag}, and unlabeled tags are - /// returned as just the tag name. - virtual std::string toString() { - std::string str; - return str; - } - }; - -} // namespace pattern -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/pattern/ParseTreeMatch.cpp b/src/include/tree/pattern/ParseTreeMatch.cpp deleted file mode 100755 index ce34b3f2..00000000 --- a/src/include/tree/pattern/ParseTreeMatch.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "Exceptions.h" - -#include "tree/pattern/ParseTreeMatch.h" - -using namespace antlr4::tree; -using namespace antlr4::tree::pattern; - -ParseTreeMatch::ParseTreeMatch(ParseTree *tree, const ParseTreePattern &pattern, - const std::map> &labels, - ParseTree *mismatchedNode) - : _tree(tree), _pattern(pattern), _labels(labels), _mismatchedNode(mismatchedNode) { - if (tree == nullptr) { - throw IllegalArgumentException("tree cannot be nul"); - } -} - -ParseTreeMatch::~ParseTreeMatch() { -} - -ParseTree* ParseTreeMatch::get(const std::string &label) { - auto iterator = _labels.find(label); - if (iterator == _labels.end() || iterator->second.empty()) { - return nullptr; - } - - return iterator->second.back(); // return last if multiple -} - -std::vector ParseTreeMatch::getAll(const std::string &label) { - auto iterator = _labels.find(label); - if (iterator == _labels.end()) { - return {}; - } - - return iterator->second; -} - -std::map>& ParseTreeMatch::getLabels() { - return _labels; -} - -ParseTree *ParseTreeMatch::getMismatchedNode() { - return _mismatchedNode; -} - -bool ParseTreeMatch::succeeded() { - return _mismatchedNode == nullptr; -} - -const ParseTreePattern& ParseTreeMatch::getPattern() { - return _pattern; -} - -ParseTree * ParseTreeMatch::getTree() { - return _tree; -} - -std::string ParseTreeMatch::toString() { - if (succeeded()) { - return "Match succeeded; found " + std::to_string(_labels.size()) + " labels"; - } else { - return "Match failed; found " + std::to_string(_labels.size()) + " labels"; - } -} diff --git a/src/include/tree/pattern/ParseTreeMatch.h b/src/include/tree/pattern/ParseTreeMatch.h deleted file mode 100755 index eefde46c..00000000 --- a/src/include/tree/pattern/ParseTreeMatch.h +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace tree { -namespace pattern { - - /// Represents the result of matching a ParseTree against a tree pattern. - class ANTLR4CPP_PUBLIC ParseTreeMatch { - private: - /// This is the backing field for getTree(). - ParseTree *_tree; - - /// This is the backing field for getPattern(). - const ParseTreePattern &_pattern; - - /// This is the backing field for getLabels(). - std::map> _labels; - - /// This is the backing field for getMismatchedNode(). - ParseTree *_mismatchedNode; - - public: - /// - /// Constructs a new instance of from the specified - /// parse tree and pattern. - /// - /// The parse tree to match against the pattern. - /// The parse tree pattern. - /// A mapping from label names to collections of - /// objects located by the tree pattern matching process. - /// The first node which failed to match the tree - /// pattern during the matching process. - /// - /// if {@code tree} is {@code null} - /// if {@code pattern} is {@code null} - /// if {@code labels} is {@code null} - ParseTreeMatch(ParseTree *tree, ParseTreePattern const& pattern, - const std::map> &labels, ParseTree *mismatchedNode); - ParseTreeMatch(ParseTreeMatch const&) = default; - virtual ~ParseTreeMatch(); - - /// - /// Get the last node associated with a specific {@code label}. - ///

- /// For example, for pattern {@code }, {@code get("id")} returns the - /// node matched for that {@code ID}. If more than one node - /// matched the specified label, only the last is returned. If there is - /// no node associated with the label, this returns {@code null}. - ///

- /// Pattern tags like {@code } and {@code } without labels are - /// considered to be labeled with {@code ID} and {@code expr}, respectively. - ///

- /// The label to check. - /// - /// The last to match a tag with the specified - /// label, or {@code null} if no parse tree matched a tag with the label. - virtual ParseTree* get(const std::string &label); - - /// - /// Return all nodes matching a rule or token tag with the specified label. - ///

- /// If the {@code label} is the name of a parser rule or token in the - /// grammar, the resulting list will contain both the parse trees matching - /// rule or tags explicitly labeled with the label and the complete set of - /// parse trees matching the labeled and unlabeled tags in the pattern for - /// the parser rule or token. For example, if {@code label} is {@code "foo"}, - /// the result will contain all of the following. - /// - ///

    - ///
  • Parse tree nodes matching tags of the form {@code } and - /// {@code }.
  • - ///
  • Parse tree nodes matching tags of the form {@code }.
  • - ///
  • Parse tree nodes matching tags of the form {@code }.
  • - ///
- ///
- /// The label. - /// - /// A collection of all nodes matching tags with - /// the specified {@code label}. If no nodes matched the label, an empty list - /// is returned. - virtual std::vector getAll(const std::string &label); - - /// - /// Return a mapping from label → [list of nodes]. - ///

- /// The map includes special entries corresponding to the names of rules and - /// tokens referenced in tags in the original pattern. For additional - /// information, see the description of . - ///

- /// 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. - virtual std::map>& getLabels(); - - /// - /// Get the node at which we first detected a mismatch. - /// - /// the node at which we first detected a mismatch, or {@code null} - /// if the match was successful. - virtual ParseTree* getMismatchedNode(); - - /// - /// Gets a value indicating whether the match operation succeeded. - /// - /// {@code true} if the match operation succeeded; otherwise, - /// {@code false}. - virtual bool succeeded(); - - /// - /// Get the tree pattern we are matching against. - /// - /// The tree pattern we are matching against. - virtual const ParseTreePattern& getPattern(); - - /// - /// Get the parse tree we are trying to match to a pattern. - /// - /// The we are trying to match to a pattern. - virtual ParseTree* getTree(); - - virtual std::string toString(); - }; - -} // namespace pattern -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/pattern/ParseTreePattern.cpp b/src/include/tree/pattern/ParseTreePattern.cpp deleted file mode 100755 index 50f44c82..00000000 --- a/src/include/tree/pattern/ParseTreePattern.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/ParseTree.h" -#include "tree/pattern/ParseTreePatternMatcher.h" -#include "tree/pattern/ParseTreeMatch.h" - -#include "tree/xpath/XPath.h" -#include "tree/xpath/XPathElement.h" - -#include "tree/pattern/ParseTreePattern.h" - -using namespace antlr4::tree; -using namespace antlr4::tree::pattern; - -using namespace antlrcpp; - -ParseTreePattern::ParseTreePattern(ParseTreePatternMatcher *matcher, const std::string &pattern, int patternRuleIndex_, - ParseTree *patternTree) - : patternRuleIndex(patternRuleIndex_), _pattern(pattern), _patternTree(patternTree), _matcher(matcher) { -} - -ParseTreePattern::~ParseTreePattern() { -} - -ParseTreeMatch ParseTreePattern::match(ParseTree *tree) { - return _matcher->match(tree, *this); -} - -bool ParseTreePattern::matches(ParseTree *tree) { - return _matcher->match(tree, *this).succeeded(); -} - -std::vector ParseTreePattern::findAll(ParseTree *tree, const std::string &xpath) { - xpath::XPath finder(_matcher->getParser(), xpath); - std::vector subtrees = finder.evaluate(tree); - std::vector matches; - for (auto *t : subtrees) { - ParseTreeMatch aMatch = match(t); - if (aMatch.succeeded()) { - matches.push_back(aMatch); - } - } - return matches; -} - - -ParseTreePatternMatcher *ParseTreePattern::getMatcher() const { - return _matcher; -} - -std::string ParseTreePattern::getPattern() const { - return _pattern; -} - -int ParseTreePattern::getPatternRuleIndex() const { - return patternRuleIndex; -} - -ParseTree* ParseTreePattern::getPatternTree() const { - return _patternTree; -} diff --git a/src/include/tree/pattern/ParseTreePattern.h b/src/include/tree/pattern/ParseTreePattern.h deleted file mode 100755 index d5b86ff4..00000000 --- a/src/include/tree/pattern/ParseTreePattern.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace tree { -namespace pattern { - - /// - /// A pattern like {@code = ;} converted to a by - /// . - /// - class ANTLR4CPP_PUBLIC ParseTreePattern { - public: - /// - /// Construct a new instance of the class. - /// - /// The which created this - /// tree pattern. - /// The tree pattern in concrete syntax form. - /// The parser rule which serves as the root of the - /// tree pattern. - /// The tree pattern in form. - ParseTreePattern(ParseTreePatternMatcher *matcher, const std::string &pattern, int patternRuleIndex, - ParseTree *patternTree); - ParseTreePattern(ParseTreePattern const&) = default; - virtual ~ParseTreePattern(); - - /// - /// Match a specific parse tree against this tree pattern. - /// - /// The parse tree to match against this tree pattern. - /// A object describing the result of the - /// match operation. The method can be - /// used to determine whether or not the match was successful. - virtual ParseTreeMatch match(ParseTree *tree); - - /// - /// Determine whether or not a parse tree matches this tree pattern. - /// - /// The parse tree to match against this tree pattern. - /// {@code true} if {@code tree} is a match for the current tree - /// pattern; otherwise, {@code false}. - virtual bool matches(ParseTree *tree); - - /// Find all nodes using XPath and then try to match those subtrees against - /// this tree pattern. - /// @param tree The ParseTree to match against this pattern. - /// @param xpath An expression matching the nodes - /// - /// @returns A collection of ParseTreeMatch objects describing the - /// successful matches. Unsuccessful matches are omitted from the result, - /// regardless of the reason for the failure. - virtual std::vector findAll(ParseTree *tree, const std::string &xpath); - - /// - /// Get the which created this tree pattern. - /// - /// The which created this tree - /// pattern. - virtual ParseTreePatternMatcher *getMatcher() const; - - /// - /// Get the tree pattern in concrete syntax form. - /// - /// The tree pattern in concrete syntax form. - virtual std::string getPattern() const; - - /// - /// Get the parser rule which serves as the outermost rule for the tree - /// pattern. - /// - /// The parser rule which serves as the outermost rule for the tree - /// pattern. - virtual int getPatternRuleIndex() const; - - /// - /// Get the tree pattern as a . The rule and token tags from - /// the pattern are present in the parse tree as terminal nodes with a symbol - /// of type or . - /// - /// The tree pattern as a . - virtual ParseTree* getPatternTree() const; - - private: - const int patternRuleIndex; - - /// This is the backing field for . - const std::string _pattern; - - /// This is the backing field for . - ParseTree *_patternTree; - - /// This is the backing field for . - ParseTreePatternMatcher *const _matcher; - }; - -} // namespace pattern -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/pattern/ParseTreePatternMatcher.cpp b/src/include/tree/pattern/ParseTreePatternMatcher.cpp deleted file mode 100755 index cbc4076b..00000000 --- a/src/include/tree/pattern/ParseTreePatternMatcher.cpp +++ /dev/null @@ -1,370 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/pattern/ParseTreePattern.h" -#include "tree/pattern/ParseTreeMatch.h" -#include "tree/TerminalNode.h" -#include "CommonTokenStream.h" -#include "ParserInterpreter.h" -#include "tree/pattern/TokenTagToken.h" -#include "ParserRuleContext.h" -#include "tree/pattern/RuleTagToken.h" -#include "tree/pattern/TagChunk.h" -#include "atn/ATN.h" -#include "Lexer.h" -#include "BailErrorStrategy.h" - -#include "ListTokenSource.h" -#include "tree/pattern/TextChunk.h" -#include "ANTLRInputStream.h" -#include "support/Arrays.h" -#include "Exceptions.h" -#include "support/CPPUtils.h" - -#include "tree/pattern/ParseTreePatternMatcher.h" - -using namespace antlr4; -using namespace antlr4::tree; -using namespace antlr4::tree::pattern; -using namespace antlrcpp; - -ParseTreePatternMatcher::CannotInvokeStartRule::CannotInvokeStartRule(const RuntimeException &e) : RuntimeException(e.what()) { -} - -ParseTreePatternMatcher::CannotInvokeStartRule::~CannotInvokeStartRule() { -} - -ParseTreePatternMatcher::StartRuleDoesNotConsumeFullPattern::~StartRuleDoesNotConsumeFullPattern() { -} - -ParseTreePatternMatcher::ParseTreePatternMatcher(Lexer *lexer, Parser *parser) : _lexer(lexer), _parser(parser) { - InitializeInstanceFields(); -} - -ParseTreePatternMatcher::~ParseTreePatternMatcher() { -} - -void ParseTreePatternMatcher::setDelimiters(const std::string &start, const std::string &stop, const std::string &escapeLeft) { - if (start.empty()) { - throw IllegalArgumentException("start cannot be null or empty"); - } - - if (stop.empty()) { - throw IllegalArgumentException("stop cannot be null or empty"); - } - - _start = start; - _stop = stop; - _escape = escapeLeft; -} - -bool ParseTreePatternMatcher::matches(ParseTree *tree, const std::string &pattern, int patternRuleIndex) { - ParseTreePattern p = compile(pattern, patternRuleIndex); - return matches(tree, p); -} - -bool ParseTreePatternMatcher::matches(ParseTree *tree, const ParseTreePattern &pattern) { - std::map> labels; - ParseTree *mismatchedNode = matchImpl(tree, pattern.getPatternTree(), labels); - return mismatchedNode == nullptr; -} - -ParseTreeMatch ParseTreePatternMatcher::match(ParseTree *tree, const std::string &pattern, int patternRuleIndex) { - ParseTreePattern p = compile(pattern, patternRuleIndex); - return match(tree, p); -} - -ParseTreeMatch ParseTreePatternMatcher::match(ParseTree *tree, const ParseTreePattern &pattern) { - std::map> labels; - tree::ParseTree *mismatchedNode = matchImpl(tree, pattern.getPatternTree(), labels); - return ParseTreeMatch(tree, pattern, labels, mismatchedNode); -} - -ParseTreePattern ParseTreePatternMatcher::compile(const std::string &pattern, int patternRuleIndex) { - ListTokenSource tokenSrc(tokenize(pattern)); - CommonTokenStream tokens(&tokenSrc); - - ParserInterpreter parserInterp(_parser->getGrammarFileName(), _parser->getVocabulary(), - _parser->getRuleNames(), _parser->getATNWithBypassAlts(), &tokens); - - ParserRuleContext *tree = nullptr; - try { - parserInterp.setErrorHandler(std::make_shared()); - tree = parserInterp.parse(patternRuleIndex); - } catch (ParseCancellationException &e) { -#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026 - // rethrow_if_nested is not available before VS 2015. - throw e; -#else - std::rethrow_if_nested(e); // Unwrap the nested exception. -#endif - } catch (RecognitionException &re) { - throw re; -#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026 - } catch (std::exception &e) { - // throw_with_nested is not available before VS 2015. - throw e; -#else - } catch (std::exception & /*e*/) { - std::throw_with_nested(RuntimeException("Cannot invoke start rule")); // Wrap any other exception. -#endif - } - - // Make sure tree pattern compilation checks for a complete parse - if (tokens.LA(1) != Token::EOF) { - throw StartRuleDoesNotConsumeFullPattern(); - } - - return ParseTreePattern(this, pattern, patternRuleIndex, tree); -} - -Lexer* ParseTreePatternMatcher::getLexer() { - return _lexer; -} - -Parser* ParseTreePatternMatcher::getParser() { - return _parser; -} - -ParseTree* ParseTreePatternMatcher::matchImpl(ParseTree *tree, ParseTree *patternTree, - std::map> &labels) { - if (tree == nullptr) { - throw IllegalArgumentException("tree cannot be nul"); - } - - if (patternTree == nullptr) { - throw IllegalArgumentException("patternTree cannot be nul"); - } - - // x and , x and y, or x and x; or could be mismatched types - if (is(tree) && is(patternTree)) { - TerminalNode *t1 = dynamic_cast(tree); - TerminalNode *t2 = dynamic_cast(patternTree); - - ParseTree *mismatchedNode = nullptr; - // both are tokens and they have same type - if (t1->getSymbol()->getType() == t2->getSymbol()->getType()) { - if (is(t2->getSymbol())) { // x and - TokenTagToken *tokenTagToken = dynamic_cast(t2->getSymbol()); - - // track label->list-of-nodes for both token name and label (if any) - labels[tokenTagToken->getTokenName()].push_back(tree); - if (tokenTagToken->getLabel() != "") { - labels[tokenTagToken->getLabel()].push_back(tree); - } - } else if (t1->getText() == t2->getText()) { - // x and x - } else { - // x and y - if (mismatchedNode == nullptr) { - mismatchedNode = t1; - } - } - } else { - if (mismatchedNode == nullptr) { - mismatchedNode = t1; - } - } - - return mismatchedNode; - } - - if (is(tree) && is(patternTree)) { - ParserRuleContext *r1 = dynamic_cast(tree); - ParserRuleContext *r2 = dynamic_cast(patternTree); - ParseTree *mismatchedNode = nullptr; - - // (expr ...) and - RuleTagToken *ruleTagToken = getRuleTagToken(r2); - if (ruleTagToken != nullptr) { - //ParseTreeMatch *m = nullptr; // unused? - if (r1->getRuleIndex() == r2->getRuleIndex()) { - // track label->list-of-nodes for both rule name and label (if any) - labels[ruleTagToken->getRuleName()].push_back(tree); - if (ruleTagToken->getLabel() != "") { - labels[ruleTagToken->getLabel()].push_back(tree); - } - } else { - if (!mismatchedNode) { - mismatchedNode = r1; - } - } - - return mismatchedNode; - } - - // (expr ...) and (expr ...) - if (r1->children.size() != r2->children.size()) { - if (mismatchedNode == nullptr) { - mismatchedNode = r1; - } - - return mismatchedNode; - } - - std::size_t n = r1->children.size(); - for (size_t i = 0; i < n; i++) { - ParseTree *childMatch = matchImpl(r1->children[i], patternTree->children[i], labels); - if (childMatch) { - return childMatch; - } - } - - return mismatchedNode; - } - - // if nodes aren't both tokens or both rule nodes, can't match - return tree; -} - -RuleTagToken* ParseTreePatternMatcher::getRuleTagToken(ParseTree *t) { - if (t->children.size() == 1 && is(t->children[0])) { - TerminalNode *c = dynamic_cast(t->children[0]); - if (is(c->getSymbol())) { - return dynamic_cast(c->getSymbol()); - } - } - return nullptr; -} - -std::vector> ParseTreePatternMatcher::tokenize(const std::string &pattern) { - // split pattern into chunks: sea (raw input) and islands (, ) - std::vector chunks = split(pattern); - - // create token stream from text and tags - std::vector> tokens; - for (auto chunk : chunks) { - if (is(&chunk)) { - TagChunk &tagChunk = (TagChunk&)chunk; - // add special rule token or conjure up new token from name - if (isupper(tagChunk.getTag()[0])) { - size_t ttype = _parser->getTokenType(tagChunk.getTag()); - if (ttype == Token::INVALID_TYPE) { - throw IllegalArgumentException("Unknown token " + tagChunk.getTag() + " in pattern: " + pattern); - } - tokens.emplace_back(new TokenTagToken(tagChunk.getTag(), (int)ttype, tagChunk.getLabel())); - } else if (islower(tagChunk.getTag()[0])) { - size_t ruleIndex = _parser->getRuleIndex(tagChunk.getTag()); - if (ruleIndex == INVALID_INDEX) { - throw IllegalArgumentException("Unknown rule " + tagChunk.getTag() + " in pattern: " + pattern); - } - size_t ruleImaginaryTokenType = _parser->getATNWithBypassAlts().ruleToTokenType[ruleIndex]; - tokens.emplace_back(new RuleTagToken(tagChunk.getTag(), ruleImaginaryTokenType, tagChunk.getLabel())); - } else { - throw IllegalArgumentException("invalid tag: " + tagChunk.getTag() + " in pattern: " + pattern); - } - } else { - TextChunk &textChunk = (TextChunk&)chunk; - ANTLRInputStream input(textChunk.getText()); - _lexer->setInputStream(&input); - std::unique_ptr t(_lexer->nextToken()); - while (t->getType() != Token::EOF) { - tokens.push_back(std::move(t)); - t = _lexer->nextToken(); - } - _lexer->setInputStream(nullptr); - } - } - - return tokens; -} - -std::vector ParseTreePatternMatcher::split(const std::string &pattern) { - size_t p = 0; - size_t n = pattern.length(); - std::vector chunks; - - // find all start and stop indexes first, then collect - std::vector starts; - std::vector 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)) { - starts.push_back(p); - p += _start.length(); - } else if (p == pattern.find(_stop,p)) { - stops.push_back(p); - p += _stop.length(); - } else { - p++; - } - } - - if (starts.size() > stops.size()) { - throw IllegalArgumentException("unterminated tag in pattern: " + pattern); - } - - if (starts.size() < stops.size()) { - throw IllegalArgumentException("missing start tag in pattern: " + pattern); - } - - size_t ntags = starts.size(); - for (size_t i = 0; i < ntags; i++) { - if (starts[i] >= stops[i]) { - throw IllegalArgumentException("tag delimiters out of order in pattern: " + pattern); - } - } - - // collect into chunks now - if (ntags == 0) { - std::string text = pattern.substr(0, n); - chunks.push_back(TextChunk(text)); - } - - if (ntags > 0 && starts[0] > 0) { // copy text up to first tag into chunks - std::string text = pattern.substr(0, starts[0]); - chunks.push_back(TextChunk(text)); - } - - for (size_t i = 0; i < ntags; i++) { - // copy inside of - std::string tag = pattern.substr(starts[i] + _start.length(), stops[i] - (starts[i] + _start.length())); - std::string ruleOrToken = tag; - std::string label = ""; - size_t colon = tag.find(':'); - if (colon != std::string::npos) { - label = tag.substr(0,colon); - ruleOrToken = tag.substr(colon + 1, tag.length() - (colon + 1)); - } - chunks.push_back(TagChunk(label, ruleOrToken)); - if (i + 1 < ntags) { - // copy from end of to start of next - std::string text = pattern.substr(stops[i] + _stop.length(), starts[i + 1] - (stops[i] + _stop.length())); - chunks.push_back(TextChunk(text)); - } - } - - if (ntags > 0) { - size_t afterLastTag = stops[ntags - 1] + _stop.length(); - if (afterLastTag < n) { // copy text from end of last tag to end - std::string text = pattern.substr(afterLastTag, n - afterLastTag); - chunks.push_back(TextChunk(text)); - } - } - - // strip out all backslashes from text chunks but not tags - for (size_t i = 0; i < chunks.size(); i++) { - Chunk &c = chunks[i]; - if (is(&c)) { - TextChunk &tc = (TextChunk&)c; - std::string unescaped = tc.getText(); - unescaped.erase(std::remove(unescaped.begin(), unescaped.end(), '\\'), unescaped.end()); - if (unescaped.length() < tc.getText().length()) { - chunks[i] = TextChunk(unescaped); - } - } - } - - return chunks; -} - -void ParseTreePatternMatcher::InitializeInstanceFields() { - _start = "<"; - _stop = ">"; - _escape = "\\"; -} diff --git a/src/include/tree/pattern/ParseTreePatternMatcher.h b/src/include/tree/pattern/ParseTreePatternMatcher.h deleted file mode 100755 index e77c7bc5..00000000 --- a/src/include/tree/pattern/ParseTreePatternMatcher.h +++ /dev/null @@ -1,185 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "Exceptions.h" - -namespace antlr4 { -namespace tree { -namespace pattern { - - /// - /// A tree pattern matching mechanism for ANTLR s. - ///

- /// Patterns are strings of source input text with special tags representing - /// token or rule references such as: - ///

- /// {@code = ;} - ///

- /// Given a pattern start rule such as {@code statement}, this object constructs - /// a with placeholders for the {@code ID} and {@code expr} - /// subtree. Then the routines can compare an actual - /// from a parse with this pattern. Tag {@code } matches - /// any {@code ID} token and tag {@code } references the result of the - /// {@code expr} rule (generally an instance of {@code ExprContext}. - ///

- /// Pattern {@code x = 0;} is a similar pattern that matches the same pattern - /// except that it requires the identifier to be {@code x} and the expression to - /// be {@code 0}. - ///

- /// The routines return {@code true} or {@code false} based - /// upon a match for the tree rooted at the parameter sent in. The - /// routines return a object that - /// contains the parse tree, the parse tree pattern, and a map from tag name to - /// matched nodes (more below). A subtree that fails to match, returns with - /// set to the first tree node that did not - /// match. - ///

- /// For efficiency, you can compile a tree pattern in string form to a - /// object. - ///

- /// See {@code TestParseTreeMatcher} for lots of examples. - /// has two static helper methods: - /// and that - /// are easy to use but not super efficient because they create new - /// objects each time and have to compile the - /// pattern in string form before using it. - ///

- /// The lexer and parser that you pass into the - /// constructor are used to parse the pattern in string form. The lexer converts - /// the {@code = ;} into a sequence of four tokens (assuming lexer - /// throws out whitespace or puts it on a hidden channel). Be aware that the - /// input stream is reset for the lexer (but not the parser; a - /// is created to parse the input.). Any user-defined - /// fields you have put into the lexer might get changed when this mechanism asks - /// it to scan the pattern string. - ///

- /// Normally a parser does not accept token {@code } as a valid - /// {@code expr} but, from the parser passed in, we create a special version of - /// the underlying grammar representation (an ) that allows imaginary - /// tokens representing rules ({@code }) to match entire rules. We call - /// these bypass alternatives. - ///

- /// Delimiters are {@code <} and {@code >}, with {@code \} as the escape string - /// by default, but you can set them to whatever you want using - /// . You must escape both start and stop strings - /// {@code \<} and {@code \>}. - ///

- class ANTLR4CPP_PUBLIC ParseTreePatternMatcher { - public: - class CannotInvokeStartRule : public RuntimeException { - public: - CannotInvokeStartRule(const RuntimeException &e); - ~CannotInvokeStartRule(); - }; - - // Fixes https://github.com/antlr/antlr4/issues/413 - // "Tree pattern compilation doesn't check for a complete parse" - class StartRuleDoesNotConsumeFullPattern : public RuntimeException { - public: - StartRuleDoesNotConsumeFullPattern() = default; - StartRuleDoesNotConsumeFullPattern(StartRuleDoesNotConsumeFullPattern const&) = default; - ~StartRuleDoesNotConsumeFullPattern(); - - StartRuleDoesNotConsumeFullPattern& operator=(StartRuleDoesNotConsumeFullPattern const&) = default; - }; - - /// Constructs a or from a and - /// object. The lexer input stream is altered for tokenizing - /// the tree patterns. The parser is used as a convenient mechanism to get - /// the grammar name, plus token, rule names. - ParseTreePatternMatcher(Lexer *lexer, Parser *parser); - virtual ~ParseTreePatternMatcher(); - - /// - /// Set the delimiters used for marking rule and token tags within concrete - /// syntax used by the tree pattern parser. - /// - /// The start delimiter. - /// The stop delimiter. - /// The escape sequence to use for escaping a start or stop delimiter. - /// - /// if {@code start} is {@code null} or empty. - /// if {@code stop} is {@code null} or empty. - virtual void setDelimiters(const std::string &start, const std::string &stop, const std::string &escapeLeft); - - /// - /// Does {@code pattern} matched as rule {@code patternRuleIndex} match {@code tree}? - virtual bool matches(ParseTree *tree, const std::string &pattern, int patternRuleIndex); - - /// - /// Does {@code pattern} matched as rule patternRuleIndex match tree? Pass in a - /// compiled pattern instead of a string representation of a tree pattern. - /// - virtual bool matches(ParseTree *tree, const ParseTreePattern &pattern); - - /// - /// Compare {@code pattern} matched as rule {@code patternRuleIndex} against - /// {@code tree} and return a object that contains the - /// matched elements, or the node at which the match failed. - /// - virtual ParseTreeMatch match(ParseTree *tree, const std::string &pattern, int patternRuleIndex); - - /// - /// Compare {@code pattern} matched against {@code tree} and return a - /// object that contains the matched elements, or the - /// node at which the match failed. Pass in a compiled pattern instead of a - /// string representation of a tree pattern. - /// - virtual ParseTreeMatch match(ParseTree *tree, const ParseTreePattern &pattern); - - /// - /// For repeated use of a tree pattern, compile it to a - /// using this method. - /// - virtual ParseTreePattern compile(const std::string &pattern, int patternRuleIndex); - - /// - /// Used to convert the tree pattern string into a series of tokens. The - /// input stream is reset. - /// - virtual Lexer* getLexer(); - - /// - /// Used to collect to the grammar file name, token names, rule names for - /// used to parse the pattern into a parse tree. - /// - virtual Parser* getParser(); - - // ---- SUPPORT CODE ---- - - virtual std::vector> tokenize(const std::string &pattern); - - /// Split " = ;" into 4 chunks for tokenizing by tokenize(). - virtual std::vector split(const std::string &pattern); - - protected: - std::string _start; - std::string _stop; - std::string _escape; // e.g., \< and \> must escape BOTH! - - /// Recursively walk {@code tree} against {@code patternTree}, filling - /// {@code match.}. - /// - /// the first node encountered in {@code tree} which does not match - /// a corresponding node in {@code patternTree}, or {@code null} if the match - /// was successful. The specific node returned depends on the matching - /// algorithm used by the implementation, and may be overridden. - virtual ParseTree* matchImpl(ParseTree *tree, ParseTree *patternTree, std::map> &labels); - - /// Is t subtree? - virtual RuleTagToken* getRuleTagToken(ParseTree *t); - - private: - Lexer *_lexer; - Parser *_parser; - - void InitializeInstanceFields(); - }; - -} // namespace pattern -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/pattern/RuleTagToken.cpp b/src/include/tree/pattern/RuleTagToken.cpp deleted file mode 100755 index 4e33f989..00000000 --- a/src/include/tree/pattern/RuleTagToken.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "Exceptions.h" - -#include "tree/pattern/RuleTagToken.h" - -using namespace antlr4::tree::pattern; - -RuleTagToken::RuleTagToken(const std::string &/*ruleName*/, int _bypassTokenType) : bypassTokenType(_bypassTokenType) { -} - -RuleTagToken::RuleTagToken(const std::string &ruleName, size_t bypassTokenType, const std::string &label) - : ruleName(ruleName), bypassTokenType(bypassTokenType), label(label) { - if (ruleName.empty()) { - throw IllegalArgumentException("ruleName cannot be null or empty."); - } - -} - -std::string RuleTagToken::getRuleName() const { - return ruleName; -} - -std::string RuleTagToken::getLabel() const { - return label; -} - -size_t RuleTagToken::getChannel() const { - return DEFAULT_CHANNEL; -} - -std::string RuleTagToken::getText() const { - if (label != "") { - return std::string("<") + label + std::string(":") + ruleName + std::string(">"); - } - - return std::string("<") + ruleName + std::string(">"); -} - -size_t RuleTagToken::getType() const { - return bypassTokenType; -} - -size_t RuleTagToken::getLine() const { - return 0; -} - -size_t RuleTagToken::getCharPositionInLine() const { - return INVALID_INDEX; -} - -size_t RuleTagToken::getTokenIndex() const { - return INVALID_INDEX; -} - -size_t RuleTagToken::getStartIndex() const { - return INVALID_INDEX; -} - -size_t RuleTagToken::getStopIndex() const { - return INVALID_INDEX; -} - -antlr4::TokenSource *RuleTagToken::getTokenSource() const { - return nullptr; -} - -antlr4::CharStream *RuleTagToken::getInputStream() const { - return nullptr; -} - -std::string RuleTagToken::toString() const { - return ruleName + ":" + std::to_string(bypassTokenType); -} diff --git a/src/include/tree/pattern/RuleTagToken.h b/src/include/tree/pattern/RuleTagToken.h deleted file mode 100755 index 368ae41b..00000000 --- a/src/include/tree/pattern/RuleTagToken.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "Token.h" - -namespace antlr4 { -namespace tree { -namespace pattern { - - /// - /// A object representing an entire subtree matched by a parser - /// rule; e.g., {@code }. These tokens are created for - /// chunks where the tag corresponds to a parser rule. - /// - class ANTLR4CPP_PUBLIC RuleTagToken : public Token { - /// - /// This is the backing field for . - /// - private: - const std::string ruleName; - - /// The token type for the current token. This is the token type assigned to - /// the bypass alternative for the rule during ATN deserialization. - const size_t bypassTokenType; - - /// This is the backing field for . - const std::string label; - - public: - /// - /// Constructs a new instance of with the specified rule - /// name and bypass token type and no label. - /// - /// The name of the parser rule this rule tag matches. - /// The bypass token type assigned to the parser rule. - /// - /// if {@code ruleName} is {@code null} - /// or empty. - RuleTagToken(const std::string &ruleName, int bypassTokenType); //this(ruleName, bypassTokenType, nullptr); - - /// - /// Constructs a new instance of with the specified rule - /// name, bypass token type, and label. - /// - /// The name of the parser rule this rule tag matches. - /// The bypass token type assigned to the parser rule. - /// The label associated with the rule tag, or {@code null} if - /// the rule tag is unlabeled. - /// - /// if {@code ruleName} is {@code null} - /// or empty. - RuleTagToken(const std::string &ruleName, size_t bypassTokenType, const std::string &label); - - /// - /// Gets the name of the rule associated with this rule tag. - /// - /// The name of the parser rule associated with this rule tag. - std::string getRuleName() const; - - /// - /// Gets the label associated with the rule tag. - /// - /// The name of the label associated with the rule tag, or - /// {@code null} if this is an unlabeled rule tag. - std::string getLabel() const; - - /// - /// {@inheritDoc} - ///

- /// Rule tag tokens are always placed on the . - ///

- virtual size_t getChannel() const override; - - /// - /// {@inheritDoc} - ///

- /// This method returns the rule tag formatted with {@code <} and {@code >} - /// delimiters. - ///

- virtual std::string getText() const override; - - /// Rule tag tokens have types assigned according to the rule bypass - /// transitions created during ATN deserialization. - virtual size_t getType() const override; - - /// The implementation for always returns 0. - virtual size_t getLine() const override; - - /// The implementation for always returns INVALID_INDEX. - virtual size_t getCharPositionInLine() const override; - - /// The implementation for always returns INVALID_INDEX. - virtual size_t getTokenIndex() const override; - - /// The implementation for always returns INVALID_INDEX. - virtual size_t getStartIndex() const override; - - /// The implementation for always returns INVALID_INDEX. - virtual size_t getStopIndex() const override; - - /// The implementation for always returns {@code null}. - virtual TokenSource *getTokenSource() const override; - - /// The implementation for always returns {@code null}. - virtual CharStream *getInputStream() const override; - - /// The implementation for returns a string of the form {@code ruleName:bypassTokenType}. - virtual std::string toString() const override; - }; - -} // namespace pattern -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/pattern/TagChunk.cpp b/src/include/tree/pattern/TagChunk.cpp deleted file mode 100755 index 77f2b4c9..00000000 --- a/src/include/tree/pattern/TagChunk.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "Exceptions.h" - -#include "tree/pattern/TagChunk.h" - -using namespace antlr4::tree::pattern; - -TagChunk::TagChunk(const std::string &tag) : TagChunk("", tag) { -} - -TagChunk::TagChunk(const std::string &label, const std::string &tag) : _tag(tag), _label(label) { - if (tag.empty()) { - throw IllegalArgumentException("tag cannot be null or empty"); - } - -} - -TagChunk::~TagChunk() { -} - -std::string TagChunk::getTag() { - return _tag; -} - -std::string TagChunk::getLabel() { - return _label; -} - -std::string TagChunk::toString() { - if (!_label.empty()) { - return _label + ":" + _tag; - } - - return _tag; -} diff --git a/src/include/tree/pattern/TagChunk.h b/src/include/tree/pattern/TagChunk.h deleted file mode 100755 index 3d0c9f8d..00000000 --- a/src/include/tree/pattern/TagChunk.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "Chunk.h" - -namespace antlr4 { -namespace tree { -namespace pattern { - - /// - /// Represents a placeholder tag in a tree pattern. A tag can have any of the - /// following forms. - /// - ///
    - ///
  • {@code expr}: An unlabeled placeholder for a parser rule {@code expr}.
  • - ///
  • {@code ID}: An unlabeled placeholder for a token of type {@code ID}.
  • - ///
  • {@code e:expr}: A labeled placeholder for a parser rule {@code expr}.
  • - ///
  • {@code id:ID}: A labeled placeholder for a token of type {@code ID}.
  • - ///
- /// - /// This class does not perform any validation on the tag or label names aside - /// from ensuring that the tag is a non-null, non-empty string. - ///
- class ANTLR4CPP_PUBLIC TagChunk : public Chunk { - public: - /// - /// Construct a new instance of using the specified tag and - /// no label. - /// - /// The tag, which should be the name of a parser rule or token - /// type. - /// - /// if {@code tag} is {@code null} or - /// empty. - TagChunk(const std::string &tag); - virtual ~TagChunk(); - - /// - /// Construct a new instance of using the specified label - /// and tag. - /// - /// The label for the tag. If this is {@code null}, the - /// represents an unlabeled tag. - /// The tag, which should be the name of a parser rule or token - /// type. - /// - /// if {@code tag} is {@code null} or - /// empty. - TagChunk(const std::string &label, const std::string &tag); - - /// - /// Get the tag for this chunk. - /// - /// The tag for the chunk. - std::string getTag(); - - /// - /// Get the label, if any, assigned to this chunk. - /// - /// The label assigned to this chunk, or {@code null} if no label is - /// assigned to the chunk. - std::string getLabel(); - - /// - /// This method returns a text representation of the tag chunk. Labeled tags - /// are returned in the form {@code label:tag}, and unlabeled tags are - /// returned as just the tag name. - /// - virtual std::string toString() override; - - private: - /// This is the backing field for . - const std::string _tag; - /// - /// This is the backing field for . - /// - const std::string _label; - }; - -} // namespace pattern -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/pattern/TextChunk.cpp b/src/include/tree/pattern/TextChunk.cpp deleted file mode 100755 index f8dcfb0d..00000000 --- a/src/include/tree/pattern/TextChunk.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "Exceptions.h" - -#include "tree/pattern/TextChunk.h" - -using namespace antlr4::tree::pattern; - -TextChunk::TextChunk(const std::string &text) : text(text) { - if (text == "") { - throw IllegalArgumentException("text cannot be nul"); - } - -} - -TextChunk::~TextChunk() { -} - -std::string TextChunk::getText() { - return text; -} - -std::string TextChunk::toString() { - return std::string("'") + text + std::string("'"); -} diff --git a/src/include/tree/pattern/TextChunk.h b/src/include/tree/pattern/TextChunk.h deleted file mode 100755 index 1cbc0ddb..00000000 --- a/src/include/tree/pattern/TextChunk.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "Chunk.h" - -namespace antlr4 { -namespace tree { -namespace pattern { - - /// - /// Represents a span of raw text (concrete syntax) between tags in a tree - /// pattern string. - /// - class ANTLR4CPP_PUBLIC TextChunk : public Chunk { - private: - /// - /// This is the backing field for . - /// - const std::string text; - - /// - /// Constructs a new instance of with the specified text. - /// - /// The text of this chunk. - /// if {@code text} is {@code null}. - public: - TextChunk(const std::string &text); - virtual ~TextChunk(); - - /// - /// Gets the raw text of this chunk. - /// - /// The text of the chunk. - std::string getText(); - - /// - /// {@inheritDoc} - ///

- /// The implementation for returns the result of - /// in single quotes. - ///

- virtual std::string toString() override; - }; - -} // namespace pattern -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/pattern/TokenTagToken.cpp b/src/include/tree/pattern/TokenTagToken.cpp deleted file mode 100755 index 7d6cc9a9..00000000 --- a/src/include/tree/pattern/TokenTagToken.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/pattern/TokenTagToken.h" - -using namespace antlr4::tree::pattern; - -TokenTagToken::TokenTagToken(const std::string &/*tokenName*/, int type) - : CommonToken(type), tokenName(""), label("") { -} - -TokenTagToken::TokenTagToken(const std::string &tokenName, int type, const std::string &label) - : CommonToken(type), tokenName(tokenName), label(label) { -} - -std::string TokenTagToken::getTokenName() const { - return tokenName; -} - -std::string TokenTagToken::getLabel() const { - return label; -} - -std::string TokenTagToken::getText() const { - if (!label.empty()) { - return "<" + label + ":" + tokenName + ">"; - } - - return "<" + tokenName + ">"; -} - -std::string TokenTagToken::toString() const { - return tokenName + ":" + std::to_string(_type); -} diff --git a/src/include/tree/pattern/TokenTagToken.h b/src/include/tree/pattern/TokenTagToken.h deleted file mode 100755 index 9013fb8c..00000000 --- a/src/include/tree/pattern/TokenTagToken.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "CommonToken.h" - -namespace antlr4 { -namespace tree { -namespace pattern { - - /// - /// A object representing a token of a particular type; e.g., - /// {@code }. These tokens are created for chunks where the - /// tag corresponds to a lexer rule or token type. - /// - class ANTLR4CPP_PUBLIC TokenTagToken : public CommonToken { - /// - /// This is the backing field for . - /// - private: - const std::string tokenName; - /// - /// This is the backing field for . - /// - const std::string label; - - /// - /// Constructs a new instance of for an unlabeled tag - /// with the specified token name and type. - /// - /// The token name. - /// The token type. - public: - TokenTagToken(const std::string &tokenName, int type); //this(tokenName, type, nullptr); - - /// - /// Constructs a new instance of with the specified - /// token name, type, and label. - /// - /// The token name. - /// The token type. - /// The label associated with the token tag, or {@code null} if - /// the token tag is unlabeled. - TokenTagToken(const std::string &tokenName, int type, const std::string &label); - - /// - /// Gets the token name. - /// The token name. - std::string getTokenName() const; - - /// - /// Gets the label associated with the rule tag. - /// - /// The name of the label associated with the rule tag, or - /// {@code null} if this is an unlabeled rule tag. - std::string getLabel() const; - - /// - /// {@inheritDoc} - ///

- /// The implementation for returns the token tag - /// formatted with {@code <} and {@code >} delimiters. - ///

- virtual std::string getText() const override; - - /// - /// {@inheritDoc} - ///

- /// The implementation for returns a string of the form - /// {@code tokenName:type}. - ///

- virtual std::string toString() const override; - }; - -} // namespace pattern -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/xpath/XPath.cpp b/src/include/tree/xpath/XPath.cpp deleted file mode 100755 index c0398962..00000000 --- a/src/include/tree/xpath/XPath.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "XPathLexer.h" -#include "XPathLexerErrorListener.h" -#include "XPathElement.h" -#include "XPathWildcardAnywhereElement.h" -#include "XPathWildcardElement.h" -#include "XPathTokenAnywhereElement.h" -#include "XPathTokenElement.h" -#include "XPathRuleAnywhereElement.h" -#include "XPathRuleElement.h" - -#include "XPath.h" - -using namespace antlr4; -using namespace antlr4::tree; -using namespace antlr4::tree::xpath; - -const std::string XPath::WILDCARD = "*"; -const std::string XPath::NOT = "!"; - -XPath::XPath(Parser *parser, const std::string &path) { - _parser = parser; - _path = path; -} - -std::vector> XPath::split(const std::string &path) { - ANTLRInputStream in(path); - XPathLexer lexer(&in); - lexer.removeErrorListeners(); - XPathLexerErrorListener listener; - lexer.addErrorListener(&listener); - CommonTokenStream tokenStream(&lexer); - try { - tokenStream.fill(); - } catch (LexerNoViableAltException &) { - size_t pos = lexer.getCharPositionInLine(); - std::string msg = "Invalid tokens or characters at index " + std::to_string(pos) + " in path '" + path + "'"; - throw IllegalArgumentException(msg); - } - - std::vector tokens = tokenStream.getTokens(); - std::vector> elements; - size_t n = tokens.size(); - size_t i = 0; - bool done = false; - while (!done && i < n) { - Token *el = tokens[i]; - Token *next = nullptr; - switch (el->getType()) { - case XPathLexer::ROOT: - case XPathLexer::ANYWHERE: { - bool anywhere = el->getType() == XPathLexer::ANYWHERE; - i++; - next = tokens[i]; - bool invert = next->getType() == XPathLexer::BANG; - if (invert) { - i++; - next = tokens[i]; - } - std::unique_ptr pathElement = getXPathElement(next, anywhere); - pathElement->setInvert(invert); - elements.push_back(std::move(pathElement)); - i++; - break; - - } - case XPathLexer::TOKEN_REF: - case XPathLexer::RULE_REF: - case XPathLexer::WILDCARD: - elements.push_back(getXPathElement(el, false)); - i++; - break; - - case Token::EOF: - done = true; - break; - - default : - throw IllegalArgumentException("Unknown path element " + el->toString()); - } - } - - return elements; -} - -std::unique_ptr XPath::getXPathElement(Token *wordToken, bool anywhere) { - if (wordToken->getType() == Token::EOF) { - throw IllegalArgumentException("Missing path element at end of path"); - } - - std::string word = wordToken->getText(); - size_t ttype = _parser->getTokenType(word); - ssize_t ruleIndex = _parser->getRuleIndex(word); - switch (wordToken->getType()) { - case XPathLexer::WILDCARD : - if (anywhere) - return std::unique_ptr(new XPathWildcardAnywhereElement()); - return std::unique_ptr(new XPathWildcardElement()); - - case XPathLexer::TOKEN_REF: - case XPathLexer::STRING : - if (ttype == Token::INVALID_TYPE) { - throw IllegalArgumentException(word + " at index " + std::to_string(wordToken->getStartIndex()) + " isn't a valid token name"); - } - if (anywhere) - return std::unique_ptr(new XPathTokenAnywhereElement(word, (int)ttype)); - return std::unique_ptr(new XPathTokenElement(word, (int)ttype)); - - default : - if (ruleIndex == -1) { - throw IllegalArgumentException(word + " at index " + std::to_string(wordToken->getStartIndex()) + " isn't a valid rule name"); - } - if (anywhere) - return std::unique_ptr(new XPathRuleAnywhereElement(word, (int)ruleIndex)); - return std::unique_ptr(new XPathRuleElement(word, (int)ruleIndex)); - } -} - -static ParserRuleContext dummyRoot; - -std::vector XPath::findAll(ParseTree *tree, std::string const& xpath, Parser *parser) { - XPath p(parser, xpath); - return p.evaluate(tree); -} - -std::vector XPath::evaluate(ParseTree *t) { - dummyRoot.children = { t }; // don't set t's parent. - - std::vector work = { &dummyRoot }; - - size_t i = 0; - std::vector> elements = split(_path); - - while (i < elements.size()) { - std::vector next; - for (auto *node : work) { - if (!node->children.empty()) { - // only try to match next element if it has children - // e.g., //func/*/stat might have a token node for which - // we can't go looking for stat nodes. - auto matching = elements[i]->evaluate(node); - next.insert(next.end(), matching.begin(), matching.end()); - } - } - i++; - work = next; - } - - return work; -} diff --git a/src/include/tree/xpath/XPath.h b/src/include/tree/xpath/XPath.h deleted file mode 100755 index e38d482d..00000000 --- a/src/include/tree/xpath/XPath.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace tree { -namespace xpath { - - /// Represent a subset of XPath XML path syntax for use in identifying nodes in - /// parse trees. - /// - /// - /// Split path into words and separators {@code /} and {@code //} via ANTLR - /// itself then walk path elements from left to right. At each separator-word - /// pair, find set of nodes. Next stage uses those as work list. - /// - /// - /// The basic interface is - /// {@code (tree, pathString, parser)}. - /// But that is just shorthand for: - /// - ///
-  ///  p = new (parser, pathString);
-  /// return p.(tree);
-  /// 
- /// - /// - /// See {@code org.antlr.v4.test.TestXPath} for descriptions. In short, this - /// allows operators: - /// - ///
- ///
/
root
- ///
//
anywhere
- ///
!
invert; this must appear directly after root or anywhere - /// operator
- ///
- /// - /// - /// and path elements: - /// - ///
- ///
ID
token name
- ///
'string'
any string literal token from the grammar
- ///
expr
rule name
- ///
*
wildcard matching any node
- ///
- /// - /// - /// Whitespace is not allowed. - - class ANTLR4CPP_PUBLIC XPath { - public: - static const std::string WILDCARD; // word not operator/separator - static const std::string NOT; // word for invert operator - - XPath(Parser *parser, const std::string &path); - virtual ~XPath() {} - - // TODO: check for invalid token/rule names, bad syntax - virtual std::vector> split(const std::string &path); - - static std::vector findAll(ParseTree *tree, std::string const& xpath, Parser *parser); - - /// Return a list of all nodes starting at {@code t} as root that satisfy the - /// path. The root {@code /} is relative to the node passed to - /// . - virtual std::vector evaluate(ParseTree *t); - - protected: - std::string _path; - Parser *_parser; - - /// Convert word like {@code *} or {@code ID} or {@code expr} to a path - /// element. {@code anywhere} is {@code true} if {@code //} precedes the - /// word. - virtual std::unique_ptr getXPathElement(Token *wordToken, bool anywhere); - }; - -} // namespace xpath -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/xpath/XPathElement.cpp b/src/include/tree/xpath/XPathElement.cpp deleted file mode 100755 index 64b122df..00000000 --- a/src/include/tree/xpath/XPathElement.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "support/CPPUtils.h" - -#include "XPathElement.h" - -using namespace antlr4::tree; -using namespace antlr4::tree::xpath; - -XPathElement::XPathElement(const std::string &nodeName) { - _nodeName = nodeName; -} - -XPathElement::~XPathElement() { -} - -std::vector XPathElement::evaluate(ParseTree * /*t*/) { - return {}; -} - -std::string XPathElement::toString() const { - std::string inv = _invert ? "!" : ""; - return antlrcpp::toString(*this) + "[" + inv + _nodeName + "]"; -} - -void XPathElement::setInvert(bool value) { - _invert = value; -} diff --git a/src/include/tree/xpath/XPathElement.h b/src/include/tree/xpath/XPathElement.h deleted file mode 100755 index f339117d..00000000 --- a/src/include/tree/xpath/XPathElement.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "antlr4-common.h" - -namespace antlr4 { -namespace tree { - class ParseTree; - -namespace xpath { - - class ANTLR4CPP_PUBLIC XPathElement { - public: - /// Construct element like {@code /ID} or {@code ID} or {@code /*} etc... - /// op is null if just node - XPathElement(const std::string &nodeName); - XPathElement(XPathElement const&) = default; - virtual ~XPathElement(); - - XPathElement& operator=(XPathElement const&) = default; - - /// Given tree rooted at {@code t} return all nodes matched by this path - /// element. - virtual std::vector evaluate(ParseTree *t); - virtual std::string toString() const; - - void setInvert(bool value); - - protected: - std::string _nodeName; - bool _invert = false; - }; - -} // namespace xpath -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/xpath/XPathLexer.cpp b/src/include/tree/xpath/XPathLexer.cpp deleted file mode 100644 index bba8a150..00000000 --- a/src/include/tree/xpath/XPathLexer.cpp +++ /dev/null @@ -1,180 +0,0 @@ - -// Generated from XPathLexer.g4 by ANTLR 4.13.1 - - -#include "XPathLexer.h" - - -using namespace antlr4; - - - -using namespace antlr4; - -namespace { - -struct XPathLexerStaticData final { - XPathLexerStaticData(std::vector ruleNames, - std::vector channelNames, - std::vector modeNames, - std::vector literalNames, - std::vector symbolicNames) - : ruleNames(std::move(ruleNames)), channelNames(std::move(channelNames)), - modeNames(std::move(modeNames)), literalNames(std::move(literalNames)), - symbolicNames(std::move(symbolicNames)), - vocabulary(this->literalNames, this->symbolicNames) {} - - XPathLexerStaticData(const XPathLexerStaticData&) = delete; - XPathLexerStaticData(XPathLexerStaticData&&) = delete; - XPathLexerStaticData& operator=(const XPathLexerStaticData&) = delete; - XPathLexerStaticData& operator=(XPathLexerStaticData&&) = delete; - - std::vector decisionToDFA; - antlr4::atn::PredictionContextCache sharedContextCache; - const std::vector ruleNames; - const std::vector channelNames; - const std::vector modeNames; - const std::vector literalNames; - const std::vector symbolicNames; - const antlr4::dfa::Vocabulary vocabulary; - antlr4::atn::SerializedATNView serializedATN; - std::unique_ptr atn; -}; - -::antlr4::internal::OnceFlag xpathlexerLexerOnceFlag; -#if ANTLR4_USE_THREAD_LOCAL_CACHE -static thread_local -#endif -std::unique_ptr xpathlexerLexerStaticData = nullptr; - -void xpathlexerLexerInitialize() { -#if ANTLR4_USE_THREAD_LOCAL_CACHE - if (xpathlexerLexerStaticData != nullptr) { - return; - } -#else - assert(xpathlexerLexerStaticData == nullptr); -#endif - auto staticData = std::make_unique( - std::vector{ - "ANYWHERE", "ROOT", "WILDCARD", "BANG", "ID", "NameChar", "NameStartChar", - "STRING" - }, - std::vector{ - "DEFAULT_TOKEN_CHANNEL", "HIDDEN" - }, - std::vector{ - "DEFAULT_MODE" - }, - std::vector{ - "", "", "", "'//'", "'/'", "'*'", "'!'" - }, - std::vector{ - "", "TOKEN_REF", "RULE_REF", "ANYWHERE", "ROOT", "WILDCARD", "BANG", - "ID", "STRING" - } - ); - static const int32_t serializedATNSegment[] = { - 4,0,8,50,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6, - 2,7,7,7,1,0,1,0,1,0,1,1,1,1,1,2,1,2,1,3,1,3,1,4,1,4,5,4,29,8,4,10,4,12, - 4,32,9,4,1,4,1,4,1,5,1,5,3,5,38,8,5,1,6,1,6,1,7,1,7,5,7,44,8,7,10,7,12, - 7,47,9,7,1,7,1,7,1,45,0,8,1,3,3,4,5,5,7,6,9,7,11,0,13,0,15,8,1,0,2,5, - 0,48,57,95,95,183,183,768,879,8255,8256,13,0,65,90,97,122,192,214,216, - 246,248,767,880,893,895,8191,8204,8205,8304,8591,11264,12271,12289,55295, - 63744,64975,65008,65535,50,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1, - 0,0,0,0,9,1,0,0,0,0,15,1,0,0,0,1,17,1,0,0,0,3,20,1,0,0,0,5,22,1,0,0,0, - 7,24,1,0,0,0,9,26,1,0,0,0,11,37,1,0,0,0,13,39,1,0,0,0,15,41,1,0,0,0,17, - 18,5,47,0,0,18,19,5,47,0,0,19,2,1,0,0,0,20,21,5,47,0,0,21,4,1,0,0,0,22, - 23,5,42,0,0,23,6,1,0,0,0,24,25,5,33,0,0,25,8,1,0,0,0,26,30,3,13,6,0,27, - 29,3,11,5,0,28,27,1,0,0,0,29,32,1,0,0,0,30,28,1,0,0,0,30,31,1,0,0,0,31, - 33,1,0,0,0,32,30,1,0,0,0,33,34,6,4,0,0,34,10,1,0,0,0,35,38,3,13,6,0,36, - 38,7,0,0,0,37,35,1,0,0,0,37,36,1,0,0,0,38,12,1,0,0,0,39,40,7,1,0,0,40, - 14,1,0,0,0,41,45,5,39,0,0,42,44,9,0,0,0,43,42,1,0,0,0,44,47,1,0,0,0,45, - 46,1,0,0,0,45,43,1,0,0,0,46,48,1,0,0,0,47,45,1,0,0,0,48,49,5,39,0,0,49, - 16,1,0,0,0,4,0,30,37,45,1,1,4,0 - }; - staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0])); - - antlr4::atn::ATNDeserializer deserializer; - staticData->atn = deserializer.deserialize(staticData->serializedATN); - - const size_t count = staticData->atn->getNumberOfDecisions(); - staticData->decisionToDFA.reserve(count); - for (size_t i = 0; i < count; i++) { - staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i); - } - xpathlexerLexerStaticData = std::move(staticData); -} - -} - -XPathLexer::XPathLexer(CharStream *input) : Lexer(input) { - XPathLexer::initialize(); - _interpreter = new atn::LexerATNSimulator(this, *xpathlexerLexerStaticData->atn, xpathlexerLexerStaticData->decisionToDFA, xpathlexerLexerStaticData->sharedContextCache); -} - -XPathLexer::~XPathLexer() { - delete _interpreter; -} - -std::string XPathLexer::getGrammarFileName() const { - return "XPathLexer.g4"; -} - -const std::vector& XPathLexer::getRuleNames() const { - return xpathlexerLexerStaticData->ruleNames; -} - -const std::vector& XPathLexer::getChannelNames() const { - return xpathlexerLexerStaticData->channelNames; -} - -const std::vector& XPathLexer::getModeNames() const { - return xpathlexerLexerStaticData->modeNames; -} - -const dfa::Vocabulary& XPathLexer::getVocabulary() const { - return xpathlexerLexerStaticData->vocabulary; -} - -antlr4::atn::SerializedATNView XPathLexer::getSerializedATN() const { - return xpathlexerLexerStaticData->serializedATN; -} - -const atn::ATN& XPathLexer::getATN() const { - return *xpathlexerLexerStaticData->atn; -} - - -void XPathLexer::action(RuleContext *context, size_t ruleIndex, size_t actionIndex) { - switch (ruleIndex) { - case 4: IDAction(antlrcpp::downCast(context), actionIndex); break; - - default: - break; - } -} - -void XPathLexer::IDAction(antlr4::RuleContext *context, size_t actionIndex) { - switch (actionIndex) { - case 0: - if (isupper(getText()[0])) - setType(TOKEN_REF); - else - setType(RULE_REF); - break; - - default: - break; - } -} - - - -void XPathLexer::initialize() { -#if ANTLR4_USE_THREAD_LOCAL_CACHE - xpathlexerLexerInitialize(); -#else - ::antlr4::internal::call_once(xpathlexerLexerOnceFlag, xpathlexerLexerInitialize); -#endif -} diff --git a/src/include/tree/xpath/XPathLexer.g4 b/src/include/tree/xpath/XPathLexer.g4 deleted file mode 100644 index 14bcf5ab..00000000 --- a/src/include/tree/xpath/XPathLexer.g4 +++ /dev/null @@ -1,64 +0,0 @@ -lexer grammar XPathLexer; - -tokens { TOKEN_REF, RULE_REF } - -/* -path : separator? word (separator word)* EOF ; - -separator - : '/' '!' - | '//' '!' - | '/' - | '//' - ; - -word: TOKEN_REF - | RULE_REF - | STRING - | '*' - ; -*/ - -ANYWHERE : '//' ; -ROOT : '/' ; -WILDCARD : '*' ; -BANG : '!' ; - -ID : NameStartChar NameChar* - { - if (isupper(getText()[0])) - setType(TOKEN_REF); - else - setType(RULE_REF); - } - ; - -fragment -NameChar : NameStartChar - | '0'..'9' - | '_' - | '\u00B7' - | '\u0300'..'\u036F' - | '\u203F'..'\u2040' - ; - -fragment -NameStartChar - : 'A'..'Z' | 'a'..'z' - | '\u00C0'..'\u00D6' - | '\u00D8'..'\u00F6' - | '\u00F8'..'\u02FF' - | '\u0370'..'\u037D' - | '\u037F'..'\u1FFF' - | '\u200C'..'\u200D' - | '\u2070'..'\u218F' - | '\u2C00'..'\u2FEF' - | '\u3001'..'\uD7FF' - | '\uF900'..'\uFDCF' - | '\uFDF0'..'\uFFFF' // implicitly includes ['\u10000-'\uEFFFF] - ; - -STRING : '\'' .*? '\''; - -//WS : [ \t\r\n]+ -> skip ; - diff --git a/src/include/tree/xpath/XPathLexer.h b/src/include/tree/xpath/XPathLexer.h deleted file mode 100644 index 556e9505..00000000 --- a/src/include/tree/xpath/XPathLexer.h +++ /dev/null @@ -1,53 +0,0 @@ - -// Generated from XPathLexer.g4 by ANTLR 4.13.1 - -#pragma once - - -#include "antlr4-runtime.h" - - - - -class XPathLexer : public antlr4::Lexer { -public: - enum { - TOKEN_REF = 1, RULE_REF = 2, ANYWHERE = 3, ROOT = 4, WILDCARD = 5, BANG = 6, - ID = 7, STRING = 8 - }; - - explicit XPathLexer(antlr4::CharStream *input); - - ~XPathLexer() override; - - - std::string getGrammarFileName() const override; - - const std::vector& getRuleNames() const override; - - const std::vector& getChannelNames() const override; - - const std::vector& getModeNames() const override; - - const antlr4::dfa::Vocabulary& getVocabulary() const override; - - antlr4::atn::SerializedATNView getSerializedATN() const override; - - const antlr4::atn::ATN& getATN() const override; - - void action(antlr4::RuleContext *context, size_t ruleIndex, size_t actionIndex) override; - - // By default the static state used to implement the lexer is lazily initialized during the first - // call to the constructor. You can call this function if you wish to initialize the static state - // ahead of time. - static void initialize(); - -private: - - // Individual action functions triggered by action() above. - void IDAction(antlr4::RuleContext *context, size_t actionIndex); - - // Individual semantic predicate functions triggered by sempred() above. - -}; - diff --git a/src/include/tree/xpath/XPathLexerErrorListener.cpp b/src/include/tree/xpath/XPathLexerErrorListener.cpp deleted file mode 100755 index 2804c8ee..00000000 --- a/src/include/tree/xpath/XPathLexerErrorListener.cpp +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "XPathLexerErrorListener.h" - -using namespace antlr4; -using namespace antlr4::tree::xpath; - -void XPathLexerErrorListener::syntaxError(Recognizer * /*recognizer*/, Token * /*offendingSymbol*/, - size_t /*line*/, size_t /*charPositionInLine*/, const std::string &/*msg*/, std::exception_ptr /*e*/) { -} diff --git a/src/include/tree/xpath/XPathLexerErrorListener.h b/src/include/tree/xpath/XPathLexerErrorListener.h deleted file mode 100755 index c0c3eaac..00000000 --- a/src/include/tree/xpath/XPathLexerErrorListener.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "BaseErrorListener.h" - -namespace antlr4 { -namespace tree { -namespace xpath { - - class ANTLR4CPP_PUBLIC XPathLexerErrorListener : public BaseErrorListener { - public: - virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line, - size_t charPositionInLine, const std::string &msg, std::exception_ptr e) override; - }; - -} // namespace xpath -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/xpath/XPathRuleAnywhereElement.cpp b/src/include/tree/xpath/XPathRuleAnywhereElement.cpp deleted file mode 100755 index 9ca910df..00000000 --- a/src/include/tree/xpath/XPathRuleAnywhereElement.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/ParseTree.h" -#include "tree/Trees.h" - -#include "tree/xpath/XPathRuleAnywhereElement.h" - -using namespace antlr4::tree; -using namespace antlr4::tree::xpath; - -XPathRuleAnywhereElement::XPathRuleAnywhereElement(const std::string &ruleName, int ruleIndex) : XPathElement(ruleName) { - _ruleIndex = ruleIndex; -} - -std::vector XPathRuleAnywhereElement::evaluate(ParseTree *t) { - return Trees::findAllRuleNodes(t, _ruleIndex); -} diff --git a/src/include/tree/xpath/XPathRuleAnywhereElement.h b/src/include/tree/xpath/XPathRuleAnywhereElement.h deleted file mode 100755 index 2ceb75ce..00000000 --- a/src/include/tree/xpath/XPathRuleAnywhereElement.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "XPathElement.h" - -namespace antlr4 { -namespace tree { -namespace xpath { - - /// Either {@code ID} at start of path or {@code ...//ID} in middle of path. - class ANTLR4CPP_PUBLIC XPathRuleAnywhereElement : public XPathElement { - public: - XPathRuleAnywhereElement(const std::string &ruleName, int ruleIndex); - - virtual std::vector evaluate(ParseTree *t) override; - - protected: - int _ruleIndex = 0; - }; - -} // namespace xpath -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/xpath/XPathRuleElement.cpp b/src/include/tree/xpath/XPathRuleElement.cpp deleted file mode 100755 index 1d145fb5..00000000 --- a/src/include/tree/xpath/XPathRuleElement.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/ParseTree.h" -#include "tree/Trees.h" - -#include "XPathRuleElement.h" - -using namespace antlr4::tree; -using namespace antlr4::tree::xpath; - -XPathRuleElement::XPathRuleElement(const std::string &ruleName, size_t ruleIndex) : XPathElement(ruleName) { - _ruleIndex = ruleIndex; -} - -std::vector XPathRuleElement::evaluate(ParseTree *t) { - // return all children of t that match nodeName - std::vector nodes; - for (auto *c : t->children) { - if (antlrcpp::is(c)) { - ParserRuleContext *ctx = dynamic_cast(c); - if ((ctx->getRuleIndex() == _ruleIndex && !_invert) || (ctx->getRuleIndex() != _ruleIndex && _invert)) { - nodes.push_back(ctx); - } - } - } - return nodes; -} diff --git a/src/include/tree/xpath/XPathRuleElement.h b/src/include/tree/xpath/XPathRuleElement.h deleted file mode 100755 index b57276f0..00000000 --- a/src/include/tree/xpath/XPathRuleElement.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "XPathElement.h" - -namespace antlr4 { -namespace tree { -namespace xpath { - - class ANTLR4CPP_PUBLIC XPathRuleElement : public XPathElement { - public: - XPathRuleElement(const std::string &ruleName, size_t ruleIndex); - - virtual std::vector evaluate(ParseTree *t) override; - - protected: - size_t _ruleIndex = 0; - }; - -} // namespace xpath -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/xpath/XPathTokenAnywhereElement.cpp b/src/include/tree/xpath/XPathTokenAnywhereElement.cpp deleted file mode 100755 index c557c9d6..00000000 --- a/src/include/tree/xpath/XPathTokenAnywhereElement.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/ParseTree.h" -#include "tree/Trees.h" - -#include "XPathTokenAnywhereElement.h" - -using namespace antlr4::tree; -using namespace antlr4::tree::xpath; - -XPathTokenAnywhereElement::XPathTokenAnywhereElement(const std::string &tokenName, int tokenType) : XPathElement(tokenName) { - this->tokenType = tokenType; -} - -std::vector XPathTokenAnywhereElement::evaluate(ParseTree *t) { - return Trees::findAllTokenNodes(t, tokenType); -} diff --git a/src/include/tree/xpath/XPathTokenAnywhereElement.h b/src/include/tree/xpath/XPathTokenAnywhereElement.h deleted file mode 100755 index 2045d91b..00000000 --- a/src/include/tree/xpath/XPathTokenAnywhereElement.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "XPathElement.h" - -namespace antlr4 { -namespace tree { -namespace xpath { - - class ANTLR4CPP_PUBLIC XPathTokenAnywhereElement : public XPathElement { - protected: - int tokenType = 0; - public: - XPathTokenAnywhereElement(const std::string &tokenName, int tokenType); - - virtual std::vector evaluate(ParseTree *t) override; - }; - -} // namespace xpath -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/xpath/XPathTokenElement.cpp b/src/include/tree/xpath/XPathTokenElement.cpp deleted file mode 100755 index d52fc26a..00000000 --- a/src/include/tree/xpath/XPathTokenElement.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "tree/ParseTree.h" -#include "tree/Trees.h" -#include "support/CPPUtils.h" -#include "Token.h" - -#include "XPathTokenElement.h" - -using namespace antlr4; -using namespace antlr4::tree; -using namespace antlr4::tree::xpath; - -XPathTokenElement::XPathTokenElement(const std::string &tokenName, size_t tokenType) : XPathElement(tokenName) { - _tokenType = tokenType; -} - -std::vector XPathTokenElement::evaluate(ParseTree *t) { - // return all children of t that match nodeName - std::vector nodes; - for (auto *c : t->children) { - if (antlrcpp::is(c)) { - TerminalNode *tnode = dynamic_cast(c); - if ((tnode->getSymbol()->getType() == _tokenType && !_invert) || (tnode->getSymbol()->getType() != _tokenType && _invert)) { - nodes.push_back(tnode); - } - } - } - return nodes; -} diff --git a/src/include/tree/xpath/XPathTokenElement.h b/src/include/tree/xpath/XPathTokenElement.h deleted file mode 100755 index 7221530c..00000000 --- a/src/include/tree/xpath/XPathTokenElement.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "XPathElement.h" - -namespace antlr4 { -namespace tree { -namespace xpath { - - class ANTLR4CPP_PUBLIC XPathTokenElement : public XPathElement { - public: - XPathTokenElement(const std::string &tokenName, size_t tokenType); - - virtual std::vector evaluate(ParseTree *t) override; - - protected: - size_t _tokenType = 0; - }; - -} // namespace xpath -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/xpath/XPathWildcardAnywhereElement.cpp b/src/include/tree/xpath/XPathWildcardAnywhereElement.cpp deleted file mode 100755 index 4ff424f0..00000000 --- a/src/include/tree/xpath/XPathWildcardAnywhereElement.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "XPath.h" -#include "tree/ParseTree.h" -#include "tree/Trees.h" - -#include "XPathWildcardAnywhereElement.h" - -using namespace antlr4::tree; -using namespace antlr4::tree::xpath; - -XPathWildcardAnywhereElement::XPathWildcardAnywhereElement() : XPathElement(XPath::WILDCARD) { -} - -std::vector XPathWildcardAnywhereElement::evaluate(ParseTree *t) { - if (_invert) { - return {}; // !* is weird but valid (empty) - } - return Trees::getDescendants(t); -} diff --git a/src/include/tree/xpath/XPathWildcardAnywhereElement.h b/src/include/tree/xpath/XPathWildcardAnywhereElement.h deleted file mode 100755 index dc5d1e5a..00000000 --- a/src/include/tree/xpath/XPathWildcardAnywhereElement.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "XPathElement.h" - -namespace antlr4 { -namespace tree { -namespace xpath { - - class ANTLR4CPP_PUBLIC XPathWildcardAnywhereElement : public XPathElement { - public: - XPathWildcardAnywhereElement(); - - virtual std::vector evaluate(ParseTree *t) override; - }; - -} // namespace xpath -} // namespace tree -} // namespace antlr4 diff --git a/src/include/tree/xpath/XPathWildcardElement.cpp b/src/include/tree/xpath/XPathWildcardElement.cpp deleted file mode 100755 index aabda5a9..00000000 --- a/src/include/tree/xpath/XPathWildcardElement.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#include "XPath.h" -#include "tree/ParseTree.h" -#include "tree/Trees.h" - -#include "XPathWildcardElement.h" - -using namespace antlr4::tree; -using namespace antlr4::tree::xpath; - -XPathWildcardElement::XPathWildcardElement() : XPathElement(XPath::WILDCARD) { -} - -std::vector XPathWildcardElement::evaluate(ParseTree *t) { - if (_invert) { - return {}; // !* is weird but valid (empty) - } - - return t->children; -} diff --git a/src/include/tree/xpath/XPathWildcardElement.h b/src/include/tree/xpath/XPathWildcardElement.h deleted file mode 100755 index accb461d..00000000 --- a/src/include/tree/xpath/XPathWildcardElement.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. - * Use of this file is governed by the BSD 3-clause license that - * can be found in the LICENSE.txt file in the project root. - */ - -#pragma once - -#include "XPathElement.h" - -namespace antlr4 { -namespace tree { -namespace xpath { - - class ANTLR4CPP_PUBLIC XPathWildcardElement : public XPathElement { - public: - XPathWildcardElement(); - - virtual std::vector evaluate(ParseTree *t) override; - }; - -} // namespace xpath -} // namespace tree -} // namespace antlr4