diff options
Diffstat (limited to 'lib/antlr/src/TokenStreamHiddenTokenFilter.cpp')
-rw-r--r-- | lib/antlr/src/TokenStreamHiddenTokenFilter.cpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/lib/antlr/src/TokenStreamHiddenTokenFilter.cpp b/lib/antlr/src/TokenStreamHiddenTokenFilter.cpp new file mode 100644 index 00000000..431df0c3 --- /dev/null +++ b/lib/antlr/src/TokenStreamHiddenTokenFilter.cpp @@ -0,0 +1,156 @@ +/* ANTLR Translator Generator + * Project led by Terence Parr at http://www.jGuru.com + * Software rights: http://www.antlr.org/license.html + * + * $Id$ + */ +#include "antlr/TokenStreamHiddenTokenFilter.hpp" +#include "antlr/CommonHiddenStreamToken.hpp" + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +namespace antlr { +#endif + +/**This object filters a token stream coming from a lexer + * or another TokenStream so that only certain token channels + * get transmitted to the parser. + * + * Any of the channels can be filtered off as "hidden" channels whose + * tokens can be accessed from the parser. + */ + +TokenStreamHiddenTokenFilter::TokenStreamHiddenTokenFilter(TokenStream& input) +: TokenStreamBasicFilter(input) +{ +} + +void TokenStreamHiddenTokenFilter::consume() +{ + nextMonitoredToken = input->nextToken(); +} + +void TokenStreamHiddenTokenFilter::consumeFirst() +{ + consume(); + + // Handle situation where hidden or discarded tokens + // appear first in input stream + RefToken p; + // while hidden or discarded scarf tokens + while ( hideMask.member(LA(1)->getType()) || discardMask.member(LA(1)->getType()) ) { + if ( hideMask.member(LA(1)->getType()) ) { + if ( !p ) { + p = LA(1); + } + else { + static_cast<CommonHiddenStreamToken*>(p.get())->setHiddenAfter(LA(1)); + static_cast<CommonHiddenStreamToken*>(LA(1).get())->setHiddenBefore(p); // double-link + p = LA(1); + } + lastHiddenToken = p; + if (!firstHidden) + firstHidden = p; // record hidden token if first + } + consume(); + } +} + +BitSet TokenStreamHiddenTokenFilter::getDiscardMask() const +{ + return discardMask; +} + +/** Return a ptr to the hidden token appearing immediately after + * token t in the input stream. + */ +RefToken TokenStreamHiddenTokenFilter::getHiddenAfter(RefToken t) +{ + return static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenAfter(); +} + +/** Return a ptr to the hidden token appearing immediately before + * token t in the input stream. + */ +RefToken TokenStreamHiddenTokenFilter::getHiddenBefore(RefToken t) +{ + return static_cast<CommonHiddenStreamToken*>(t.get())->getHiddenBefore(); +} + +BitSet TokenStreamHiddenTokenFilter::getHideMask() const +{ + return hideMask; +} + +/** Return the first hidden token if one appears + * before any monitored token. + */ +RefToken TokenStreamHiddenTokenFilter::getInitialHiddenToken() +{ + return firstHidden; +} + +void TokenStreamHiddenTokenFilter::hide(int m) +{ + hideMask.add(m); +} + +void TokenStreamHiddenTokenFilter::hide(const BitSet& mask) +{ + hideMask = mask; +} + +RefToken TokenStreamHiddenTokenFilter::LA(int) +{ + return nextMonitoredToken; +} + +/** Return the next monitored token. +* Test the token following the monitored token. +* If following is another monitored token, save it +* for the next invocation of nextToken (like a single +* lookahead token) and return it then. +* If following is unmonitored, nondiscarded (hidden) +* channel token, add it to the monitored token. +* +* Note: EOF must be a monitored Token. +*/ +RefToken TokenStreamHiddenTokenFilter::nextToken() +{ + // handle an initial condition; don't want to get lookahead + // token of this splitter until first call to nextToken + if ( !LA(1) ) { + consumeFirst(); + } + + // we always consume hidden tokens after monitored, thus, + // upon entry LA(1) is a monitored token. + RefToken monitored = LA(1); + // point to hidden tokens found during last invocation + static_cast<CommonHiddenStreamToken*>(monitored.get())->setHiddenBefore(lastHiddenToken); + lastHiddenToken = nullToken; + + // Look for hidden tokens, hook them into list emanating + // from the monitored tokens. + consume(); + RefToken p = monitored; + // while hidden or discarded scarf tokens + while ( hideMask.member(LA(1)->getType()) || discardMask.member(LA(1)->getType()) ) { + if ( hideMask.member(LA(1)->getType()) ) { + // attach the hidden token to the monitored in a chain + // link forwards + static_cast<CommonHiddenStreamToken*>(p.get())->setHiddenAfter(LA(1)); + // link backwards + if (p != monitored) { //hidden cannot point to monitored tokens + static_cast<CommonHiddenStreamToken*>(LA(1).get())->setHiddenBefore(p); + } + p = lastHiddenToken = LA(1); + } + consume(); + } + return monitored; +} + +#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE +} +#endif + |